(`!s. polyhedron s /\ conic s /\ ~(interior s = {}) /\ ~(s = (:real^N))
       ==> sum (0..dimindex(:N))
               (\d. (-- &1) pow d *
                    &(
  REPEAT STRIP_TAC THEN
  SUBGOAL_THEN `affine hull s = (:real^N)` ASSUME_TAC THENL
   [MATCH_MP_TAC(SET_RULE `!s. s = 
UNIV /\ s 
SUBSET t ==> t = 
UNIV`) THEN
    EXISTS_TAC `affine hull (interior s:real^N->bool)` THEN
    SIMP_TAC[
INTERIOR_SUBSET; 
HULL_MONO] THEN
    MATCH_MP_TAC 
AFFINE_HULL_OPEN THEN ASM_REWRITE_TAC[
OPEN_INTERIOR];
    ALL_TAC] THEN
  FIRST_ASSUM
   (MP_TAC o GEN_REWRITE_RULE I [
POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
  ASM_REWRITE_TAC[
INTER_UNIV; 
LEFT_IMP_EXISTS_THM] THEN
  X_GEN_TAC `H:(real^N->bool)->bool` THEN
  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
  DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) STRIP_ASSUME_TAC) THEN
  SUBGOAL_THEN `(vec 0:real^N) 
IN s` ASSUME_TAC THENL
   [ASM_SIMP_TAC[
CONIC_CONTAINS_0] THEN
    ASM_MESON_TAC[
SUBSET_EMPTY; 
INTERIOR_SUBSET];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `!h:real^N->bool. h 
IN H ==> ?a. ~(a = vec 0) /\ h = {x | a dot x <= &0}`
  MP_TAC THENL
   [GEN_TAC THEN DISCH_TAC THEN
    FIRST_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
    ANTS_TAC THENL [ASM_REWRITE_TAC[]; MATCH_MP_TAC 
MONO_EXISTS]  THEN
    X_GEN_TAC `a:real^N` THEN
    DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THEN
    SUBGOAL_THEN `b = &0` SUBST_ALL_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[]] THEN
    MATCH_MP_TAC(REAL_ARITH `&0 <= b /\ ~(&0 < b) ==> b = &0`) THEN
    CONJ_TAC THENL
     [SUBGOAL_THEN `(vec 0:real^N) 
IN INTERS H` MP_TAC THENL
       [ASM SET_TAC[]; REWRITE_TAC[
IN_INTERS]] THEN
      DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
      REWRITE_TAC[
IN_ELIM_THM; 
DOT_RZERO];
      DISCH_TAC THEN
      FIRST_X_ASSUM(MP_TAC o SPEC `H 
DELETE (h:real^N->bool)`) THEN
      ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[
PSUBSET_ALT]] THEN
      DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC o CONJUNCT2) THEN
      SUBGOAL_THEN `?e. &0 < e /\ e < &1 /\
                        (e % x:real^N) 
IN h` STRIP_ASSUME_TAC THENL
       [EXISTS_TAC `min (&1 / &2) (b / ((a:real^N) dot x))` THEN
        ASM_REWRITE_TAC[
IN_ELIM_THM; 
DOT_RMUL] THEN
        SUBGOAL_THEN `&0 < (a:real^N) dot x` ASSUME_TAC THENL
         [MATCH_MP_TAC 
REAL_LT_TRANS THEN EXISTS_TAC `b:real` THEN
          ASM_REWRITE_TAC[] THEN
          UNDISCH_TAC `~((x:real^N) 
IN s)` THEN EXPAND_TAC "s" THEN
          ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
          REWRITE_TAC[
REAL_NOT_LT] THEN DISCH_TAC THEN
          SUBGOAL_THEN `H:(real^N->bool)->bool = h 
INSERT (H 
DELETE h)`
          SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
          REWRITE_TAC[
INTERS_INSERT; 
IN_INTER] THEN
          ASM_REWRITE_TAC[
IN_ELIM_THM];
          ASM_SIMP_TAC[
REAL_LT_MIN; 
REAL_LT_DIV; 
REAL_MIN_LT] THEN
          CONV_TAC REAL_RAT_REDUCE_CONV THEN
          ASM_SIMP_TAC[GSYM 
REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC];
        UNDISCH_TAC `~((x:real^N) 
IN s)` THEN REWRITE_TAC[] THEN
        SUBGOAL_THEN `x:real^N = inv e % e % x` SUBST1_TAC THENL
         [ASM_SIMP_TAC[
VECTOR_MUL_ASSOC; REAL_MUL_LINV; 
REAL_LT_IMP_NZ;
                       
VECTOR_MUL_LID];
          ALL_TAC] THEN
        RULE_ASSUM_TAC(REWRITE_RULE[conic]) THEN
        FIRST_ASSUM MATCH_MP_TAC THEN
        ASM_SIMP_TAC[
REAL_LT_IMP_LE; 
REAL_LE_INV_EQ] THEN
        EXPAND_TAC "s" THEN
        SUBGOAL_THEN `H:(real^N->bool)->bool = h 
INSERT (H 
DELETE h)`
        SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
        REWRITE_TAC[
INTERS_INSERT; 
IN_INTER] THEN
        CONJ_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN
        UNDISCH_TAC `(x:real^N) 
IN INTERS (H 
DELETE h)` THEN
        REWRITE_TAC[
IN_INTERS] THEN MATCH_MP_TAC 
MONO_FORALL THEN
        X_GEN_TAC `k:real^N->bool` THEN REWRITE_TAC[
IN_DELETE] THEN
        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
        ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN
        FIRST_X_ASSUM(MP_TAC o SPEC `k:real^N->bool`) THEN
        ASM_REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
        MAP_EVERY X_GEN_TAC [`a':real^N`; `b':real`] THEN
        STRIP_TAC THEN ASM_REWRITE_TAC[
IN_ELIM_THM] THEN
        MATCH_MP_TAC(REAL_ARITH
         `(&0 <= x ==> y <= x) /\ (&0 <= --x ==> &0 <= --y) /\ &0 <= b
          ==> x <= b ==> y <= b`) THEN
        REWRITE_TAC[
DOT_RMUL; GSYM 
REAL_MUL_RNEG] THEN
        REWRITE_TAC[REAL_ARITH `e * x <= x <=> &0 <= x * (&1 - e)`] THEN
        ASM_SIMP_TAC[
REAL_LE_MUL; 
REAL_LT_IMP_LE; 
REAL_SUB_LE] THEN
        SUBGOAL_THEN `(vec 0:real^N) 
IN INTERS H` MP_TAC THENL
         [ASM SET_TAC[]; REWRITE_TAC[
IN_INTERS]] THEN
        DISCH_THEN(MP_TAC o SPEC `k:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
        REWRITE_TAC[
IN_ELIM_THM; 
DOT_RZERO]]];
    FIRST_X_ASSUM(K ALL_TAC o SPEC `h:real^N->bool`)] 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 `fa:(real^N->bool)->real^N` THEN
  GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o funpow 2 RAND_CONV)
   [
EQ_SYM_EQ] THEN
  DISCH_TAC THEN ABBREV_TAC
   `A = 
IMAGE (\h. (fa:(real^N->bool)->real^N) h,&0) H` THEN
  SUBGOAL_THEN `
FINITE(A:real^N#real->bool)` ASSUME_TAC THENL
   [EXPAND_TAC "A" THEN MATCH_MP_TAC 
FINITE_IMAGE THEN ASM_SIMP_TAC[];
    ALL_TAC] THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `
euler_characteristic A (s:real^N->bool)` THEN CONJ_TAC THENL
   [ASM_SIMP_TAC[
EULER_CHARACTERISTIC] THEN MATCH_MP_TAC 
SUM_EQ_NUMSEG THEN
    X_GEN_TAC `d:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
    AP_TERM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC 
BIJECTIONS_CARD_EQ THEN
    ASM_SIMP_TAC[
FINITE_RESTRICT_HYPERPLANE_CELLS] THEN
    EXISTS_TAC `relative_interior:(real^N->bool)->(real^N->bool)` THEN
    EXISTS_TAC `closure:(real^N->bool)->(real^N->bool)` THEN
    REWRITE_TAC[
IN_ELIM_THM] THEN CONJ_TAC THENL
     [X_GEN_TAC `f:real^N->bool` THEN STRIP_TAC THEN
      SUBGOAL_THEN `closure(
relative_interior f):real^N->bool = f`
      ASSUME_TAC THENL
       [MATCH_MP_TAC 
EQ_TRANS THEN EXISTS_TAC `closure f:real^N->bool` THEN
        CONJ_TAC THENL
         [MATCH_MP_TAC 
CONVEX_CLOSURE_RELATIVE_INTERIOR THEN
          ASM_MESON_TAC[
FACE_OF_IMP_CONVEX];
          REWRITE_TAC[
CLOSURE_EQ] THEN MATCH_MP_TAC 
FACE_OF_IMP_CLOSED THEN
          ASM_MESON_TAC[
POLYHEDRON_IMP_CLOSED; 
POLYHEDRON_IMP_CONVEX]];
        ALL_TAC] THEN
      ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
       [ALL_TAC;
        ONCE_REWRITE_TAC[GSYM 
AFF_DIM_AFFINE_HULL] THEN
        ONCE_REWRITE_TAC[GSYM 
AFFINE_HULL_CLOSURE] THEN
        ASM_REWRITE_TAC[
AFF_DIM_AFFINE_HULL] THEN
        ASM_MESON_TAC[
RELATIVE_INTERIOR_SUBSET; 
SUBSET_TRANS;
                      
FACE_OF_IMP_SUBSET]] THEN
      SUBGOAL_THEN `~(f:real^N->bool = {})` ASSUME_TAC THENL
       [ASM_REWRITE_TAC[GSYM 
AFF_DIM_POS_LE; 
INT_POS]; ALL_TAC] THEN
      SUBGOAL_THEN
       `?J. J 
SUBSET H /\
            f = 
INTERS {{x:real^N | fa h dot x <= &0} | h 
IN H} 
INTER
                INTERS {{x | fa(h:real^N->bool) dot x = &0} | h 
IN J}`
      ASSUME_TAC THENL
       [ASM_CASES_TAC `f:real^N->bool = s` THENL
         [EXISTS_TAC `{}:(real^N->bool)->bool` THEN
          REWRITE_TAC[
EMPTY_SUBSET; 
NOT_IN_EMPTY; 
INTERS_0; 
INTER_UNIV;
                      SET_RULE `{f x | x | F} = {}`] THEN
          ASM_REWRITE_TAC[] THEN
          REWRITE_TAC[SYM(ASSUME `
INTERS H = (s:real^N->bool)`)] THEN
          AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
           `(!x. x 
IN s ==> f x = x) ==> s = {f x | x 
IN s}`) THEN
          ASM_SIMP_TAC[];
          ALL_TAC] THEN
        EXISTS_TAC
        `{h:real^N->bool | h 
IN H /\
                     f 
SUBSET s 
INTER {x:real^N | fa h dot x = &0}}` THEN
        CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
        MP_TAC(ISPECL [`s:real^N->bool`; `H:(real^N->bool)->bool`;
                       `fa:(real^N->bool)->real^N`;
                       `\h:real^N->bool. &0`]
          
FACE_OF_POLYHEDRON_EXPLICIT) THEN
        ASM_SIMP_TAC[
INTER_UNIV] THEN
        DISCH_THEN(MP_TAC o SPEC `f:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
        SUBGOAL_THEN
         `
INTERS {{x:real^N | fa(h:real^N->bool) dot x <= &0} | h 
IN H} = s`
        ASSUME_TAC THENL
         [EXPAND_TAC "s" THEN AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
           `(!x. x 
IN s ==> f x = x) ==> {f x | x 
IN s} = s`) THEN
          ASM_SIMP_TAC[];
         ALL_TAC] THEN
        ASM_CASES_TAC `{h:real^N->bool | h 
IN H /\
                           f 
SUBSET s 
INTER {x:real^N | fa h dot x = &0}} =
                       {}`
        THENL
         [ONCE_REWRITE_TAC[
SIMPLE_IMAGE_GEN] THEN
          ASM_REWRITE_TAC[
IMAGE_CLAUSES; 
INTERS_0] THEN
          FIRST_ASSUM(MP_TAC o MATCH_MP 
FACE_OF_IMP_SUBSET) THEN
          ASM SET_TAC[];
          ALL_TAC] THEN
        DISCH_THEN(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
        ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC I [
EXTENSION] THEN
        X_GEN_TAC `y:real^N` THEN REWRITE_TAC[
IN_INTER; 
IN_INTERS] THEN
        REWRITE_TAC[
FORALL_IN_GSPEC; 
IN_INTER] THEN
        ASM_CASES_TAC `(y:real^N) 
IN s` THEN ASM_REWRITE_TAC[] THEN
        ASM SET_TAC[];
        ALL_TAC] THEN
      ABBREV_TAC
       `H' = 
IMAGE (\h:real^N->bool. {x:real^N | --(fa h) dot x <= &0}) H` THEN
      SUBGOAL_THEN
       `?J. 
FINITE J /\
            J 
SUBSET (H 
UNION H') /\
            f:real^N->bool = affine hull f 
INTER INTERS J`
      MP_TAC THENL
       [FIRST_X_ASSUM(X_CHOOSE_THEN `J:(real^N->bool)->bool`
          STRIP_ASSUME_TAC) THEN
        EXISTS_TAC
         `H 
UNION IMAGE (\h:real^N->bool.
             {x:real^N | --(fa h) dot x <= &0}) J` THEN
        REPEAT CONJ_TAC THENL
         [ASM_REWRITE_TAC[
FINITE_UNION] THEN MATCH_MP_TAC 
FINITE_IMAGE THEN
          ASM_MESON_TAC[
FINITE_SUBSET];
          EXPAND_TAC "H'" THEN ASM SET_TAC[];
          MATCH_MP_TAC(SET_RULE `s 
SUBSET f /\ s = t ==> s = f 
INTER t`) THEN
          REWRITE_TAC[
HULL_SUBSET] THEN
          FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
          REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
          REWRITE_TAC[
INTERS_UNION] THEN MATCH_MP_TAC(SET_RULE
           `s = s' /\ (!x. x 
IN s ==> (x 
IN t <=> x 
IN t'))
            ==> s 
INTER t = s' 
INTER t'`) THEN
          CONJ_TAC THENL
           [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
             `(!x. x 
IN s ==> f x = x) ==> {f x | x 
IN s} = s`) THEN
            ASM_SIMP_TAC[];
            ALL_TAC] THEN
          X_GEN_TAC `y:real^N` THEN REWRITE_TAC[
IN_INTERS] THEN
          REWRITE_TAC[
FORALL_IN_IMAGE; 
FORALL_IN_GSPEC] THEN
          REWRITE_TAC[
IN_ELIM_THM; 
DOT_LNEG] THEN
          REWRITE_TAC[REAL_ARITH `--x <= &0 <=> &0 <= x`] THEN
          ASM SET_TAC[]];
        ALL_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 `nn:num`
        (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
      DISCH_THEN(X_CHOOSE_THEN `J:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
      SUBGOAL_THEN
       `!J'. J' 
PSUBSET J
             ==> (f:real^N->bool) 
PSUBSET (affine hull f 
INTER INTERS J')`
      ASSUME_TAC THENL
       [REPEAT STRIP_TAC THEN
        FIRST_X_ASSUM(MP_TAC o SPEC `
CARD(J':(real^N->bool)->bool)`) THEN
        ANTS_TAC THENL [ASM_MESON_TAC[
CARD_PSUBSET; 
HAS_SIZE]; ALL_TAC] THEN
        REWRITE_TAC[
NOT_EXISTS_THM; 
HAS_SIZE] THEN
        DISCH_THEN(MP_TAC o SPEC `J':(real^N->bool)->bool`) THEN
        MATCH_MP_TAC(TAUT `a /\ b /\ (~c ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN
        CONJ_TAC THENL
         [ASM_MESON_TAC[
PSUBSET; 
FINITE_SUBSET; 
HAS_SIZE]; ALL_TAC] THEN
        CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
        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[];
        ALL_TAC] THEN
      SUBGOAL_THEN
       `!h:real^N->bool. h 
IN J
          ==> ?a. {x | a dot x <= &0} = h /\
                  (h 
IN H /\ a = fa h \/ ?h'. h' 
IN H /\ a = --(fa h'))`
      MP_TAC THENL
       [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
        SUBGOAL_THEN `(h:real^N->bool) 
IN (H 
UNION H')` MP_TAC THENL
         [ASM SET_TAC[]; EXPAND_TAC "H'"] THEN
        UNDISCH_THEN `(h:real^N->bool) 
IN J` (K ALL_TAC) THEN
        SPEC_TAC(`h:real^N->bool`,`h:real^N->bool`) THEN
        REWRITE_TAC[
IN_UNION; TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`;
                    
FORALL_AND_THM; 
FORALL_IN_IMAGE] THEN
        CONJ_TAC THEN X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THENL
         [EXISTS_TAC `(fa:(real^N->bool)->real^N) h` THEN
          ASM_SIMP_TAC[];
          EXISTS_TAC `--((fa:(real^N->bool)->real^N) h)` THEN
          REWRITE_TAC[] THEN DISJ2_TAC THEN ASM_MESON_TAC[]];
        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 `ga:(real^N->bool)->real^N` THEN DISCH_TAC THEN
      MP_TAC(ISPECL
       [`f:real^N->bool`; `J:(real^N->bool)->bool`;
        `ga:(real^N->bool)->real^N`; `\h:real^N->bool. &0`]
       
RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
      ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
       [REPEAT CONJ_TAC THENL
         [ASM_MESON_TAC[
HAS_SIZE];
          ASM_MESON_TAC[];
          ASM_SIMP_TAC[] THEN ASM_MESON_TAC[
VECTOR_NEG_EQ_0; 
SUBSET]];
        DISCH_TAC THEN ASM_REWRITE_TAC[]] THEN
      SUBGOAL_THEN
       `!h:real^N->bool. h 
IN J ==> h 
IN H /\ ga h:real^N = fa h`
      ASSUME_TAC THENL
       [SUBGOAL_THEN `~(
relative_interior f:real^N->bool = {})` MP_TAC THENL
         [ASM_MESON_TAC[
RELATIVE_INTERIOR_EQ_EMPTY; 
FACE_OF_IMP_CONVEX];
          REWRITE_TAC[GSYM 
MEMBER_NOT_EMPTY]] THEN
        DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN
        SUBGOAL_THEN `(z:real^N) 
IN f /\ z 
IN s` STRIP_ASSUME_TAC THENL
         [ASM_MESON_TAC[
SUBSET; 
FACE_OF_IMP_SUBSET; 
RELATIVE_INTERIOR_SUBSET];
          ALL_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(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
        DISCH_THEN(DISJ_CASES_THEN MP_TAC) THEN REWRITE_TAC[] THEN
        DISCH_THEN(X_CHOOSE_THEN `h':real^N->bool` STRIP_ASSUME_TAC) THEN
        UNDISCH_TAC `(z:real^N) 
IN relative_interior f` THEN
        ASM_REWRITE_TAC[
IN_ELIM_THM] THEN
        DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN
        ASM_REWRITE_TAC[
DOT_LNEG] THEN
        UNDISCH_TAC `(z:real^N) 
IN s` THEN EXPAND_TAC "s" THEN
        REWRITE_TAC[
IN_INTERS] THEN
        DISCH_THEN(MP_TAC o SPEC `h':real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
        FIRST_X_ASSUM(MP_TAC o SPEC `h':real^N->bool`) THEN
        ASM_REWRITE_TAC[] THEN DISCH_THEN(fun th ->
          GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SYM(CONJUNCT2 th)]) THEN
        REWRITE_TAC[
IN_ELIM_THM] THEN REAL_ARITH_TAC;
        ALL_TAC] THEN
      FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th] THEN
        MP_TAC(SYM th)) THEN
      FIRST_X_ASSUM(X_CHOOSE_THEN `K:(real^N->bool)->bool` MP_TAC) THEN
      DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
      DISCH_THEN(fun th -> ASSUME_TAC(SYM th) THEN
        GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [th]) THEN
      REWRITE_TAC[
IN_INTER; 
IN_INTERS; 
FORALL_IN_GSPEC; GSYM 
CONJ_ASSOC] THEN
      REWRITE_TAC[
IN_ELIM_THM] THEN DISCH_TAC THEN
      SUBGOAL_THEN `~(
relative_interior f:real^N->bool = {})` ASSUME_TAC THENL
       [ASM_MESON_TAC[
RELATIVE_INTERIOR_EQ_EMPTY; 
FACE_OF_IMP_CONVEX];
        ALL_TAC] THEN
      SUBGOAL_THEN `
DISJOINT (J:(real^N->bool)->bool) K` ASSUME_TAC THENL
       [UNDISCH_TAC `~(
relative_interior f:real^N->bool = {})` THEN
        FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC
         (LAND_CONV o RAND_CONV o LAND_CONV) [SYM th]) THEN
        REWRITE_TAC[
IN_DISJOINT; GSYM 
MEMBER_NOT_EMPTY; 
IN_ELIM_THM] THEN
        ASM_MESON_TAC[
REAL_LT_REFL];
        ALL_TAC] THEN
      SUBGOAL_THEN
       `
relative_interior f =
          
INTERS {(if (h:real^N->bool) 
IN J then {x | fa h dot x < &0}
                   else if h 
IN K then {x:real^N | fa h dot x = &0}
                   else if 
relative_interior f 
SUBSET {x | fa h dot x = &0}
                   then {x | fa h dot x = &0}
                   else {x | fa h dot x < &0}) | h 
IN H}`
      ASSUME_TAC THENL
       [MATCH_MP_TAC 
SUBSET_ANTISYM THEN CONJ_TAC THENL
         [ALL_TAC;
          FIRST_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN
          GEN_REWRITE_TAC I [
SUBSET] THEN
          REWRITE_TAC[
IN_INTERS; 
FORALL_IN_GSPEC; 
AND_FORALL_THM] THEN
          X_GEN_TAC `x:real^N` THEN REWRITE_TAC[
IN_ELIM_THM] THEN
          MATCH_MP_TAC 
MONO_FORALL THEN X_GEN_TAC `h:real^N->bool` THEN
          ASM_CASES_TAC `(h:real^N->bool) 
IN H` THENL
           [ALL_TAC; DISCH_THEN(K ALL_TAC) THEN ASM SET_TAC[]] THEN
          ASM_REWRITE_TAC[] THEN
          ASM_CASES_TAC `(h:real^N->bool) 
IN J` THEN
          ASM_SIMP_TAC[
IN_ELIM_THM; 
REAL_LT_IMP_LE] THENL
           [ASM SET_TAC[]; ALL_TAC] THEN
          ASM_CASES_TAC `(h:real^N->bool) 
IN K` THEN
          ASM_SIMP_TAC[
IN_ELIM_THM; 
REAL_LE_REFL] THEN
          COND_CASES_TAC THEN REWRITE_TAC[
IN_ELIM_THM] THEN
          REAL_ARITH_TAC] THEN
        GEN_REWRITE_TAC I [
SUBSET] THEN X_GEN_TAC `x:real^N` THEN
        DISCH_TAC THEN REWRITE_TAC[
IN_INTERS; 
FORALL_IN_GSPEC] THEN
        X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
        REPEAT(COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
        REWRITE_TAC[
IN_ELIM_THM; 
REAL_LT_LE] THEN
        CONJ_TAC THENL [ASM SET_TAC[]; DISCH_TAC] THEN
        FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
         [SET_RULE `~(s 
SUBSET t) <=> ?y. y 
IN s /\ ~(y 
IN t)`]) THEN
        REWRITE_TAC[
IN_ELIM_THM; 
NOT_EXISTS_THM] THEN
        X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
        FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
         `~(x:real = &0) ==> ~(x <= &0) \/ x < &0`))
        THENL [ASM SET_TAC[]; ALL_TAC] THEN
        MP_TAC(ASSUME `(x:real^N) 
IN relative_interior f`) THEN
        REWRITE_TAC[
IN_RELATIVE_INTERIOR_CBALL] THEN
        DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
        REWRITE_TAC[
NOT_EXISTS_THM] THEN X_GEN_TAC `e:real` THEN
        DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
        REWRITE_TAC[
SUBSET; 
IN_INTER; 
IN_CBALL] THEN
        SUBGOAL_THEN `~(y:real^N = x)` ASSUME_TAC THENL
         [ASM_MESON_TAC[
REAL_LT_REFL]; ALL_TAC] THEN
        DISCH_THEN(MP_TAC o SPEC `x + e / norm(y - x) % (x - y):real^N`) THEN
        SUBGOAL_THEN
         `(x:real^N) 
IN affine hull f /\ y 
IN affine hull f`
        STRIP_ASSUME_TAC THENL
         [ASM_MESON_TAC[
RELATIVE_INTERIOR_SUBSET; 
SUBSET; 
HULL_SUBSET];
          ASM_SIMP_TAC[
IN_AFFINE_ADD_MUL_DIFF; 
AFFINE_AFFINE_HULL]] THEN
        REWRITE_TAC[NORM_ARITH `dist(x:real^N,x + r) = norm r`] THEN
        REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL
         [ASM_SIMP_TAC[
NORM_MUL; 
REAL_ABS_DIV; 
REAL_ABS_NORM; 
NORM_SUB;
                       
REAL_DIV_RMUL; 
NORM_EQ_0; 
VECTOR_SUB_EQ] THEN
          ASM_REAL_ARITH_TAC;
          DISCH_TAC] THEN
        SUBGOAL_THEN `(x + e / norm(y - x) % (x - y):real^N) 
IN s` MP_TAC THENL
         [ASM_MESON_TAC[
SUBSET; 
FACE_OF_IMP_SUBSET]; ALL_TAC] THEN
        EXPAND_TAC "s" THEN REWRITE_TAC[
IN_INTERS] THEN
        DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN
        ASM_REWRITE_TAC[] THEN
        FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV)
         [SYM(CONJUNCT2(MATCH_MP th (ASSUME `(h:real^N->bool) 
IN H`)))]) THEN
        ASM_REWRITE_TAC[
IN_ELIM_THM; 
DOT_RADD; REAL_ADD_LID; 
DOT_RMUL] THEN
        ASM_REWRITE_TAC[
DOT_RSUB; 
REAL_SUB_LZERO; 
REAL_NOT_LE] THEN
        MATCH_MP_TAC 
REAL_LT_MUL THEN
        ASM_SIMP_TAC[
REAL_LT_DIV; 
NORM_POS_LT; 
VECTOR_SUB_EQ] THEN
        ASM_REAL_ARITH_TAC;
        ALL_TAC] THEN
      UNDISCH_TAC `~(
relative_interior f:real^N->bool = {})` THEN
      REWRITE_TAC[GSYM 
MEMBER_NOT_EMPTY; 
hyperplane_cell] THEN
      MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN
      GEN_REWRITE_TAC RAND_CONV [
EXTENSION] THEN
      ONCE_ASM_REWRITE_TAC[] THEN EXPAND_TAC "A" THEN
      REWRITE_TAC[
IN_INTERS; 
FORALL_IN_GSPEC] THEN
      DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN MP_TAC th) THEN
      GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [
IN] THEN
      REWRITE_TAC[
hyperplane_equiv; 
FORALL_IN_IMAGE] THEN
      MATCH_MP_TAC(MESON[]
       `(!h. P h ==> (Q h <=> R h))
        ==> (!h. P h) ==> ((!h. Q h) <=> (!h. R h))`) THEN
      X_GEN_TAC `h:real^N->bool` THEN
      ASM_CASES_TAC `(h:real^N->bool) 
IN H` THEN ASM_REWRITE_TAC[] THEN
      REWRITE_TAC[
hyperplane_side; 
REAL_SUB_RZERO] THEN
      REPEAT(COND_CASES_TAC THEN
        SIMP_TAC[
IN_ELIM_THM] THENL [MESON_TAC[
REAL_SGN_EQ]; ALL_TAC]) THEN
      MESON_TAC[
REAL_SGN_EQ];
      X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
      ONCE_REWRITE_TAC[GSYM 
AFF_DIM_AFFINE_HULL] THEN
      REWRITE_TAC[
AFFINE_HULL_CLOSURE] THEN
      ASM_REWRITE_TAC[
AFF_DIM_AFFINE_HULL] THEN CONJ_TAC THENL
       [ALL_TAC;
        MATCH_MP_TAC 
EQ_TRANS THEN
        EXISTS_TAC `
relative_interior c:real^N->bool` THEN CONJ_TAC THENL
         [MATCH_MP_TAC 
CONVEX_RELATIVE_INTERIOR_CLOSURE THEN
          ASM_MESON_TAC[
HYPERPLANE_CELL_CONVEX];
          ASM_MESON_TAC[
HYPERPLANE_CELL_RELATIVE_INTERIOR]]] THEN
      SUBGOAL_THEN
       `?J. J 
SUBSET H /\
            c = 
INTERS {{x | (fa(h:real^N->bool)) dot x < &0} | h 
IN J} 
INTER
                INTERS {{x:real^N | (fa h) dot x = &0} | h 
IN (H 
DIFF J)}`
      MP_TAC THENL
       [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
HYPERPLANE_CELL]) THEN
        EXPAND_TAC "A" THEN REWRITE_TAC[
hyperplane_equiv; 
FORALL_IN_IMAGE] THEN
        DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
        REWRITE_TAC[
hyperplane_side; 
REAL_SUB_RZERO] THEN
        GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o ONCE_DEPTH_CONV)
         [
EQ_SYM_EQ] THEN
        DISCH_THEN(ASSUME_TAC o SYM) THEN EXISTS_TAC
         `{h:real^N->bool | h 
IN H /\
                            
real_sgn(fa h dot (z:real^N)) = -- &1}` THEN
        REWRITE_TAC[SET_RULE `{x | x 
IN s /\ P x} 
SUBSET s`] THEN
        REWRITE_TAC[GSYM 
INTERS_UNION] THEN EXPAND_TAC "c" THEN
        GEN_REWRITE_TAC I [
EXTENSION] THEN X_GEN_TAC `y:real^N` THEN
        REWRITE_TAC[
IN_ELIM_THM; 
IN_INTERS] THEN REWRITE_TAC[
IN_UNION] THEN
        REWRITE_TAC[TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`;
                    
FORALL_AND_THM] THEN
        REWRITE_TAC[
FORALL_IN_GSPEC] THEN
        REWRITE_TAC[
IN_DIFF; 
IN_ELIM_THM] THEN
        REWRITE_TAC[TAUT `a /\ ~(a /\ b) <=> a /\ ~b`] THEN
        REWRITE_TAC[
AND_FORALL_THM] THEN AP_TERM_TAC THEN
        REWRITE_TAC[
FUN_EQ_THM] THEN X_GEN_TAC `h:real^N->bool` THEN
        ASM_CASES_TAC `(h:real^N->bool) 
IN H` THEN ASM_REWRITE_TAC[] THEN
        REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
         (SPEC `(fa:(real^N->bool)->real^N) h dot z` 
REAL_SGN_CASES) THEN
        ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
        REWRITE_TAC[
REAL_SGN_EQ] THEN
        SUBGOAL_THEN `?x:real^N. x 
IN c /\ x 
IN s` MP_TAC THENL
         [ASM_MESON_TAC[
MEMBER_NOT_EMPTY; 
SUBSET; 
NONEMPTY_HYPERPLANE_CELL];
          MATCH_MP_TAC(TAUT `~p ==> p ==> q`)] THEN
        MAP_EVERY EXPAND_TAC ["s";