1 (* ========================================================================= *)
2 (* Faces, extreme points, polytopes, polyhedra etc. *)
3 (* ========================================================================= *)
5 needs "Multivariate/paths.ml";;
7 (* ------------------------------------------------------------------------- *)
8 (* Faces of a (usually convex) set. *)
9 (* ------------------------------------------------------------------------- *)
11 parse_as_infix("face_of",(12,"right"));;
13 let face_of = new_definition
15 t SUBSET s /\ convex t /\
16 !a b x. a IN s /\ b IN s /\ x IN t /\ x IN segment(a,b)
17 ==> a IN t /\ b IN t`;;
19 let FACE_OF_TRANSLATION_EQ = prove
20 (`!a f s:real^N->bool.
21 (IMAGE (\x. a + x) f) face_of (IMAGE (\x. a + x) s) <=> f face_of s`,
22 REWRITE_TAC[face_of] THEN GEOM_TRANSLATE_TAC[]);;
24 add_translation_invariants [FACE_OF_TRANSLATION_EQ];;
26 let FACE_OF_LINEAR_IMAGE = prove
27 (`!f:real^M->real^N c s.
28 linear f /\ (!x y. f x = f y ==> x = y)
29 ==> ((IMAGE f c) face_of (IMAGE f s) <=> c face_of s)`,
30 REWRITE_TAC[face_of; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
31 REPEAT STRIP_TAC THEN MP_TAC(end_itlist CONJ
32 (mapfilter (ISPEC `f:real^M->real^N`) (!invariant_under_linear))) THEN
33 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[]);;
35 add_linear_invariants [FACE_OF_LINEAR_IMAGE];;
37 let FACE_OF_REFL = prove
38 (`!s. convex s ==> s face_of s`,
39 SIMP_TAC[face_of] THEN SET_TAC[]);;
41 let FACE_OF_REFL_EQ = prove
42 (`!s. s face_of s <=> convex s`,
43 SIMP_TAC[face_of] THEN SET_TAC[]);;
45 let EMPTY_FACE_OF = prove
47 REWRITE_TAC[face_of; CONVEX_EMPTY] THEN SET_TAC[]);;
49 let FACE_OF_EMPTY = prove
50 (`!s. s face_of {} <=> s = {}`,
51 REWRITE_TAC[face_of; SUBSET_EMPTY; NOT_IN_EMPTY] THEN
52 MESON_TAC[CONVEX_EMPTY]);;
54 let FACE_OF_TRANS = prove
55 (`!s t u. s face_of t /\ t face_of u
57 REWRITE_TAC[face_of] THEN SET_TAC[]);;
59 let FACE_OF_FACE = prove
62 ==> (f face_of t <=> f face_of s /\ f SUBSET t)`,
63 REWRITE_TAC[face_of] THEN SET_TAC[]);;
65 let FACE_OF_SUBSET = prove
66 (`!f s t. f face_of s /\ f SUBSET t /\ t SUBSET s ==> f face_of t`,
67 REWRITE_TAC[face_of] THEN SET_TAC[]);;
69 let FACE_OF_SLICE = prove
71 f face_of s /\ convex t
72 ==> (f INTER t) face_of (s INTER t)`,
73 REPEAT GEN_TAC THEN REWRITE_TAC[face_of; IN_INTER] THEN STRIP_TAC THEN
76 ASM_MESON_TAC[CONVEX_INTER];
79 let FACE_OF_INTER = prove
80 (`!s t1 t2. t1 face_of s /\ t2 face_of s
81 ==> (t1 INTER t2) face_of s`,
82 SIMP_TAC[face_of; CONVEX_INTER] THEN SET_TAC[]);;
84 let FACE_OF_INTERS = prove
85 (`!P s. ~(P = {}) /\ (!t. t IN P ==> t face_of s)
86 ==> (INTERS P) face_of s`,
87 REWRITE_TAC[face_of] THEN REPEAT STRIP_TAC THENL
88 [ASM SET_TAC[]; ASM_SIMP_TAC[CONVEX_INTERS]; ASM SET_TAC[]; ASM SET_TAC[]]);;
90 let FACE_OF_INTER_INTER = prove
92 f face_of t /\ f' face_of t' ==> (f INTER f') face_of (t INTER t')`,
93 REWRITE_TAC[face_of; SUBSET; IN_INTER] THEN MESON_TAC[CONVEX_INTER]);;
95 let FACE_OF_STILLCONVEX = prove
101 t = (affine hull t) INTER s)`,
102 REPEAT STRIP_TAC THEN REWRITE_TAC[face_of] THEN
103 ASM_CASES_TAC `(t:real^N->bool) SUBSET s` THEN ASM_REWRITE_TAC[] THEN
104 EQ_TAC THEN STRIP_TAC THENL
106 [REPEAT(POP_ASSUM MP_TAC) THEN
107 REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; open_segment; IN_DIFF] THEN
108 REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; SUBSET_DIFF] THEN SET_TAC[];
110 REWRITE_TAC[EXTENSION] THEN X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
111 [ASM MESON_TAC[HULL_INC; SUBSET; IN_INTER]; ALL_TAC] THEN
112 ASM_CASES_TAC `t:real^N -> bool = {}` THEN
113 ASM_REWRITE_TAC[IN_INTER; AFFINE_HULL_EMPTY; NOT_IN_EMPTY] THEN
114 MP_TAC(ISPEC `t:real^N->bool` RELATIVE_INTERIOR_EQ_EMPTY) THEN
115 ASM_REWRITE_TAC[] THEN
116 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN
117 X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_RELATIVE_INTERIOR_CBALL] THEN
118 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
119 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
120 STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THEN ASM_REWRITE_TAC[] THEN
121 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN
122 REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SEGMENT_SYM] THEN
123 ASM_SIMP_TAC[LEFT_FORALL_IMP_THM; OPEN_SEGMENT_ALT] THEN
124 ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN
125 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN ASM_SIMP_TAC[] THEN
126 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
127 REWRITE_TAC[EXISTS_IN_GSPEC] THEN
128 EXISTS_TAC `min (&1 / &2) (e / norm(x - y:real^N))` THEN
129 REWRITE_TAC[REAL_LT_MIN; REAL_MIN_LT] THEN
130 CONV_TAC REAL_RAT_REDUCE_CONV THEN
131 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN
132 FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTER; IN_CBALL; dist] THEN
134 [REWRITE_TAC[NORM_MUL; VECTOR_ARITH
135 `y - ((&1 - u) % y + u % x):real^N = u % (y - x)`] THEN
136 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
137 REWRITE_TAC[NORM_SUB] THEN
138 MATCH_MP_TAC(REAL_ARITH `&0 < e ==> abs(min (&1 / &2) e) <= e`) THEN
139 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ];
140 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
141 ASM_SIMP_TAC[HULL_INC]];
143 [ONCE_ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONVEX_INTER THEN
144 ASM_SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL];
146 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
148 `!a b x:real^N. a IN s /\ b IN s /\ x IN t /\ x IN segment(a,b) /\
149 (a IN affine hull t ==> b IN affine hull t)
150 ==> a IN t /\ b IN t`
151 (fun th -> MESON_TAC[th; SEGMENT_SYM]) THEN
152 REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN affine hull t` THEN
153 ASM_REWRITE_TAC[] THENL [ASM SET_TAC[]; STRIP_TAC] THEN
154 ASM_CASES_TAC `a:real^N = b` THENL
155 [ASM_MESON_TAC[SEGMENT_REFL; NOT_IN_EMPTY]; ALL_TAC] THEN
156 SUBGOAL_THEN `(a:real^N) IN (s DIFF t) /\ b IN (s DIFF t)`
157 STRIP_ASSUME_TAC THENL
158 [ASM_REWRITE_TAC[IN_DIFF] THEN ONCE_ASM_REWRITE_TAC[] THEN
159 ASM_REWRITE_TAC[IN_INTER] THEN
160 UNDISCH_TAC `~((a:real^N) IN affine hull t)` THEN
161 UNDISCH_TAC `(x:real^N) IN segment(a,b)` THEN
162 ASM_SIMP_TAC[OPEN_SEGMENT_ALT; CONTRAPOS_THM; IN_ELIM_THM] THEN
163 DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN
164 FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv(&1 - u)) :real^N->real^N`) THEN
165 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
166 ASM_SIMP_TAC[REAL_MUL_LINV; REAL_ARITH `x < &1 ==> ~(&1 - x = &0)`] THEN
167 REWRITE_TAC[VECTOR_ARITH
168 `x:real^N = &1 % a + u % b <=> a = x + --u % b`] THEN
169 DISCH_THEN SUBST1_TAC THEN DISCH_TAC THEN
170 MATCH_MP_TAC(REWRITE_RULE[affine] AFFINE_AFFINE_HULL) THEN
171 ASM_SIMP_TAC[HULL_INC] THEN
172 UNDISCH_TAC `u < &1` THEN CONV_TAC REAL_FIELD;
173 MP_TAC(ISPEC `s DIFF t:real^N->bool` CONVEX_CONTAINS_SEGMENT) THEN
174 ASM_REWRITE_TAC[] THEN
175 DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN
176 ASM_REWRITE_TAC[SUBSET; IN_DIFF] THEN
177 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
178 ASM_MESON_TAC[segment; IN_DIFF]]]);;
180 let FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG = prove
182 convex(s INTER {x | a dot x = b}) /\ (!x. x IN s ==> a dot x <= b)
183 ==> (s INTER {x | a dot x = b}) face_of s`,
184 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `c:real^N`; `d:real`] THEN
185 SIMP_TAC[face_of; INTER_SUBSET] THEN
186 STRIP_TAC THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
187 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
188 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
189 MATCH_MP_TAC(REAL_ARITH
190 `a <= x /\ b <= x /\ ~(a < x) /\ ~(b < x) ==> a = x /\ b = x`) THEN
191 ASM_SIMP_TAC[] THEN UNDISCH_TAC `(x:real^N) IN segment(a,b)` THEN
192 ASM_CASES_TAC `a:real^N = b` THEN
193 ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN
194 ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM] THEN
195 DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN
196 CONJ_TAC THEN DISCH_TAC THEN UNDISCH_TAC `(c:real^N) dot x = d` THEN
197 MATCH_MP_TAC(REAL_ARITH `x < a ==> x = a ==> F`) THEN
198 SUBST1_TAC(REAL_ARITH `d = (&1 - u) * d + u * d`) THEN
199 ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THENL
200 [MATCH_MP_TAC REAL_LTE_ADD2; MATCH_MP_TAC REAL_LET_ADD2] THEN
201 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LMUL_EQ; REAL_SUB_LT]);;
203 let FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG = prove
205 convex(s INTER {x | a dot x = b}) /\ (!x. x IN s ==> a dot x >= b)
206 ==> (s INTER {x | a dot x = b}) face_of s`,
207 REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN
208 MP_TAC(ISPECL [`s:real^N->bool`; `--a:real^N`; `--b:real`]
209 FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG) THEN
210 ASM_REWRITE_TAC[DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2]);;
212 let FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove
214 convex s /\ (!x. x IN s ==> a dot x <= b)
215 ==> (s INTER {x | a dot x = b}) face_of s`,
216 SIMP_TAC[FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG;
217 CONVEX_INTER; CONVEX_HYPERPLANE]);;
219 let FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove
221 convex s /\ (!x. x IN s ==> a dot x >= b)
222 ==> (s INTER {x | a dot x = b}) face_of s`,
223 SIMP_TAC[FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG;
224 CONVEX_INTER; CONVEX_HYPERPLANE]);;
226 let FACE_OF_IMP_SUBSET = prove
227 (`!s t. t face_of s ==> t SUBSET s`,
230 let FACE_OF_IMP_CONVEX = prove
231 (`!s t. t face_of s ==> convex t`,
234 let FACE_OF_IMP_CLOSED = prove
235 (`!s t. convex s /\ closed s /\ t face_of s ==> closed t`,
237 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
238 ASM_SIMP_TAC[FACE_OF_STILLCONVEX] THEN
239 STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
240 ASM_SIMP_TAC[CLOSED_AFFINE; AFFINE_AFFINE_HULL; CLOSED_INTER]);;
242 let FACE_OF_IMP_COMPACT = prove
243 (`!s t. convex s /\ compact s /\ t face_of s ==> compact t`,
244 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
245 ASM_MESON_TAC[BOUNDED_SUBSET; FACE_OF_IMP_SUBSET; FACE_OF_IMP_CLOSED]);;
247 let FACE_OF_INTER_SUBFACE = prove
248 (`!c1 c2 d1 d2:real^N->bool.
249 (c1 INTER c2) face_of c1 /\ (c1 INTER c2) face_of c2 /\
250 d1 face_of c1 /\ d2 face_of c2
251 ==> (d1 INTER d2) face_of d1 /\ (d1 INTER d2) face_of d2`,
252 REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_SUBSET THENL
253 [EXISTS_TAC `c1:real^N->bool`; EXISTS_TAC `c2:real^N->bool`] THEN
254 ASM_SIMP_TAC[FACE_OF_IMP_SUBSET; INTER_SUBSET] THEN
255 TRANS_TAC FACE_OF_TRANS `c1 INTER c2:real^N->bool` THEN
256 ASM_SIMP_TAC[FACE_OF_INTER_INTER]);;
258 let SUBSET_OF_FACE_OF = prove
259 (`!s t u:real^N->bool.
260 t face_of s /\ u SUBSET s /\
261 ~(DISJOINT t (relative_interior u))
263 REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN
264 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN
265 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
266 REWRITE_TAC[IN_INTER; LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN
267 REWRITE_TAC[IN_RELATIVE_INTERIOR_CBALL] THEN
268 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
269 DISCH_THEN(X_CHOOSE_THEN `e:real` MP_TAC) THEN
270 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
271 REWRITE_TAC[SUBSET; IN_CBALL; IN_INTER] THEN
272 ASM_CASES_TAC `c:real^N = b` THEN ASM_REWRITE_TAC[] THEN
273 ABBREV_TAC `d:real^N = b + e / norm(b - c) % (b - c)` THEN
274 DISCH_THEN(MP_TAC o SPEC `d:real^N`) THEN ANTS_TAC THENL
275 [EXPAND_TAC "d" THEN CONJ_TAC THENL
276 [REWRITE_TAC[NORM_ARITH `dist(b:real^N,b + e) = norm e`] THEN
277 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
278 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN
280 REWRITE_TAC[VECTOR_ARITH
281 `b + u % (b - c):real^N = (&1 - --u) % b + --u % c`] THEN
282 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
283 ASM_SIMP_TAC[HULL_INC]];
285 SUBGOAL_THEN `(d:real^N) IN t /\ c IN t` (fun th -> MESON_TAC[th]) THEN
286 FIRST_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [face_of]) THEN
287 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `b:real^N` THEN
288 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
289 SUBGOAL_THEN `~(b:real^N = d)` ASSUME_TAC THENL
291 REWRITE_TAC[VECTOR_ARITH `b:real^N = b + e <=> e = vec 0`] THEN
292 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ;
293 VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ];
294 ASM_REWRITE_TAC[segment; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN
295 REWRITE_TAC[IN_ELIM_THM] THEN
296 EXISTS_TAC `(e / norm(b - c:real^N)) / (&1 + e / norm(b - c))` THEN
297 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ;
298 REAL_ARITH `&0 < x ==> &0 < &1 + x`;
299 REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; REAL_MUL_LID] THEN
300 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN
301 ASM_SIMP_TAC[REAL_FIELD `&0 < n ==> (&1 + e / n) * n = n + e`;
302 NORM_POS_LT; VECTOR_SUB_EQ; REAL_LE_ADDL] THEN
303 ASM_SIMP_TAC[NORM_POS_LT; REAL_LT_IMP_LE; VECTOR_SUB_EQ] THEN
304 EXPAND_TAC "d" THEN REWRITE_TAC[VECTOR_ARITH
305 `b:real^N = (&1 - u) % (b + e % (b - c)) + u % c <=>
306 (u - e * (&1 - u)) % (b - c) = vec 0`] THEN
307 ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN
308 MATCH_MP_TAC(REAL_FIELD
309 `&0 < e ==> e / (&1 + e) - e * (&1 - e / (&1 + e)) = &0`) THEN
310 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]]]);;
312 let FACE_OF_EQ = prove
313 (`!s t u:real^N->bool.
314 t face_of s /\ u face_of s /\
315 ~(DISJOINT (relative_interior t) (relative_interior u))
317 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
318 CONJ_TAC THEN MATCH_MP_TAC SUBSET_OF_FACE_OF THEN
319 EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THENL
320 [MP_TAC(ISPEC `u:real^N->bool` RELATIVE_INTERIOR_SUBSET);
321 MP_TAC(ISPEC `t:real^N->bool` RELATIVE_INTERIOR_SUBSET)] THEN
324 let FACE_OF_DISJOINT_RELATIVE_INTERIOR = prove
326 f face_of s /\ ~(f = s) ==> f INTER relative_interior s = {}`,
327 REPEAT STRIP_TAC THEN
328 MP_TAC(ISPECL [`s:real^N->bool`; `f:real^N->bool`; `s:real^N->bool`]
329 SUBSET_OF_FACE_OF) THEN
330 FIRST_ASSUM(MP_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
333 let FACE_OF_DISJOINT_INTERIOR = prove
335 f face_of s /\ ~(f = s) ==> f INTER interior s = {}`,
337 DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_DISJOINT_RELATIVE_INTERIOR) THEN
338 MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET_RELATIVE_INTERIOR) THEN
341 let AFFINE_HULL_FACE_OF_DISJOINT_RELATIVE_INTERIOR = prove
343 convex s /\ f face_of s /\ ~(f = s)
344 ==> affine hull f INTER relative_interior s = {}`,
345 REPEAT STRIP_TAC THEN MATCH_MP_TAC(SET_RULE
346 `!s f. a INTER s = f /\ r SUBSET s /\ f INTER r = {}
347 ==> a INTER r = {}`) THEN
348 MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `f:real^N->bool`] THEN
349 ASM_SIMP_TAC[FACE_OF_DISJOINT_RELATIVE_INTERIOR;
350 RELATIVE_INTERIOR_SUBSET] THEN
351 UNDISCH_TAC `(f:real^N->bool) face_of s` THEN
352 ASM_SIMP_TAC[FACE_OF_STILLCONVEX] THEN MESON_TAC[]);;
354 let FACE_OF_SUBSET_RELATIVE_BOUNDARY = prove
356 f face_of s /\ ~(f = s) ==> f SUBSET (s DIFF relative_interior s)`,
357 ASM_SIMP_TAC[SET_RULE `s SUBSET u DIFF t <=> s SUBSET u /\ s INTER t = {}`;
358 FACE_OF_DISJOINT_RELATIVE_INTERIOR; FACE_OF_IMP_SUBSET]);;
360 let FACE_OF_SUBSET_RELATIVE_FRONTIER = prove
362 f face_of s /\ ~(f = s) ==> f SUBSET relative_frontier s`,
364 DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_SUBSET_RELATIVE_BOUNDARY) THEN
365 REWRITE_TAC[relative_frontier] THEN
366 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]);;
368 let FACE_OF_AFF_DIM_LT = prove
370 convex s /\ f face_of s /\ ~(f = s) ==> aff_dim f < aff_dim s`,
372 SIMP_TAC[INT_LT_LE; FACE_OF_IMP_SUBSET; AFF_DIM_SUBSET] THEN
373 REWRITE_TAC[IMP_CONJ; CONTRAPOS_THM] THEN
374 ASM_CASES_TAC `f:real^N->bool = {}` THENL
375 [CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN
376 ASM_REWRITE_TAC[AFF_DIM_EQ_MINUS1; AFF_DIM_EMPTY];
377 REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN
378 EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN
379 MATCH_MP_TAC(SET_RULE `~(f = {}) /\ f SUBSET s ==> ~DISJOINT f s`) THEN
380 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
381 ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN
382 MATCH_MP_TAC SUBSET_RELATIVE_INTERIOR THEN
383 ASM_MESON_TAC[FACE_OF_IMP_SUBSET; AFF_DIM_EQ_AFFINE_HULL; INT_LE_REFL]]);;
385 let FACE_OF_CONVEX_HULLS = prove
387 FINITE s /\ f SUBSET s /\
388 DISJOINT (affine hull f) (convex hull (s DIFF f))
389 ==> (convex hull f) face_of (convex hull s)`,
392 affine s /\ ~(k = &0) /\ ~(k = &1) /\ x IN s /\ inv(&1 - k) % y IN s
393 ==> inv(k) % (x - y) IN s`,
394 REWRITE_TAC[AFFINE_ALT] THEN REPEAT STRIP_TAC THEN
396 `inv(k) % (x - y):real^N = (&1 - inv k) % inv(&1 - k) % y + inv(k) % x`
397 (fun th -> ASM_SIMP_TAC[th]) THEN
398 REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_ARITH
399 `k % (x - y):real^N = a % b % y + k % x <=> (a * b + k) % y = vec 0`] THEN
400 DISJ1_TAC THEN MAP_EVERY UNDISCH_TAC [`~(k = &0)`; `~(k = &1)`] THEN
401 CONV_TAC REAL_FIELD) in
402 REPEAT STRIP_TAC THEN REWRITE_TAC[face_of] THEN
403 SUBGOAL_THEN `FINITE(f:real^N->bool)` ASSUME_TAC THENL
404 [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
405 FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
406 ASM_SIMP_TAC[HULL_MONO; CONVEX_CONVEX_HULL] THEN
407 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `w:real^N`] THEN
408 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN
409 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
410 (X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC)) THEN
411 SUBGOAL_THEN `(w:real^N) IN affine hull f` ASSUME_TAC THENL
412 [ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET]; ALL_TAC] THEN
413 MAP_EVERY UNDISCH_TAC
414 [`(y:real^N) IN convex hull s`; `(x:real^N) IN convex hull s`] THEN
415 REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN
416 DISCH_THEN(X_CHOOSE_THEN `a:real^N->real` STRIP_ASSUME_TAC) THEN
417 DISCH_THEN(X_CHOOSE_THEN `b:real^N->real` STRIP_ASSUME_TAC) THEN
418 ABBREV_TAC `(c:real^N->real) = \x. (&1 - u) * a x + u * b x` THEN
419 SUBGOAL_THEN `!x:real^N. x IN s ==> &0 <= c x` ASSUME_TAC THENL
420 [REPEAT STRIP_TAC THEN EXPAND_TAC "c" THEN REWRITE_TAC[] THEN
421 MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
422 ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC;
424 ASM_CASES_TAC `sum (s DIFF f:real^N->bool) c = &0` THENL
425 [SUBGOAL_THEN `!x:real^N. x IN (s DIFF f) ==> c x = &0` MP_TAC THENL
426 [MATCH_MP_TAC SUM_POS_EQ_0 THEN ASM_MESON_TAC[FINITE_DIFF; IN_DIFF];
429 ASM_SIMP_TAC[IN_DIFF; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LT;
430 REAL_ARITH `&0 <= x /\ &0 <= y ==> (x + y = &0 <=> x = &0 /\ y = &0)`;
431 REAL_ENTIRE; REAL_SUB_0; REAL_LT_IMP_NE] THEN
432 STRIP_TAC THEN CONJ_TAC THENL
433 [EXISTS_TAC `a:real^N->real`; EXISTS_TAC `b:real^N->real`] THEN
434 ASM_SIMP_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(fun th g ->
435 (GEN_REWRITE_TAC RAND_CONV [GSYM th] THEN CONV_TAC SYM_CONV THEN
436 (MATCH_MP_TAC SUM_SUPERSET ORELSE MATCH_MP_TAC VSUM_SUPERSET)) g) THEN
437 ASM_SIMP_TAC[VECTOR_MUL_LZERO];
439 ABBREV_TAC `k = sum (s DIFF f:real^N->bool) c` THEN
440 SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL
441 [ASM_REWRITE_TAC[REAL_LT_LE] THEN EXPAND_TAC "k" THEN
442 MATCH_MP_TAC SUM_POS_LE THEN ASM_SIMP_TAC[FINITE_DIFF; IN_DIFF];
444 ASM_CASES_TAC `k = &1` THENL
445 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DISJOINT]) THEN
446 MATCH_MP_TAC(TAUT `b ==> ~b ==> c`) THEN
447 EXISTS_TAC `w:real^N` THEN
448 ASM_REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN
449 EXISTS_TAC `c:real^N->real` THEN
450 ASM_SIMP_TAC[IN_DIFF; SUM_DIFF; VSUM_DIFF] THEN
451 SUBGOAL_THEN `vsum f (\x:real^N. c x % x) = vec 0` SUBST1_TAC THENL
453 EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN
454 ASM_SIMP_TAC[VSUM_ADD; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN
455 REWRITE_TAC[VECTOR_SUB_RZERO]] THEN
456 SUBGOAL_THEN `sum(s DIFF f) c = sum s c - sum f (c:real^N->real)`
457 MP_TAC THENL [ASM_MESON_TAC[SUM_DIFF]; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN
458 SUBGOAL_THEN `sum s (c:real^N->real) = &1` SUBST1_TAC THENL
459 [EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN
460 ASM_SIMP_TAC[SUM_ADD; GSYM REAL_MUL_ASSOC; SUM_LMUL] THEN
463 REWRITE_TAC[REAL_ARITH `&1 = &1 - x <=> x = &0`] THEN DISCH_TAC THEN
464 MP_TAC(ISPECL [`c:real^N->real`;`f:real^N->bool`] SUM_POS_EQ_0) THEN
465 ANTS_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET; SUBSET]; ALL_TAC] THEN
466 SIMP_TAC[VECTOR_MUL_LZERO; VSUM_0];
468 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DISJOINT]) THEN
469 MATCH_MP_TAC(TAUT `b ==> ~b ==> c`) THEN
470 EXISTS_TAC `inv(k) % (w - vsum f (\x:real^N. c x % x))` THEN CONJ_TAC THENL
472 SUBGOAL_THEN `w = vsum f (\x:real^N. c x % x) +
473 vsum (s DIFF f) (\x:real^N. c x % x)`
475 [ASM_SIMP_TAC[VSUM_DIFF; VECTOR_ARITH `a + b - a:real^N = b`] THEN
476 EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN
477 ASM_SIMP_TAC[VSUM_ADD; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL];
478 REWRITE_TAC[VECTOR_ADD_SUB]] THEN
479 ASM_SIMP_TAC[GSYM VSUM_LMUL; FINITE_DIFF] THEN
480 REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN
481 EXISTS_TAC `\x. inv k * (c:real^N->real) x` THEN
482 ASM_REWRITE_TAC[VECTOR_MUL_ASSOC] THEN
483 ASM_SIMP_TAC[IN_DIFF; REAL_LE_MUL; REAL_LE_INV_EQ; REAL_LT_IMP_LE] THEN
484 ASM_SIMP_TAC[SUM_LMUL; ETA_AX; REAL_MUL_LINV]] THEN
485 MATCH_MP_TAC lemma THEN REPEAT CONJ_TAC THENL
486 [REWRITE_TAC[AFFINE_AFFINE_HULL];
489 ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET];
491 ASM_SIMP_TAC[GSYM VSUM_LMUL; AFFINE_HULL_FINITE; IN_ELIM_THM] THEN
492 EXISTS_TAC `(\x. inv(&1 - k) * c x):real^N->real` THEN
493 REWRITE_TAC[VECTOR_MUL_ASSOC; SUM_LMUL] THEN
494 MATCH_MP_TAC(REAL_FIELD
495 `~(k = &1) /\ f = &1 - k ==> inv(&1 - k) * f = &1`) THEN
496 ASM_REWRITE_TAC[] THEN
497 SUBGOAL_THEN `sum(s DIFF f) c = sum s c - sum f (c:real^N->real)`
498 MP_TAC THENL [ASM_MESON_TAC[SUM_DIFF]; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN
499 SUBGOAL_THEN `sum s (c:real^N->real) = &1` SUBST1_TAC THENL
500 [EXPAND_TAC "c" THEN REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN
501 ASM_SIMP_TAC[SUM_ADD; GSYM REAL_MUL_ASSOC; SUM_LMUL];
505 let FACE_OF_CONVEX_HULL_INSERT = prove
507 FINITE s /\ ~(a IN affine hull s) /\ f face_of (convex hull s)
508 ==> f face_of (convex hull (a INSERT s))`,
509 REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_TRANS THEN
510 EXISTS_TAC `convex hull s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
511 MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN
512 ASM_REWRITE_TAC[FINITE_INSERT; SET_RULE `s SUBSET a INSERT s`] THEN
513 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
514 `~(a IN s) ==> t SUBSET {a} ==> DISJOINT s t`)) THEN
515 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_SING] THEN SET_TAC[]);;
517 let FACE_OF_AFFINE_TRIVIAL = prove
519 affine s /\ f face_of s ==> f = {} \/ f = s`,
520 REPEAT STRIP_TAC THEN
521 ASM_CASES_TAC `f:real^N->bool = {}` THEN ASM_REWRITE_TAC[] THEN
522 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
523 DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN
524 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
525 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
526 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN
527 ASM_CASES_TAC `(b:real^N) IN f` THEN ASM_REWRITE_TAC[] THEN
528 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [face_of]) THEN
529 DISCH_THEN(MP_TAC o SPECL [`&2 % a - b:real^N`; `b:real^N`; `a:real^N`] o
530 CONJUNCT2 o CONJUNCT2) THEN
531 SUBGOAL_THEN `~(a:real^N = b)` ASSUME_TAC THENL
532 [ASM_MESON_TAC[]; ALL_TAC] THEN
533 ASM_SIMP_TAC[IN_SEGMENT; VECTOR_ARITH `&2 % a - b:real^N = b <=> a = b`] THEN
535 [REWRITE_TAC[VECTOR_ARITH `&2 % a - b:real^N = a + &1 % (a - b)`] THEN
536 MATCH_MP_TAC IN_AFFINE_ADD_MUL_DIFF THEN ASM SET_TAC[];
537 EXISTS_TAC `&1 / &2` THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
540 let FACE_OF_AFFINE_EQ = prove
541 (`!s:real^N->bool f. affine s ==> (f face_of s <=> f = {} \/ f = s)`,
542 MESON_TAC[FACE_OF_AFFINE_TRIVIAL; EMPTY_FACE_OF; FACE_OF_REFL;
543 AFFINE_IMP_CONVEX]);;
545 let INTERS_FACES_FINITE_BOUND = prove
546 (`!s f:(real^N->bool)->bool.
547 convex s /\ (!c. c IN f ==> c face_of s)
548 ==> ?f'. FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 1 /\
549 INTERS f' = INTERS f`,
551 `!s f:(real^N->bool)->bool.
552 convex s /\ (!c. c IN f ==> c face_of s /\ ~(c = s))
553 ==> ?f'. FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 1 /\
554 INTERS f' = INTERS f`
557 REPEAT STRIP_TAC THEN
558 ASM_CASES_TAC `(s:real^N->bool) IN f` THENL
559 [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]] THEN
560 FIRST_ASSUM(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC o MATCH_MP (SET_RULE
561 `s IN f ==> f = {s} \/ ?t. ~(t = s) /\ t IN f`)) THENL
562 [EXISTS_TAC `{s:real^N->bool}` THEN
563 SIMP_TAC[FINITE_INSERT; FINITE_EMPTY; SUBSET_REFL; CARD_CLAUSES] THEN
565 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC)] THEN
566 FIRST_X_ASSUM(MP_TAC o SPECL [`s:real^N->bool`; `f DELETE
567 (s:real^N->bool)`]) THEN
568 ASM_SIMP_TAC[IN_DELETE; SUBSET_DELETE] THEN
569 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f':(real^N->bool)->bool` THEN
570 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
571 SUBGOAL_THEN `f = (s:real^N->bool) INSERT (f DELETE s)` MP_TAC THENL
573 DISCH_THEN(fun th -> GEN_REWRITE_TAC (funpow 2 RAND_CONV) [th])] THEN
574 REWRITE_TAC[INTERS_INSERT] THEN
575 MATCH_MP_TAC(SET_RULE `t SUBSET s ==> t = s INTER t`) THEN
576 FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`) THEN
577 ASM_REWRITE_TAC[] THEN
578 DISCH_THEN(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
579 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `t:real^N->bool` THEN
580 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; IN_INTERS; IN_DELETE] THEN
582 REPEAT STRIP_TAC THEN ASM_CASES_TAC
583 `!f':(real^N->bool)->bool.
584 FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 1
585 ==> ?c. c IN f /\ c INTER (INTERS f') PSUBSET (INTERS f')`
588 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
589 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
590 SIMP_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN
591 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
592 ASM_REWRITE_TAC[PSUBSET; INTER_SUBSET] THEN ASM SET_TAC[]] THEN
593 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
594 [RIGHT_IMP_EXISTS_THM]) THEN
595 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
596 X_GEN_TAC `c:((real^N->bool)->bool)->real^N->bool` THEN DISCH_TAC THEN
597 CHOOSE_TAC(prove_recursive_functions_exist num_RECURSION
598 `d 0 = {c {} :real^N->bool} /\ !n. d(SUC n) = c(d n) INSERT d n`) THEN
599 SUBGOAL_THEN `!n:num. ~(d n:(real^N->bool)->bool = {})` ASSUME_TAC THENL
600 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; ALL_TAC] THEN
602 `!n. n <= dimindex(:N) + 1
603 ==> (d n) SUBSET (f:(real^N->bool)->bool) /\
604 FINITE(d n) /\ CARD(d n) <= n + 1`
606 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN
607 ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY;
608 EMPTY_SUBSET; ARITH_RULE `SUC n <= m + 1 ==> n <= m + 1`] THEN
609 REPEAT STRIP_TAC THEN TRY ASM_ARITH_TAC THEN
610 FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN
611 FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
612 ANTS_TAC THENL [ASM_ARITH_TAC; STRIP_TAC] THEN ASM_REWRITE_TAC[] THEN
613 ANTS_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[]];
616 `!n. n <= dimindex(:N)
617 ==> (INTERS(d(SUC n)):real^N->bool) PSUBSET INTERS(d n)`
619 [REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERS_INSERT] THEN
620 FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN
621 ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN
622 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN
623 ASM_SIMP_TAC[ARITH_RULE `n <= N ==> n <= N + 1`] THEN
626 FIRST_X_ASSUM(CONJUNCTS_THEN(K ALL_TAC)) THEN
628 `!n. n <= dimindex(:N) + 1
629 ==> aff_dim(INTERS(d n):real^N->bool) < &(dimindex(:N)) - &n`
632 [DISCH_TAC THEN REWRITE_TAC[INT_SUB_RZERO] THEN
633 MATCH_MP_TAC INT_LTE_TRANS THEN
634 EXISTS_TAC `aff_dim(s:real^N->bool)` THEN
635 REWRITE_TAC[AFF_DIM_LE_UNIV] THEN
636 MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN
637 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
638 [MATCH_MP_TAC FACE_OF_INTERS THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
639 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY] o
641 DISCH_THEN(X_CHOOSE_TAC `e:real^N->bool`) THEN
642 FIRST_X_ASSUM(MP_TAC o SPEC `e:real^N->bool`) THEN
643 ANTS_TAC THENL [ASM SET_TAC[]; STRIP_TAC] THEN
644 MATCH_MP_TAC(SET_RULE
645 `!t. t PSUBSET s /\ u SUBSET t ==> ~(u = s)`) THEN
646 EXISTS_TAC `e:real^N->bool` THEN
647 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
649 DISCH_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_SUC] THEN
650 MATCH_MP_TAC(INT_ARITH
651 `!d':int. d < d' /\ d' < m - n ==> d < m - (n + &1)`) THEN
652 EXISTS_TAC `aff_dim(INTERS(d(n:num)):real^N->bool)` THEN
653 ASM_SIMP_TAC[ARITH_RULE `SUC n <= k + 1 ==> n <= k + 1`] THEN
654 MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN
655 ASM_SIMP_TAC[ARITH_RULE `SUC n <= m + 1 ==> n <= m`;
656 SET_RULE `s PSUBSET t ==> ~(s = t)`] THEN
658 [MATCH_MP_TAC CONVEX_INTERS THEN
659 REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_IMP_CONVEX THEN
660 EXISTS_TAC `s:real^N->bool` THEN
661 ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 1 ==> n <= m + 1`];
663 MP_TAC(ISPECL [`INTERS(d(SUC n)):real^N->bool`;`s:real^N->bool`;
664 `INTERS(d(n:num)):real^N->bool`] FACE_OF_FACE) THEN
665 ASM_SIMP_TAC[SET_RULE `s PSUBSET t ==> s SUBSET t`;
666 ARITH_RULE `SUC n <= m + 1 ==> n <= m`] THEN
667 MATCH_MP_TAC(TAUT `a /\ b ==> (a ==> (c <=> b)) ==> c`) THEN
668 CONJ_TAC THEN MATCH_MP_TAC FACE_OF_INTERS THEN ASM_REWRITE_TAC[] THEN
669 ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 1 ==> n <= m + 1`]];
671 DISCH_THEN(MP_TAC o SPEC `dimindex(:N) + 1`) THEN REWRITE_TAC[LE_REFL] THEN
672 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[INT_NOT_LT] THEN
673 REWRITE_TAC[GSYM INT_OF_NUM_ADD; INT_ARITH `d - (d + &1):int = -- &1`] THEN
674 REWRITE_TAC[AFF_DIM_GE]);;
676 let INTERS_FACES_FINITE_ALTBOUND = prove
677 (`!s f:(real^N->bool)->bool.
678 (!c. c IN f ==> c face_of s)
679 ==> ?f'. FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 2 /\
680 INTERS f' = INTERS f`,
681 REPEAT STRIP_TAC THEN ASM_CASES_TAC
682 `!f':(real^N->bool)->bool.
683 FINITE f' /\ f' SUBSET f /\ CARD f' <= dimindex(:N) + 2
684 ==> ?c. c IN f /\ c INTER (INTERS f') PSUBSET (INTERS f')`
687 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
688 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
689 SIMP_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN
690 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
691 ASM_REWRITE_TAC[PSUBSET; INTER_SUBSET] THEN ASM SET_TAC[]] THEN
692 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
693 [RIGHT_IMP_EXISTS_THM]) THEN
694 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
695 X_GEN_TAC `c:((real^N->bool)->bool)->real^N->bool` THEN DISCH_TAC THEN
696 CHOOSE_TAC(prove_recursive_functions_exist num_RECURSION
697 `d 0 = {c {} :real^N->bool} /\ !n. d(SUC n) = c(d n) INSERT d n`) THEN
698 SUBGOAL_THEN `!n:num. ~(d n:(real^N->bool)->bool = {})` ASSUME_TAC THENL
699 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN SET_TAC[]; ALL_TAC] THEN
701 `!n. n <= dimindex(:N) + 2
702 ==> (d n) SUBSET (f:(real^N->bool)->bool) /\
703 FINITE(d n) /\ CARD(d n) <= n + 1`
705 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN
706 ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY;
707 EMPTY_SUBSET; ARITH_RULE `SUC n <= m + 2 ==> n <= m + 2`] THEN
708 REPEAT STRIP_TAC THEN TRY ASM_ARITH_TAC THEN
709 FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN
710 FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
711 ANTS_TAC THENL [ASM_ARITH_TAC; STRIP_TAC] THEN ASM_REWRITE_TAC[] THEN
712 ANTS_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[]];
715 `!n. n <= dimindex(:N) + 1
716 ==> (INTERS(d(SUC n)):real^N->bool) PSUBSET INTERS(d n)`
718 [REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERS_INSERT] THEN
719 FIRST_X_ASSUM(MP_TAC o SPEC `(d:num->(real^N->bool)->bool) n`) THEN
720 ANTS_TAC THENL [ALL_TAC; SIMP_TAC[]] THEN
721 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN
722 ASM_SIMP_TAC[ARITH_RULE `n <= N + 1 ==> n <= N + 2`] THEN
725 FIRST_X_ASSUM(CONJUNCTS_THEN(K ALL_TAC)) THEN
727 `!n. n <= dimindex(:N) + 2
728 ==> aff_dim(INTERS(d n):real^N->bool) <= &(dimindex(:N)) - &n`
730 [INDUCT_TAC THEN REWRITE_TAC[INT_SUB_RZERO; AFF_DIM_LE_UNIV] THEN
731 DISCH_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_SUC] THEN
732 MATCH_MP_TAC(INT_ARITH
733 `!d':int. d < d' /\ d' <= m - n ==> d <= m - (n + &1)`) THEN
734 EXISTS_TAC `aff_dim(INTERS(d(n:num)):real^N->bool)` THEN
735 ASM_SIMP_TAC[ARITH_RULE `SUC n <= k + 2 ==> n <= k + 2`] THEN
736 MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN
737 ASM_SIMP_TAC[ARITH_RULE `SUC n <= m + 2 ==> n <= m + 1`;
738 SET_RULE `s PSUBSET t ==> ~(s = t)`] THEN
740 [MATCH_MP_TAC CONVEX_INTERS THEN
741 REPEAT STRIP_TAC THEN MATCH_MP_TAC FACE_OF_IMP_CONVEX THEN
742 EXISTS_TAC `s:real^N->bool` THEN
743 ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 2 ==> n <= m + 2`];
745 MP_TAC(ISPECL [`INTERS(d(SUC n)):real^N->bool`;`s:real^N->bool`;
746 `INTERS(d(n:num)):real^N->bool`] FACE_OF_FACE) THEN
747 ASM_SIMP_TAC[SET_RULE `s PSUBSET t ==> s SUBSET t`;
748 ARITH_RULE `SUC n <= m + 2 ==> n <= m + 1`] THEN
749 MATCH_MP_TAC(TAUT `a /\ b ==> (a ==> (c <=> b)) ==> c`) THEN
750 CONJ_TAC THEN MATCH_MP_TAC FACE_OF_INTERS THEN ASM_REWRITE_TAC[] THEN
751 ASM_MESON_TAC[SUBSET; ARITH_RULE `SUC n <= m + 2 ==> n <= m + 2`];
753 DISCH_THEN(MP_TAC o SPEC `dimindex(:N) + 2`) THEN REWRITE_TAC[LE_REFL] THEN
754 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[INT_NOT_LE] THEN
755 REWRITE_TAC[GSYM INT_OF_NUM_ADD; INT_ARITH
756 `d - (d + &2):int < i <=> -- &1 <= i`] THEN
757 REWRITE_TAC[AFF_DIM_GE]);;
759 let FACES_OF_TRANSLATION = prove
761 {f | f face_of IMAGE (\x. a + x) s} =
762 IMAGE (IMAGE (\x. a + x)) {f | f face_of s}`,
763 REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN
764 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
765 REWRITE_TAC[IN_ELIM_THM; FACE_OF_TRANSLATION_EQ] THEN
766 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
767 ONCE_REWRITE_TAC[TRANSLATION_GALOIS] THEN
768 REWRITE_TAC[EXISTS_REFL]);;
770 let FACES_OF_LINEAR_IMAGE = prove
771 (`!f:real^M->real^N s.
772 linear f /\ (!x y. f x = f y ==> x = y)
773 ==> {t | t face_of (IMAGE f s)} = IMAGE (IMAGE f) {t | t face_of s}`,
774 REPEAT GEN_TAC THEN DISCH_TAC THEN
775 REWRITE_TAC[face_of; SUBSET_IMAGE; SET_RULE
776 `{y | (?x. P x /\ y = f x) /\ Q y} = {f x |x| P x /\ Q(f x)}`] THEN
777 REWRITE_TAC[SET_RULE `IMAGE f {x | P x} = {f x | P x}`] THEN
778 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
779 FIRST_ASSUM(fun th ->
780 REWRITE_TAC[MATCH_MP CONVEX_LINEAR_IMAGE_EQ th;
781 MATCH_MP OPEN_SEGMENT_LINEAR_IMAGE th;
783 `(!x y. f x = f y ==> x = y) ==> (!s x. f x IN IMAGE f s <=> x IN s)`)
786 let FACE_OF_CONIC = prove
787 (`!s f:real^N->bool. conic s /\ f face_of s ==> conic f`,
788 REPEAT GEN_TAC THEN REWRITE_TAC[face_of; conic] THEN STRIP_TAC THEN
789 MAP_EVERY X_GEN_TAC [`x:real^N`; `c:real`] THEN STRIP_TAC THEN
790 ASM_CASES_TAC `x:real^N = vec 0` THENL
791 [ASM_MESON_TAC[VECTOR_MUL_RZERO]; ALL_TAC] THEN
792 ASM_CASES_TAC `c = &1` THENL
793 [ASM_MESON_TAC[VECTOR_MUL_LID]; ALL_TAC] THEN
794 SUBGOAL_THEN `?d e. &0 <= d /\ &0 <= e /\ d < &1 /\ &1 < e /\ d < e /\
797 [FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
798 `~(c = &1) ==> c < &1 \/ &1 < c`))
800 [MAP_EVERY EXISTS_TAC [`c:real`; `&2`] THEN ASM_REAL_ARITH_TAC;
801 MAP_EVERY EXISTS_TAC [`&1 / &2`; `c:real`] THEN ASM_REAL_ARITH_TAC];
802 DISCH_THEN(REPEAT_TCL CHOOSE_THEN
803 (REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN
804 FIRST_X_ASSUM(MP_TAC o SPECL
805 [`d % x :real^N`; `e % x:real^N`; `x:real^N`]) THEN
806 ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
807 SUBGOAL_THEN `(x:real^N) IN s` ASSUME_TAC THENL
808 [ASM SET_TAC[]; ASM_SIMP_TAC[IN_SEGMENT]] THEN
809 ASM_SIMP_TAC[VECTOR_MUL_RCANCEL; REAL_LT_IMP_NE] THEN
810 EXISTS_TAC `(&1 - d) / (e - d)` THEN
811 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN
812 REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
813 REWRITE_TAC[VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_RDISTRIB] THEN
814 REWRITE_TAC[VECTOR_ARITH `x:real^N = a % x <=> (a - &1) % x = vec 0`] THEN
815 ASM_REWRITE_TAC[VECTOR_MUL_EQ_0] THEN
816 UNDISCH_TAC `d:real < e` THEN CONV_TAC REAL_FIELD]);;
818 let FACE_OF_PCROSS = prove
819 (`!f s:real^M->bool f' s':real^N->bool.
820 f face_of s /\ f' face_of s' ==> (f PCROSS f') face_of (s PCROSS s')`,
821 REPEAT GEN_TAC THEN SIMP_TAC[face_of; CONVEX_PCROSS; PCROSS_MONO] THEN
822 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
823 REWRITE_TAC[IN_SEGMENT; FORALL_IN_PCROSS] THEN
824 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN
825 REWRITE_TAC[GSYM PASTECART_CMUL; PASTECART_ADD; PASTECART_INJ] THEN
826 REWRITE_TAC[PASTECART_IN_PCROSS] THEN
828 [`a:real^M`; `a':real^N`; `b:real^M`; `b':real^N`] THEN
829 MAP_EVERY ASM_CASES_TAC [`b:real^M = a`; `b':real^N = a'`] THEN
830 ASM_REWRITE_TAC[VECTOR_ARITH `(&1 - u) % a + u % a:real^N = a`] THEN
833 let FACE_OF_PCROSS_DECOMP = prove
834 (`!s:real^M->bool s':real^N->bool c.
835 c face_of (s PCROSS s') <=>
836 ?f f'. f face_of s /\ f' face_of s' /\ c = f PCROSS f'`,
837 REPEAT GEN_TAC THEN EQ_TAC THENL
838 [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[FACE_OF_PCROSS]] THEN
839 ASM_CASES_TAC `c:real^(M,N)finite_sum->bool = {}` THENL
840 [ASM_MESON_TAC[EMPTY_FACE_OF; PCROSS_EMPTY]; DISCH_TAC] THEN
841 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
843 [`IMAGE fstcart (c:real^(M,N)finite_sum->bool)`;
844 `IMAGE sndcart (c:real^(M,N)finite_sum->bool)`] THEN
845 MATCH_MP_TAC(TAUT `(p /\ q ==> r) /\ p /\ q ==> p /\ q /\ r`) THEN
847 [STRIP_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN
848 EXISTS_TAC `(s:real^M->bool) PCROSS (s':real^N->bool)` THEN
849 ASM_SIMP_TAC[FACE_OF_PCROSS; RELATIVE_INTERIOR_PCROSS] THEN
850 ASM_SIMP_TAC[RELATIVE_INTERIOR_LINEAR_IMAGE_CONVEX;
851 LINEAR_FSTCART; LINEAR_SNDCART] THEN
852 MATCH_MP_TAC(SET_RULE `~(s = {}) /\ s SUBSET t ==> ~DISJOINT s t`) THEN
853 ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN
854 REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS; IN_IMAGE] THEN
855 REWRITE_TAC[EXISTS_PASTECART; FSTCART_PASTECART; SNDCART_PASTECART] THEN
858 FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [face_of]) THEN
859 REWRITE_TAC[face_of] THEN
860 ASM_SIMP_TAC[CONVEX_LINEAR_IMAGE; LINEAR_FSTCART; LINEAR_SNDCART] THEN
861 FIRST_ASSUM(MP_TAC o ISPEC `fstcart:real^(M,N)finite_sum->real^M` o
862 MATCH_MP IMAGE_SUBSET) THEN
863 FIRST_ASSUM(MP_TAC o ISPEC `sndcart:real^(M,N)finite_sum->real^N` o
864 MATCH_MP IMAGE_SUBSET) THEN
865 REWRITE_TAC[IMAGE_FSTCART_PCROSS; IMAGE_SNDCART_PCROSS] THEN
866 REPEAT(DISCH_THEN(ASSUME_TAC o MATCH_MP (SET_RULE
867 `s SUBSET (if p then {} else t) ==> s SUBSET t`))) THEN
868 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
869 [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `x:real^M`] THEN
870 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_IMAGE]) THEN
871 REWRITE_TAC[EXISTS_PASTECART; FSTCART_PASTECART] THEN
872 REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN
873 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN FIRST_X_ASSUM(MP_TAC o SPECL
874 [`pastecart (a:real^M) (y:real^N)`;
875 `pastecart (b:real^M) (y:real^N)`;
876 `pastecart (x:real^M) (y:real^N)`]) THEN
877 ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_IMAGE; EXISTS_PASTECART] THEN
878 REWRITE_TAC[FSTCART_PASTECART; RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN
879 ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
880 UNDISCH_TAC `(c:real^(M,N)finite_sum->bool) SUBSET s PCROSS s'` THEN
881 REWRITE_TAC[SUBSET] THEN
882 DISCH_THEN(MP_TAC o SPEC `pastecart (x:real^M) (y:real^N)`);
883 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
884 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_IMAGE]) THEN
885 REWRITE_TAC[EXISTS_PASTECART; SNDCART_PASTECART] THEN
886 REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN
887 DISCH_THEN(X_CHOOSE_TAC `y:real^M`) THEN FIRST_X_ASSUM(MP_TAC o SPECL
888 [`pastecart (y:real^M) (a:real^N)`;
889 `pastecart (y:real^M) (b:real^N)`;
890 `pastecart (y:real^M) (x:real^N)`]) THEN
891 ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_IMAGE; EXISTS_PASTECART] THEN
892 REWRITE_TAC[SNDCART_PASTECART; RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN
893 ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
894 UNDISCH_TAC `(c:real^(M,N)finite_sum->bool) SUBSET s PCROSS s'` THEN
895 REWRITE_TAC[SUBSET] THEN
896 DISCH_THEN(MP_TAC o SPEC `pastecart (y:real^M) (x:real^N)`)] THEN
897 ASM_REWRITE_TAC[PASTECART_IN_PCROSS] THEN STRIP_TAC THEN
898 ASM_REWRITE_TAC[] THEN
899 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN
900 REWRITE_TAC[IN_SEGMENT; PASTECART_INJ] THEN
901 REWRITE_TAC[PASTECART_ADD; GSYM PASTECART_CMUL;
902 VECTOR_ARITH `(&1 - u) % a + u % a:real^N = a`] THEN
905 let FACE_OF_PCROSS_EQ = prove
906 (`!f s:real^M->bool f' s':real^N->bool.
907 (f PCROSS f') face_of (s PCROSS s') <=>
908 f = {} \/ f' = {} \/ f face_of s /\ f' face_of s'`,
909 REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC
910 [`f:real^M->bool = {}`; `f':real^N->bool = {}`] THEN
911 ASM_REWRITE_TAC[PCROSS_EMPTY; EMPTY_FACE_OF] THEN
912 ASM_REWRITE_TAC[FACE_OF_PCROSS_DECOMP; PCROSS_EQ] THEN MESON_TAC[]);;
914 let HYPERPLANE_FACE_OF_HALFSPACE_LE = prove
915 (`!a:real^N b. {x | a dot x = b} face_of {x | a dot x <= b}`,
917 ONCE_REWRITE_TAC[REAL_ARITH `a:real = b <=> a <= b /\ a = b`] THEN
918 REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
919 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
920 REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_LE]);;
922 let HYPERPLANE_FACE_OF_HALFSPACE_GE = prove
923 (`!a:real^N b. {x | a dot x = b} face_of {x | a dot x >= b}`,
925 ONCE_REWRITE_TAC[REAL_ARITH `a:real = b <=> a >= b /\ a = b`] THEN
926 REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
927 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN
928 REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_GE]);;
930 let FACE_OF_HALFSPACE_LE = prove
932 f face_of {x | a dot x <= b} <=>
933 f = {} \/ f = {x | a dot x = b} \/ f = {x | a dot x <= b}`,
934 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
935 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
936 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[FACE_OF_EMPTY]) THEN
937 ASM_SIMP_TAC[FACE_OF_AFFINE_EQ; AFFINE_UNIV; DISJ_ACI] THEN
940 EQ_TAC THEN STRIP_TAC THEN
941 ASM_SIMP_TAC[EMPTY_FACE_OF; FACE_OF_REFL; CONVEX_HALFSPACE_LE;
942 HYPERPLANE_FACE_OF_HALFSPACE_LE] THEN
943 MATCH_MP_TAC(TAUT `(~r ==> p \/ q) ==> p \/ q \/ r`) THEN DISCH_TAC THEN
944 SUBGOAL_THEN `f face_of {x:real^N | a dot x = b}` MP_TAC THENL
945 [ASM_SIMP_TAC[GSYM FRONTIER_HALFSPACE_LE] THEN
946 ASM_SIMP_TAC[CONV_RULE(RAND_CONV SYM_CONV)
947 (SPEC_ALL RELATIVE_FRONTIER_NONEMPTY_INTERIOR);
948 INTERIOR_HALFSPACE_LE; HALFSPACE_EQ_EMPTY_LT] THEN
949 MATCH_MP_TAC FACE_OF_SUBSET THEN
950 EXISTS_TAC `{x:real^N | a dot x <= b}` THEN
951 ASM_SIMP_TAC[FACE_OF_SUBSET_RELATIVE_FRONTIER] THEN
952 ASM_SIMP_TAC[relative_frontier; CLOSURE_CLOSED; CLOSED_HALFSPACE_LE] THEN
954 ASM_SIMP_TAC[FACE_OF_AFFINE_EQ; AFFINE_HYPERPLANE]]);;
956 let FACE_OF_HALFSPACE_GE = prove
958 f face_of {x | a dot x >= b} <=>
959 f = {} \/ f = {x | a dot x = b} \/ f = {x | a dot x >= b}`,
961 MP_TAC(ISPECL [`f:real^N->bool`; `--a:real^N`; `--b:real`]
962 FACE_OF_HALFSPACE_LE) THEN
963 REWRITE_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2; real_ge]);;
965 (* ------------------------------------------------------------------------- *)
966 (* Exposed faces (faces that are intersection with supporting hyperplane). *)
967 (* ------------------------------------------------------------------------- *)
969 parse_as_infix("exposed_face_of",(12,"right"));;
971 let exposed_face_of = new_definition
972 `t exposed_face_of s <=>
974 ?a b. s SUBSET {x | a dot x <= b} /\ t = s INTER {x | a dot x = b}`;;
976 let EMPTY_EXPOSED_FACE_OF = prove
977 (`!s:real^N->bool. {} exposed_face_of s`,
978 GEN_TAC THEN REWRITE_TAC[exposed_face_of; EMPTY_FACE_OF] THEN
979 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&1:real`] THEN
980 REWRITE_TAC[DOT_LZERO] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN SET_TAC[]);;
982 let EXPOSED_FACE_OF_REFL_EQ = prove
983 (`!s:real^N->bool. s exposed_face_of s <=> convex s`,
984 GEN_TAC THEN REWRITE_TAC[exposed_face_of; FACE_OF_REFL_EQ] THEN
985 ASM_CASES_TAC `convex(s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN
986 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&0:real`] THEN
987 REWRITE_TAC[DOT_LZERO] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN SET_TAC[]);;
989 let EXPOSED_FACE_OF_REFL = prove
990 (`!s:real^N->bool. convex s ==> s exposed_face_of s`,
991 REWRITE_TAC[EXPOSED_FACE_OF_REFL_EQ]);;
993 let EXPOSED_FACE_OF = prove
994 (`!s t. t exposed_face_of s <=>
997 ?a b. ~(a = vec 0) /\
998 s SUBSET {x:real^N | a dot x <= b} /\
999 t = s INTER {x | a dot x = b})`,
1000 REPEAT GEN_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THEN
1001 ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF; EMPTY_FACE_OF] THEN
1002 ASM_CASES_TAC `t:real^N->bool = s` THEN
1003 ASM_REWRITE_TAC[EXPOSED_FACE_OF_REFL_EQ; FACE_OF_REFL_EQ] THEN
1004 REWRITE_TAC[exposed_face_of] THEN AP_TERM_TAC THEN
1005 EQ_TAC THENL [REWRITE_TAC[LEFT_IMP_EXISTS_THM]; MESON_TAC[]] THEN
1006 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN
1007 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1008 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN
1009 ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[] THEN
1010 FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT(POP_ASSUM MP_TAC) THEN
1011 REWRITE_TAC[DOT_LZERO] THEN SET_TAC[]);;
1013 let EXPOSED_FACE_OF_TRANSLATION_EQ = prove
1014 (`!a f s:real^N->bool.
1015 (IMAGE (\x. a + x) f) exposed_face_of (IMAGE (\x. a + x) s) <=>
1016 f exposed_face_of s`,
1017 REPEAT GEN_TAC THEN REWRITE_TAC[exposed_face_of; FACE_OF_TRANSLATION_EQ] THEN
1018 MP_TAC(ISPEC `\x:real^N. a + x` QUANTIFY_SURJECTION_THM) THEN
1019 REWRITE_TAC[] THEN ANTS_TAC THENL
1020 [MESON_TAC[VECTOR_ARITH `y + (x - y):real^N = x`]; ALL_TAC] THEN
1021 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
1022 [last(CONJUNCTS th)]) THEN
1023 REWRITE_TAC[end_itlist CONJ (!invariant_under_translation)] THEN
1024 REWRITE_TAC[DOT_RADD] THEN ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN
1025 REWRITE_TAC[GSYM REAL_LE_SUB_LADD; GSYM REAL_EQ_SUB_LADD] THEN
1026 AP_TERM_TAC THEN AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
1027 X_GEN_TAC `c:real^N` THEN REWRITE_TAC[] THEN
1028 EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `b:real` STRIP_ASSUME_TAC) THENL
1029 [EXISTS_TAC `b - (c:real^N) dot a`;
1030 EXISTS_TAC `b + (c:real^N) dot a`] THEN
1031 ASM_REWRITE_TAC[REAL_ARITH `(x + y) - y:real = x`]);;
1033 add_translation_invariants [EXPOSED_FACE_OF_TRANSLATION_EQ];;
1035 let EXPOSED_FACE_OF_LINEAR_IMAGE = prove
1036 (`!f:real^M->real^N c s.
1037 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
1038 ==> ((IMAGE f c) exposed_face_of (IMAGE f s) <=> c exposed_face_of s)`,
1039 REPEAT STRIP_TAC THEN REWRITE_TAC[exposed_face_of] THEN
1040 BINOP_TAC THENL [ASM_MESON_TAC[FACE_OF_LINEAR_IMAGE]; ALL_TAC] THEN
1041 MP_TAC(ISPEC `f:real^M->real^N` QUANTIFY_SURJECTION_THM) THEN
1042 ASM_REWRITE_TAC[] THEN
1043 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
1044 [last(CONJUNCTS th)]) THEN
1045 ONCE_REWRITE_TAC[DOT_SYM] THEN ASM_SIMP_TAC[ADJOINT_WORKS] THEN
1046 MP_TAC(end_itlist CONJ
1047 (mapfilter (ISPEC `f:real^M->real^N`) (!invariant_under_linear))) THEN
1048 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
1049 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN
1051 [DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
1052 EXISTS_TAC `adjoint(f:real^M->real^N) a` THEN ASM_REWRITE_TAC[];
1053 DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN
1054 MP_TAC(ISPEC `adjoint(f:real^M->real^N)`
1055 LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
1056 ASM_SIMP_TAC[ADJOINT_SURJECTIVE; ADJOINT_LINEAR] THEN
1057 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; LEFT_IMP_EXISTS_THM] THEN
1058 X_GEN_TAC `g:real^M->real^N` THEN STRIP_TAC THEN
1059 EXISTS_TAC `(g:real^M->real^N) a` THEN ASM_REWRITE_TAC[]]);;
1061 let EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove
1063 convex s /\ (!x. x IN s ==> a dot x <= b)
1064 ==> (s INTER {x | a dot x = b}) exposed_face_of s`,
1065 SIMP_TAC[FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE; exposed_face_of] THEN
1068 let EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove
1070 convex s /\ (!x. x IN s ==> a dot x >= b)
1071 ==> (s INTER {x | a dot x = b}) exposed_face_of s`,
1072 REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN
1073 MP_TAC(ISPECL [`s:real^N->bool`; `--a:real^N`; `--b:real`]
1074 EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE) THEN
1075 ASM_REWRITE_TAC[DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2]);;
1077 let EXPOSED_FACE_OF_INTER = prove
1078 (`!s t u:real^N->bool.
1079 t exposed_face_of s /\ u exposed_face_of s
1080 ==> (t INTER u) exposed_face_of s`,
1081 REPEAT GEN_TAC THEN SIMP_TAC[exposed_face_of; FACE_OF_INTER] THEN
1082 REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
1083 REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
1085 [`a':real^N`; `b':real`; `a:real^N`; `b:real`] THEN
1086 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN STRIP_TAC THEN
1087 ASM_REWRITE_TAC[] THEN
1088 MAP_EVERY EXISTS_TAC [`a + a':real^N`; `b + b':real`] THEN
1089 REWRITE_TAC[SET_RULE
1090 `(s INTER t1) INTER (s INTER t2) = s INTER u <=>
1091 !x. x IN s ==> (x IN t1 /\ x IN t2 <=> x IN u)`] THEN
1092 ASM_SIMP_TAC[DOT_LADD; REAL_LE_ADD2; IN_ELIM_THM] THEN
1093 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1094 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`)) THEN
1095 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
1097 let EXPOSED_FACE_OF_INTERS = prove
1098 (`!P s:real^N->bool.
1099 ~(P = {}) /\ (!t. t IN P ==> t exposed_face_of s)
1100 ==> INTERS P exposed_face_of s`,
1101 REPEAT STRIP_TAC THEN
1102 MP_TAC(ISPECL [`s:real^N->bool`; `P:(real^N->bool)->bool`]
1103 INTERS_FACES_FINITE_ALTBOUND) THEN
1104 ANTS_TAC THENL [ASM_MESON_TAC[exposed_face_of]; ALL_TAC] THEN
1105 DISCH_THEN(X_CHOOSE_THEN `Q:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
1106 FIRST_X_ASSUM(MP_TAC o SYM) THEN
1107 ASM_CASES_TAC `Q:(real^N->bool)->bool = {}` THENL
1108 [ASM_SIMP_TAC[INTERS_0] THEN
1109 REWRITE_TAC[SET_RULE `INTERS s = UNIV <=> !t. t IN s ==> t = UNIV`] THEN
1110 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
1112 DISCH_THEN SUBST1_TAC THEN
1113 FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN
1114 SUBGOAL_THEN `!t:real^N->bool. t IN Q ==> t exposed_face_of s` MP_TAC THENL
1115 [ASM SET_TAC[]; UNDISCH_TAC `FINITE(Q:(real^N->bool)->bool)`] THEN
1116 SPEC_TAC(`Q:(real^N->bool)->bool`,`Q:(real^N->bool)->bool`) THEN
1117 POP_ASSUM_LIST(K ALL_TAC) THEN
1118 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[FORALL_IN_INSERT] THEN
1119 MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `P:(real^N->bool)->bool`] THEN
1120 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
1121 REWRITE_TAC[INTERS_INSERT] THEN
1122 ASM_CASES_TAC `P:(real^N->bool)->bool = {}` THEN
1123 ASM_SIMP_TAC[INTERS_0; INTER_UNIV; EXPOSED_FACE_OF_INTER]]);;
1125 let EXPOSED_FACE_OF_SUMS = prove
1126 (`!s t f:real^N->bool.
1127 convex s /\ convex t /\
1128 f exposed_face_of {x + y | x IN s /\ y IN t}
1129 ==> ?k l. k exposed_face_of s /\ l exposed_face_of t /\
1130 f = {x + y | x IN k /\ y IN l}`,
1131 REPEAT STRIP_TAC THEN
1132 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXPOSED_FACE_OF]) THEN
1133 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1134 ASM_CASES_TAC `f:real^N->bool = {}` THENL
1135 [DISCH_TAC THEN REPEAT (EXISTS_TAC `{}:real^N->bool`) THEN
1136 ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF] THEN SET_TAC[];
1138 ASM_CASES_TAC `f = {x + y :real^N | x IN s /\ y IN t}` THENL
1140 MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `t:real^N->bool`] THEN
1141 ASM_SIMP_TAC[EXPOSED_FACE_OF_REFL];
1143 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1144 MAP_EVERY X_GEN_TAC [`u:real^N`; `z:real`] THEN
1145 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM] THEN
1146 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1147 DISCH_THEN SUBST_ALL_TAC THEN
1148 RULE_ASSUM_TAC(REWRITE_RULE[GSYM SUBSET_INTER_ABSORPTION]) THEN
1149 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
1150 REWRITE_TAC[EXISTS_IN_GSPEC; IN_INTER] THEN
1151 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
1152 MAP_EVERY X_GEN_TAC [`a0:real^N`; `b0:real^N`] THEN STRIP_TAC THEN
1153 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
1154 EXISTS_TAC `s INTER {x:real^N | u dot x = u dot a0}` THEN
1155 EXISTS_TAC `t INTER {y:real^N | u dot y = u dot b0}` THEN
1156 REPEAT CONJ_TAC THENL
1157 [MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
1158 ASM_REWRITE_TAC[] THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
1159 FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b0:real^N`]) THEN
1160 ASM_REWRITE_TAC[DOT_RADD] THEN REAL_ARITH_TAC;
1161 MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
1162 ASM_REWRITE_TAC[] THEN X_GEN_TAC `b:real^N` THEN DISCH_TAC THEN
1163 FIRST_X_ASSUM(MP_TAC o SPECL [`a0:real^N`; `b:real^N`]) THEN
1164 ASM_REWRITE_TAC[DOT_RADD] THEN REAL_ARITH_TAC;
1166 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN
1167 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_INTER; IMP_CONJ] THENL
1168 [ALL_TAC; SIMP_TAC[IN_INTER; IN_ELIM_THM; DOT_RADD] THEN MESON_TAC[]] THEN
1169 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
1170 DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM; DOT_RADD] THEN
1171 DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN
1172 ASM_REWRITE_TAC[] THEN
1173 FIRST_ASSUM(MP_TAC o SPECL [`a:real^N`; `b0:real^N`]) THEN
1174 FIRST_X_ASSUM(MP_TAC o SPECL [`a0:real^N`; `b:real^N`]) THEN
1175 ASM_REWRITE_TAC[DOT_RADD] THEN ASM_REAL_ARITH_TAC);;
1177 let EXPOSED_FACE_OF_PARALLEL = prove
1178 (`!t s. t exposed_face_of s <=>
1180 ?a b. s SUBSET {x:real^N | a dot x <= b} /\
1181 t = s INTER {x | a dot x = b} /\
1182 (~(t = {}) /\ ~(t = s) ==> ~(a = vec 0)) /\
1183 (!w. w IN affine hull s /\ ~(t = s)
1184 ==> (w + a) IN affine hull s)`,
1185 REPEAT GEN_TAC THEN REWRITE_TAC[exposed_face_of] THEN
1186 AP_TERM_TAC THEN EQ_TAC THENL
1187 [REWRITE_TAC[LEFT_IMP_EXISTS_THM];
1188 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN SIMP_TAC[]] THEN
1189 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN STRIP_TAC THEN
1190 MP_TAC(ISPECL [`affine hull s:real^N->bool`; `--a:real^N`; `--b:real`]
1191 AFFINE_PARALLEL_SLICE) THEN
1192 SIMP_TAC[AFFINE_AFFINE_HULL; DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2] THEN
1193 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THENL
1194 [MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&1`] THEN
1195 REWRITE_TAC[DOT_LZERO; REAL_POS; SET_RULE `{x | T} = UNIV`] THEN
1196 SIMP_TAC[SUBSET_UNIV; VECTOR_ADD_RID; REAL_ARITH `~(&0 = &1)`] THEN
1197 REWRITE_TAC[EMPTY_GSPEC] THEN ASM_REWRITE_TAC[INTER_EMPTY] THEN
1198 MATCH_MP_TAC(TAUT `p ==> p /\ ~(~p /\ q)`) THEN
1199 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
1201 ==> s SUBSET s' /\ t SUBSET t' ==> s INTER t = {}`)) THEN
1202 REWRITE_TAC[HULL_SUBSET] THEN SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL];
1203 SUBGOAL_THEN `t:real^N->bool = s` SUBST1_TAC THENL
1204 [FIRST_X_ASSUM SUBST1_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
1205 SUBGOAL_THEN `s SUBSET affine hull (s:real^N->bool)` MP_TAC THENL
1206 [REWRITE_TAC[HULL_SUBSET]; ASM SET_TAC[]];
1207 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `&0`] THEN
1208 REWRITE_TAC[DOT_LZERO; SET_RULE `{x | T} = UNIV`; REAL_LE_REFL] THEN
1210 FIRST_X_ASSUM(X_CHOOSE_THEN `a':real^N` MP_TAC) THEN
1211 DISCH_THEN(X_CHOOSE_THEN `b':real` STRIP_ASSUME_TAC) THEN
1212 MAP_EVERY EXISTS_TAC [`--a':real^N`; `--b':real`] THEN
1213 ASM_REWRITE_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2] THEN
1214 REPEAT CONJ_TAC THENL
1215 [ONCE_REWRITE_TAC[REAL_ARITH `b <= a <=> ~(a <= b) \/ a = b`] THEN
1216 MATCH_MP_TAC(SET_RULE
1217 `!s'. s SUBSET s' /\
1218 s SUBSET (UNIV DIFF (s' INTER {x | P x})) UNION
1219 (s' INTER {x | Q x})
1220 ==> s SUBSET {x | ~P x \/ Q x}`) THEN
1221 EXISTS_TAC `affine hull s:real^N->bool` THEN
1222 ASM_REWRITE_TAC[HULL_SUBSET] THEN
1223 MATCH_MP_TAC(SET_RULE
1224 `s SUBSET s' /\ s SUBSET (UNIV DIFF {x | P x}) UNION {x | Q x}
1225 ==> s SUBSET (UNIV DIFF (s' INTER {x | P x})) UNION
1226 (s' INTER {x | Q x})`) THEN
1227 REWRITE_TAC[HULL_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN
1228 EXISTS_TAC `{x:real^N | a dot x <= b}` THEN ASM_REWRITE_TAC[] THEN
1229 REWRITE_TAC[SUBSET; IN_DIFF; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN
1231 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
1232 `s' INTER a = s' INTER b
1233 ==> s SUBSET s' ==> s INTER b = s INTER a`)) THEN
1234 REWRITE_TAC[HULL_SUBSET];
1235 ASM_REWRITE_TAC[VECTOR_NEG_EQ_0];
1236 ONCE_REWRITE_TAC[VECTOR_ARITH
1237 `w + --a:real^N = w + &1 % (w - (w + a))`] THEN
1238 ASM_SIMP_TAC[IN_AFFINE_ADD_MUL_DIFF; AFFINE_AFFINE_HULL]]]);;
1240 (* ------------------------------------------------------------------------- *)
1241 (* Extreme points of a set, which are its singleton faces. *)
1242 (* ------------------------------------------------------------------------- *)
1244 parse_as_infix("extreme_point_of",(12,"right"));;
1246 let extreme_point_of = new_definition
1247 `x extreme_point_of s <=>
1248 x IN s /\ !a b. a IN s /\ b IN s ==> ~(x IN segment(a,b))`;;
1250 let EXTREME_POINT_OF_STILLCONVEX = prove
1252 convex s ==> (x extreme_point_of s <=> x IN s /\ convex(s DELETE x))`,
1253 REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; extreme_point_of; open_segment] THEN
1254 REWRITE_TAC[IN_DIFF; IN_DELETE; IN_INSERT; NOT_IN_EMPTY; SUBSET_DELETE] THEN
1257 let FACE_OF_SING = prove
1258 (`!x s. {x} face_of s <=> x extreme_point_of s`,
1259 SIMP_TAC[face_of; extreme_point_of; SING_SUBSET; CONVEX_SING; IN_SING] THEN
1260 MESON_TAC[SEGMENT_REFL; NOT_IN_EMPTY]);;
1262 let EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR = prove
1264 x extreme_point_of s /\ ~(s = {x})
1265 ==> ~(x IN relative_interior s)`,
1266 REPEAT GEN_TAC THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN
1267 REWRITE_TAC[GSYM FACE_OF_SING] THEN
1268 DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_DISJOINT_RELATIVE_INTERIOR) THEN
1271 let EXTREME_POINT_NOT_IN_INTERIOR = prove
1272 (`!s x:real^N. x extreme_point_of s ==> ~(x IN interior s)`,
1273 REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `s = {x:real^N}` THEN
1274 ASM_SIMP_TAC[EMPTY_INTERIOR_FINITE; FINITE_SING; NOT_IN_EMPTY] THEN
1275 DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
1276 INTERIOR_SUBSET_RELATIVE_INTERIOR)) THEN
1277 ASM_SIMP_TAC[EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR]);;
1279 let EXTREME_POINT_OF_FACE = prove
1280 (`!f s v. f face_of s
1281 ==> (v extreme_point_of f <=> v extreme_point_of s /\ v IN f)`,
1282 REWRITE_TAC[GSYM FACE_OF_SING; GSYM SING_SUBSET; FACE_OF_FACE]);;
1284 let EXTREME_POINT_OF_MIDPOINT = prove
1287 ==> (x extreme_point_of s <=>
1289 !a b. a IN s /\ b IN s /\ x = midpoint(a,b) ==> x = a /\ x = b)`,
1290 REPEAT STRIP_TAC THEN REWRITE_TAC[extreme_point_of] THEN
1291 AP_TERM_TAC THEN EQ_TAC THEN
1292 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
1294 [FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN
1295 ASM_SIMP_TAC[MIDPOINT_IN_SEGMENT; MIDPOINT_REFL];
1297 REWRITE_TAC[IN_SEGMENT] THEN DISCH_THEN(CONJUNCTS_THEN2
1298 ASSUME_TAC (X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC)) THEN
1299 ABBREV_TAC `d = min (&1 - u) u` THEN
1300 FIRST_X_ASSUM(MP_TAC o SPECL
1301 [`x - d / &2 % (b - a):real^N`; `x + d / &2 % (b - a):real^N`]) THEN
1302 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
1303 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN
1304 ASM_REWRITE_TAC[VECTOR_ARITH
1305 `((&1 - u) % a + u % b) - d / &2 % (b - a):real^N =
1306 (&1 - (u - d / &2)) % a + (u - d / &2) % b`] THEN
1307 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
1308 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONVEX_ALT]) THEN
1309 ASM_REWRITE_TAC[VECTOR_ARITH
1310 `((&1 - u) % a + u % b) + d / &2 % (b - a):real^N =
1311 (&1 - (u + d / &2)) % a + (u + d / &2) % b`] THEN
1312 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
1313 REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC;
1314 REWRITE_TAC[VECTOR_ARITH `x:real^N = x - d <=> d = vec 0`;
1315 VECTOR_ARITH `x:real^N = x + d <=> d = vec 0`] THEN
1316 ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN ASM_REAL_ARITH_TAC]);;
1318 let EXTREME_POINT_OF_CONVEX_HULL = prove
1319 (`!x:real^N s. x extreme_point_of (convex hull s) ==> x IN s`,
1321 SIMP_TAC[EXTREME_POINT_OF_STILLCONVEX; CONVEX_CONVEX_HULL] THEN
1322 MP_TAC(ISPECL [`convex:(real^N->bool)->bool`; `s:real^N->bool`;
1323 `(convex hull s) DELETE (x:real^N)`] HULL_MINIMAL) THEN
1324 MP_TAC(ISPECL [`convex:(real^N->bool)->bool`; `s:real^N->bool`]
1328 let EXTREME_POINTS_OF_CONVEX_HULL = prove
1329 (`!s. {x | x extreme_point_of (convex hull s)} SUBSET s`,
1330 REWRITE_TAC[SUBSET; IN_ELIM_THM; EXTREME_POINT_OF_CONVEX_HULL]);;
1332 let EXTREME_POINT_OF_EMPTY = prove
1333 (`!x. ~(x extreme_point_of {})`,
1334 REWRITE_TAC[extreme_point_of; NOT_IN_EMPTY]);;
1336 let EXTREME_POINT_OF_SING = prove
1337 (`!a x. x extreme_point_of {a} <=> x = a`,
1338 REWRITE_TAC[extreme_point_of; IN_SING] THEN
1339 MESON_TAC[SEGMENT_REFL; NOT_IN_EMPTY]);;
1341 let EXTREME_POINT_OF_TRANSLATION_EQ = prove
1343 (a + x) extreme_point_of (IMAGE (\x. a + x) s) <=>
1344 x extreme_point_of s`,
1345 REWRITE_TAC[extreme_point_of] THEN GEOM_TRANSLATE_TAC[]);;
1347 add_translation_invariants [EXTREME_POINT_OF_TRANSLATION_EQ];;
1349 let EXTREME_POINT_OF_LINEAR_IMAGE = prove
1350 (`!f:real^M->real^N.
1351 linear f /\ (!x y. f x = f y ==> x = y)
1352 ==> ((f x) extreme_point_of (IMAGE f s) <=> x extreme_point_of s)`,
1353 REWRITE_TAC[GSYM FACE_OF_SING] THEN GEOM_TRANSFORM_TAC[]);;
1355 add_linear_invariants [EXTREME_POINT_OF_LINEAR_IMAGE];;
1357 let EXTREME_POINTS_OF_TRANSLATION = prove
1358 (`!a s. {x:real^N | x extreme_point_of (IMAGE (\x. a + x) s)} =
1359 IMAGE (\x. a + x) {x | x extreme_point_of s}`,
1360 REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN
1361 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
1362 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL] THEN
1363 REWRITE_TAC[IN_ELIM_THM; EXTREME_POINT_OF_TRANSLATION_EQ]);;
1365 let EXTREME_POINT_OF_INTER = prove
1366 (`!x s t. x extreme_point_of s /\ x extreme_point_of t
1367 ==> x extreme_point_of (s INTER t)`,
1368 REWRITE_TAC[extreme_point_of; IN_INTER] THEN MESON_TAC[]);;
1370 let EXTREME_POINTS_OF_LINEAR_IMAGE = prove
1371 (`!f:real^M->real^N.
1372 linear f /\ (!x y. f x = f y ==> x = y)
1373 ==> {y | y extreme_point_of (IMAGE f s)} =
1374 IMAGE f {x | x extreme_point_of s}`,
1376 REPEAT GEN_TAC THEN DISCH_TAC THEN
1377 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_SEGMENT_LINEAR_IMAGE) THEN
1378 MATCH_MP_TAC SUBSET_ANTISYM THEN
1379 REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_GSPEC; SUBSET;
1380 extreme_point_of; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
1381 ASM_SIMP_TAC[FUN_IN_IMAGE; IN_ELIM_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN
1384 let EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove
1385 (`!s a b c. (!x. x IN s ==> a dot x <= b) /\
1386 s INTER {x | a dot x = b} = {c}
1387 ==> c extreme_point_of s`,
1388 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
1389 FIRST_ASSUM(SUBST1_TAC o SYM) THEN
1390 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE_STRONG THEN
1391 ASM_REWRITE_TAC[CONVEX_SING]);;
1393 let EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove
1394 (`!s a b c. (!x. x IN s ==> a dot x >= b) /\
1395 s INTER {x | a dot x = b} = {c}
1396 ==> c extreme_point_of s`,
1397 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
1398 FIRST_ASSUM(SUBST1_TAC o SYM) THEN
1399 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE_STRONG THEN
1400 ASM_REWRITE_TAC[CONVEX_SING]);;
1402 let EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE = prove
1404 (!x. x IN s ==> a dot x <= b) /\
1405 s INTER {x | a dot x = b} = {c}
1406 ==> {c} exposed_face_of s`,
1407 REPEAT STRIP_TAC THEN REWRITE_TAC[exposed_face_of] THEN CONJ_TAC THENL
1408 [REWRITE_TAC[FACE_OF_SING] THEN
1409 MATCH_MP_TAC EXTREME_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE;
1411 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN ASM SET_TAC[]);;
1413 let EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_GE = prove
1415 (!x. x IN s ==> a dot x >= b) /\
1416 s INTER {x | a dot x = b} = {c}
1417 ==> {c} exposed_face_of s`,
1418 REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN
1419 MP_TAC(ISPECL [`s:real^N->bool`; `--a:real^N`; `--b:real`; `c:real^N`]
1420 EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE) THEN
1421 ASM_REWRITE_TAC[DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2]);;
1423 let EXPOSED_POINT_OF_FURTHEST_POINT = prove
1425 b IN s /\ (!x. x IN s ==> dist(a,x) <= dist(a,b))
1426 ==> {b} exposed_face_of s`,
1427 REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN
1428 REWRITE_TAC[DIST_0; NORM_LE] THEN REPEAT STRIP_TAC THEN
1429 MATCH_MP_TAC EXPOSED_POINT_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
1430 MAP_EVERY EXISTS_TAC [`b:real^N`; `(b:real^N) dot b`] THEN CONJ_TAC THENL
1431 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1432 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
1434 MATCH_MP_TAC SUBSET_ANTISYM THEN
1435 ASM_REWRITE_TAC[IN_INTER; SING_SUBSET; IN_ELIM_THM] THEN
1436 REWRITE_TAC[SUBSET; IN_SING; IN_INTER; IN_ELIM_THM] THEN
1437 X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
1438 CONV_TAC SYM_CONV THEN ASM_REWRITE_TAC[VECTOR_EQ] THEN
1439 ASM_SIMP_TAC[GSYM REAL_LE_ANTISYM] THEN
1440 UNDISCH_TAC `(b:real^N) dot x = b dot b`] THEN
1441 MP_TAC(ISPEC `b - x:real^N` DOT_POS_LE) THEN
1442 REWRITE_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);;
1444 let COLLINEAR_EXTREME_POINTS = prove
1446 ==> FINITE {x:real^N | x extreme_point_of s} /\
1447 CARD {x | x extreme_point_of s} <= 2`,
1448 REWRITE_TAC[GSYM NOT_LT; TAUT `a /\ ~b <=> ~(a ==> b)`] THEN
1449 REWRITE_TAC[ARITH_RULE `2 < n <=> 3 <= n`] THEN REPEAT STRIP_TAC THEN
1450 FIRST_ASSUM(MP_TAC o MATCH_MP CHOOSE_SUBSET_STRONG) THEN
1451 CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN
1452 REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN REWRITE_TAC[NOT_EXISTS_THM] THEN
1454 [`t:real^N->bool`; `a:real^N`; `b:real^N`; `c:real^N`] THEN
1455 REPEAT STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
1457 `(a:real^N) extreme_point_of s /\
1458 b extreme_point_of s /\ c extreme_point_of s`
1459 STRIP_ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1460 SUBGOAL_THEN `(a:real^N) IN s /\ b IN s /\ c IN s` STRIP_ASSUME_TAC THENL
1461 [ASM_MESON_TAC[extreme_point_of]; ALL_TAC] THEN
1462 SUBGOAL_THEN `collinear {a:real^N,b,c}` MP_TAC THENL
1463 [MATCH_MP_TAC COLLINEAR_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN
1465 REWRITE_TAC[COLLINEAR_BETWEEN_CASES; BETWEEN_IN_SEGMENT] THEN
1466 ASM_SIMP_TAC[SEGMENT_CLOSED_OPEN; IN_INSERT; NOT_IN_EMPTY; IN_UNION] THEN
1467 ASM_MESON_TAC[extreme_point_of]]);;
1469 let EXTREME_POINT_OF_CONIC = prove
1471 conic s /\ x extreme_point_of s ==> x = vec 0`,
1472 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
1473 DISCH_THEN(MP_TAC o MATCH_MP FACE_OF_CONIC) THEN
1474 SIMP_TAC[conic; IN_SING; VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_ARITH
1475 `c % x:real^N = x <=> (c - &1) % x = vec 0`] THEN
1476 MESON_TAC[REAL_ARITH `&0 <= &0 /\ ~(&1 = &0)`]);;
1478 let EXTREME_POINT_OF_CONVEX_HULL_INSERT = prove
1480 FINITE s /\ ~(a IN convex hull s)
1481 ==> a extreme_point_of (convex hull (a INSERT s))`,
1483 ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_SIMP_TAC[HULL_INC] THEN
1484 STRIP_TAC THEN MP_TAC(ISPECL [`{a:real^N}`; `(a:real^N) INSERT s`]
1485 FACE_OF_CONVEX_HULLS) THEN
1486 ASM_REWRITE_TAC[FINITE_INSERT; AFFINE_HULL_SING; CONVEX_HULL_SING] THEN
1487 REWRITE_TAC[FACE_OF_SING] THEN DISCH_THEN MATCH_MP_TAC THEN
1488 ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> a INSERT s DIFF {a} = s`] THEN
1491 (* ------------------------------------------------------------------------- *)
1493 (* ------------------------------------------------------------------------- *)
1495 parse_as_infix("facet_of",(12, "right"));;
1497 let facet_of = new_definition
1498 `f facet_of s <=> f face_of s /\ ~(f = {}) /\ aff_dim f = aff_dim s - &1`;;
1500 let FACET_OF_EMPTY = prove
1501 (`!s. ~(s facet_of {})`,
1502 REWRITE_TAC[facet_of; FACE_OF_EMPTY] THEN CONV_TAC TAUT);;
1504 let FACET_OF_REFL = prove
1505 (`!s. ~(s facet_of s)`,
1506 REWRITE_TAC[facet_of; INT_ARITH `~(x:int = x - &1)`]);;
1508 let FACET_OF_IMP_FACE_OF = prove
1509 (`!f s. f facet_of s ==> f face_of s`,
1510 SIMP_TAC[facet_of]);;
1512 let FACET_OF_IMP_SUBSET = prove
1513 (`!f s. f facet_of s ==> f SUBSET s`,
1514 SIMP_TAC[FACET_OF_IMP_FACE_OF; FACE_OF_IMP_SUBSET]);;
1516 let FACET_OF_IMP_PROPER = prove
1517 (`!f s. f facet_of s ==> ~(f = {}) /\ ~(f = s)`,
1518 REWRITE_TAC[facet_of] THEN MESON_TAC[INT_ARITH `~(x - &1:int = x)`]);;
1520 let FACET_OF_TRANSLATION_EQ = prove
1522 (IMAGE (\x. a + x) f) facet_of (IMAGE (\x. a + x) s) <=> f facet_of s`,
1523 REWRITE_TAC[facet_of] THEN GEOM_TRANSLATE_TAC[]);;
1525 add_translation_invariants [FACET_OF_TRANSLATION_EQ];;
1527 let FACET_OF_LINEAR_IMAGE = prove
1528 (`!f:real^M->real^N c s.
1529 linear f /\ (!x y. f x = f y ==> x = y)
1530 ==> ((IMAGE f c) facet_of (IMAGE f s) <=> c facet_of s)`,
1531 REWRITE_TAC[facet_of] THEN GEOM_TRANSFORM_TAC[]);;
1533 add_linear_invariants [FACET_OF_LINEAR_IMAGE];;
1535 let HYPERPLANE_FACET_OF_HALFSPACE_LE = prove
1537 ~(a = vec 0) ==> {x | a dot x = b} facet_of {x | a dot x <= b}`,
1538 SIMP_TAC[facet_of; HYPERPLANE_FACE_OF_HALFSPACE_LE; HYPERPLANE_EQ_EMPTY;
1539 AFF_DIM_HYPERPLANE; AFF_DIM_HALFSPACE_LE]);;
1541 let HYPERPLANE_FACET_OF_HALFSPACE_GE = prove
1543 ~(a = vec 0) ==> {x | a dot x = b} facet_of {x | a dot x >= b}`,
1544 SIMP_TAC[facet_of; HYPERPLANE_FACE_OF_HALFSPACE_GE; HYPERPLANE_EQ_EMPTY;
1545 AFF_DIM_HYPERPLANE; AFF_DIM_HALFSPACE_GE]);;
1547 let FACET_OF_HALFSPACE_LE = prove
1549 f facet_of {x | a dot x <= b} <=>
1550 ~(a = vec 0) /\ f = {x | a dot x = b}`,
1552 EQ_TAC THEN ASM_SIMP_TAC[HYPERPLANE_FACET_OF_HALFSPACE_LE] THEN
1553 SIMP_TAC[AFF_DIM_HALFSPACE_LE; facet_of; FACE_OF_HALFSPACE_LE] THEN
1554 REWRITE_TAC[TAUT `(p \/ q) /\ ~p /\ r <=> (~p /\ q) /\ r`] THEN
1555 ASM_CASES_TAC `a:real^N = vec 0` THENL
1556 [ASM_REWRITE_TAC[DOT_LZERO; SET_RULE
1557 `{x | p} = if p then UNIV else {}`] THEN
1558 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[TAUT `~(~p /\ p)`]) THEN
1559 TRY ASM_REAL_ARITH_TAC THEN
1560 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
1561 ASM_REWRITE_TAC[AFF_DIM_UNIV] THEN TRY INT_ARITH_TAC THEN ASM SET_TAC[];
1562 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
1563 ASM_REWRITE_TAC[AFF_DIM_HALFSPACE_LE] THEN INT_ARITH_TAC]);;
1565 let FACET_OF_HALFSPACE_GE = prove
1567 f facet_of {x | a dot x >= b} <=>
1568 ~(a = vec 0) /\ f = {x | a dot x = b}`,
1570 MP_TAC(ISPECL [`f:real^N->bool`; `--a:real^N`; `--b:real`]
1571 FACET_OF_HALFSPACE_LE) THEN
1572 SIMP_TAC[DOT_LNEG; REAL_LE_NEG2; REAL_EQ_NEG2; VECTOR_NEG_EQ_0; real_ge]);;
1574 (* ------------------------------------------------------------------------- *)
1575 (* Edges, i.e. faces of affine dimension 1. *)
1576 (* ------------------------------------------------------------------------- *)
1578 parse_as_infix("edge_of",(12, "right"));;
1580 let edge_of = new_definition
1581 `e edge_of s <=> e face_of s /\ aff_dim e = &1`;;
1583 let EDGE_OF_TRANSLATION_EQ = prove
1585 (IMAGE (\x. a + x) f) edge_of (IMAGE (\x. a + x) s) <=> f edge_of s`,
1586 REWRITE_TAC[edge_of] THEN GEOM_TRANSLATE_TAC[]);;
1588 add_translation_invariants [EDGE_OF_TRANSLATION_EQ];;
1590 let EDGE_OF_LINEAR_IMAGE = prove
1591 (`!f:real^M->real^N c s.
1592 linear f /\ (!x y. f x = f y ==> x = y)
1593 ==> ((IMAGE f c) edge_of (IMAGE f s) <=> c edge_of s)`,
1594 REWRITE_TAC[edge_of] THEN GEOM_TRANSFORM_TAC[]);;
1596 add_linear_invariants [EDGE_OF_LINEAR_IMAGE];;
1598 let EDGE_OF_IMP_SUBSET = prove
1599 (`!s t. s edge_of t ==> s SUBSET t`,
1600 SIMP_TAC[edge_of; face_of]);;
1602 (* ------------------------------------------------------------------------- *)
1603 (* Existence of extreme points. *)
1604 (* ------------------------------------------------------------------------- *)
1606 let DIFFERENT_NORM_3_COLLINEAR_POINTS = prove
1608 ~(x IN segment(a,b) /\ norm(a) = norm(b) /\ norm(x) = norm(b))`,
1609 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN
1610 ASM_SIMP_TAC[SEGMENT_REFL; NOT_IN_EMPTY; OPEN_SEGMENT_ALT] THEN
1611 REWRITE_TAC[IN_ELIM_THM] THEN DISCH_THEN
1612 (CONJUNCTS_THEN2 (X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) MP_TAC) THEN
1613 ASM_REWRITE_TAC[NORM_EQ] THEN REWRITE_TAC[VECTOR_ARITH
1614 `(x + y:real^N) dot (x + y) = x dot x + &2 * x dot y + y dot y`] THEN
1615 REWRITE_TAC[DOT_LMUL; DOT_RMUL] THEN
1616 DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) MP_TAC) THEN
1617 UNDISCH_TAC `~(a:real^N = b)` THEN
1618 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM VECTOR_SUB_EQ] THEN
1619 REWRITE_TAC[GSYM DOT_EQ_0; VECTOR_ARITH
1620 `(a - b:real^N) dot (a - b) = a dot a + b dot b - &2 * a dot b`] THEN
1621 ASM_REWRITE_TAC[REAL_RING `a + a - &2 * ab = &0 <=> ab = a`] THEN
1623 `(&1 - u) * (&1 - u) * a + &2 * (&1 - u) * u * x + u * u * a = a <=>
1624 x = a \/ u = &0 \/ u = &1`] THEN
1625 ASM_REAL_ARITH_TAC);;
1627 let EXTREME_POINT_EXISTS_CONVEX = prove
1629 compact s /\ convex s /\ ~(s = {}) ==> ?x. x extreme_point_of s`,
1630 REPEAT STRIP_TAC THEN
1631 MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`] DISTANCE_ATTAINS_SUP) THEN
1632 ASM_REWRITE_TAC[DIST_0; extreme_point_of] THEN
1633 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN
1634 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1635 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
1636 REPEAT STRIP_TAC THEN
1637 MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `x:real^N`]
1638 DIFFERENT_NORM_3_COLLINEAR_POINTS) THEN
1639 ASM_REWRITE_TAC[] THEN
1640 MATCH_MP_TAC(REAL_ARITH
1641 `a <= x /\ b <= x /\ (a < x ==> x < x) /\ (b < x ==> x < x)
1642 ==> a = b /\ x = b`) THEN
1644 UNDISCH_TAC `(x:real^N) IN segment(a,b)` THEN
1645 ASM_CASES_TAC `a:real^N = b` THEN
1646 ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN
1647 ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM] THEN
1648 DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN
1649 CONJ_TAC THEN DISCH_TAC THEN
1650 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
1651 MATCH_MP_TAC NORM_TRIANGLE_LT THEN REWRITE_TAC[NORM_MUL] THEN
1652 ASM_SIMP_TAC[REAL_ARITH
1653 `&0 < u /\ u < &1 ==> abs u = u /\ abs(&1 - u) = &1 - u`] THEN
1654 SUBST1_TAC(REAL_RING `norm(x:real^N) = (&1 - u) * norm x + u * norm x`) THENL
1655 [MATCH_MP_TAC REAL_LTE_ADD2; MATCH_MP_TAC REAL_LET_ADD2] THEN
1656 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LMUL_EQ; REAL_SUB_LT]);;
1658 (* ------------------------------------------------------------------------- *)
1659 (* Krein-Milman, the weaker form as in more general spaces first. *)
1660 (* ------------------------------------------------------------------------- *)
1662 let KREIN_MILMAN = prove
1664 convex s /\ compact s
1665 ==> s = closure(convex hull {x | x extreme_point_of s})`,
1667 ASM_CASES_TAC `s:real^N->bool = {}` THENL
1668 [ASM_REWRITE_TAC[extreme_point_of; NOT_IN_EMPTY; EMPTY_GSPEC] THEN
1669 REWRITE_TAC[CONVEX_HULL_EMPTY; CLOSURE_EMPTY];
1671 STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
1673 MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN
1674 MATCH_MP_TAC HULL_MINIMAL THEN
1675 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; extreme_point_of]] THEN
1676 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
1677 X_GEN_TAC `u:real^N` THEN DISCH_TAC THEN
1678 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
1679 MP_TAC(ISPECL [`closure(convex hull {x:real^N | x extreme_point_of s})`;
1680 `u:real^N`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN
1681 ASM_SIMP_TAC[CONVEX_CLOSURE; CLOSED_CLOSURE; CONVEX_CONVEX_HULL] THEN
1682 REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN
1683 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`] THEN REPEAT STRIP_TAC THEN
1684 MP_TAC(ISPECL [`\x:real^N. a dot x`; `s:real^N->bool`]
1685 CONTINUOUS_ATTAINS_INF) THEN
1686 ASM_REWRITE_TAC[CONTINUOUS_ON_LIFT_DOT] THEN
1687 DISCH_THEN(X_CHOOSE_THEN `m:real^N` STRIP_ASSUME_TAC) THEN
1688 ABBREV_TAC `t = {x:real^N | x IN s /\ a dot x = a dot m}` THEN
1689 SUBGOAL_THEN `?x:real^N. x extreme_point_of t` (X_CHOOSE_TAC `v:real^N`)
1691 [MATCH_MP_TAC EXTREME_POINT_EXISTS_CONVEX THEN
1692 EXPAND_TAC "t" THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
1693 REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
1694 ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE; COMPACT_INTER_CLOSED;
1695 CLOSED_HYPERPLANE] THEN
1698 SUBGOAL_THEN `(v:real^N) extreme_point_of s` ASSUME_TAC THENL
1699 [REWRITE_TAC[GSYM FACE_OF_SING] THEN MATCH_MP_TAC FACE_OF_TRANS THEN
1700 EXISTS_TAC `t:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_SING] THEN
1702 REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
1703 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN
1704 ASM_SIMP_TAC[real_ge];
1705 SUBGOAL_THEN `(a:real^N) dot v > b` MP_TAC THENL
1706 [FIRST_X_ASSUM MATCH_MP_TAC THEN
1707 MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN
1708 MATCH_MP_TAC HULL_INC THEN ASM_REWRITE_TAC[IN_ELIM_THM];
1710 REWRITE_TAC[real_gt; REAL_NOT_LT] THEN
1711 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(a:real^N) dot u` THEN
1712 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
1713 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(a:real^N) dot m` THEN
1715 UNDISCH_TAC `(v:real^N) extreme_point_of t` THEN EXPAND_TAC "t" THEN
1716 SIMP_TAC[extreme_point_of; IN_ELIM_THM; REAL_LE_REFL]]);;
1718 (* ------------------------------------------------------------------------- *)
1719 (* Now the sharper form. *)
1720 (* ------------------------------------------------------------------------- *)
1722 let KREIN_MILMAN_MINKOWSKI = prove
1724 convex s /\ compact s
1725 ==> s = convex hull {x | x extreme_point_of s}`,
1728 convex s /\ compact s /\ (vec 0) IN s
1729 ==> (vec 0) IN convex hull {x | x extreme_point_of s}`
1731 [GEN_TAC THEN WF_INDUCT_TAC `dim(s:real^N->bool)` THEN STRIP_TAC THEN
1732 ASM_CASES_TAC `(vec 0:real^N) IN relative_interior s` THENL
1733 [MP_TAC(ISPEC `s:real^N->bool` KREIN_MILMAN) THEN
1734 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1735 UNDISCH_TAC `(vec 0:real^N) IN relative_interior s` THEN
1736 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC
1737 (LAND_CONV o RAND_CONV o RAND_CONV) [th]) THEN
1738 SIMP_TAC[CONVEX_RELATIVE_INTERIOR_CLOSURE; CONVEX_CONVEX_HULL] THEN
1739 MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET];
1741 SUBGOAL_THEN `~(relative_interior(s:real^N->bool) = {})` ASSUME_TAC THENL
1742 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY] THEN ASM SET_TAC[];
1744 MP_TAC(ISPECL [`s:real^N->bool`; `vec 0:real^N`]
1745 SUPPORTING_HYPERPLANE_RELATIVE_BOUNDARY) THEN
1746 ASM_REWRITE_TAC[DOT_RZERO] THEN
1747 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
1748 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `&0`]
1749 FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE) THEN
1750 ASM_REWRITE_TAC[real_ge] THEN DISCH_TAC THEN
1752 `(vec 0:real^N) IN convex hull
1753 {x | x extreme_point_of (s INTER {x | a dot x = &0})}`
1756 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> x IN s ==> x IN t`) THEN
1757 MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET] THEN
1758 GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM; GSYM FACE_OF_SING] THEN
1759 ASM_MESON_TAC[FACE_OF_TRANS]] THEN
1760 RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP]) THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
1761 ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE; COMPACT_INTER_CLOSED;
1762 CLOSED_HYPERPLANE; IN_INTER; IN_ELIM_THM; DOT_RZERO] THEN
1763 REWRITE_TAC[GSYM NOT_LE] THEN DISCH_TAC THEN
1765 [`s INTER {x:real^N | a dot x = &0}`; `s:real^N->bool`]
1767 ASM_REWRITE_TAC[INTER_SUBSET; EXTENSION; NOT_FORALL_THM] THEN
1768 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
1769 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN
1770 MATCH_MP_TAC(TAUT `b /\ ~a ==> ~(a <=> b)`) THEN CONJ_TAC THENL
1771 [ASM_MESON_TAC[SUBSET; SPAN_INC; RELATIVE_INTERIOR_SUBSET]; ALL_TAC] THEN
1773 `!x:real^N. x IN span (s INTER {x | a dot x = &0}) ==> a dot x = &0`
1774 (fun th -> ASM_MESON_TAC[th; REAL_LT_REFL]) THEN
1775 MATCH_MP_TAC SPAN_INDUCT THEN SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN
1776 REWRITE_TAC[subspace; DOT_RZERO; DOT_RADD; DOT_RMUL; IN_ELIM_THM] THEN
1779 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
1780 [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
1781 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\x:real^N. --a + x) s`) THEN
1782 ASM_SIMP_TAC[CONVEX_TRANSLATION_EQ; COMPACT_TRANSLATION_EQ] THEN
1783 REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN
1784 ASM_REWRITE_TAC[UNWIND_THM2] THEN
1785 REWRITE_TAC[EXTREME_POINTS_OF_TRANSLATION; CONVEX_HULL_TRANSLATION] THEN
1786 REWRITE_TAC[IN_IMAGE; VECTOR_ARITH `vec 0:real^N = --a + x <=> x = a`] THEN
1787 REWRITE_TAC[UNWIND_THM2];
1788 MATCH_MP_TAC HULL_MINIMAL THEN
1789 ASM_SIMP_TAC[SUBSET; extreme_point_of; IN_ELIM_THM]]);;
1791 (* ------------------------------------------------------------------------- *)
1792 (* Applying it to convex hulls of explicitly indicated finite sets. *)
1793 (* ------------------------------------------------------------------------- *)
1795 let KREIN_MILMAN_POLYTOPE = prove
1798 convex hull {x | x extreme_point_of (convex hull s)}`,
1799 SIMP_TAC[KREIN_MILMAN_MINKOWSKI; CONVEX_CONVEX_HULL;
1800 COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT]);;
1802 let EXTREME_POINTS_OF_CONVEX_HULL_EQ = prove
1805 (!t. t PSUBSET s ==> ~(convex hull t = convex hull s))
1806 ==> {x | x extreme_point_of (convex hull s)} = s`,
1807 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC
1808 `{x:real^N | x extreme_point_of (convex hull s)}`) THEN
1809 MATCH_MP_TAC(SET_RULE
1810 `P /\ t SUBSET s ==> (t PSUBSET s ==> ~P) ==> t = s`) THEN
1811 REWRITE_TAC[EXTREME_POINTS_OF_CONVEX_HULL] THEN
1812 CONV_TAC SYM_CONV THEN MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
1813 ASM_SIMP_TAC[CONVEX_CONVEX_HULL; COMPACT_CONVEX_HULL]);;
1815 let EXTREME_POINT_OF_CONVEX_HULL_EQ = prove
1818 (!t. t PSUBSET s ==> ~(convex hull t = convex hull s))
1819 ==> (x extreme_point_of (convex hull s) <=> x IN s)`,
1821 DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINTS_OF_CONVEX_HULL_EQ) THEN
1824 let EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT = prove
1827 (!a. a IN s ==> ~(a IN convex hull (s DELETE a)))
1828 ==> (x extreme_point_of (convex hull s) <=> x IN s)`,
1829 REPEAT STRIP_TAC THEN MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_EQ THEN
1830 ASM_REWRITE_TAC[PSUBSET_MEMBER] THEN X_GEN_TAC `t:real^N->bool` THEN
1831 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `a:real^N`)) THEN
1832 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N`) THEN
1833 ASM_REWRITE_TAC[] THEN
1834 SUBGOAL_THEN `s SUBSET convex hull (s DELETE (a:real^N))` MP_TAC THENL
1835 [ALL_TAC; ASM SET_TAC[]] THEN
1836 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `convex hull t:real^N->bool` THEN
1838 [ASM_REWRITE_TAC[HULL_SUBSET];
1839 MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]]);;
1841 let EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT = prove
1842 (`!s x. ~affine_dependent s
1843 ==> (x extreme_point_of (convex hull s) <=> x IN s)`,
1844 REPEAT STRIP_TAC THEN
1845 MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_CONVEX_INDEPENDENT THEN
1846 ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; FINITE_IMP_COMPACT] THEN
1847 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN
1848 MESON_TAC[SUBSET; CONVEX_HULL_SUBSET_AFFINE_HULL]);;
1850 let EXTREME_POINT_OF_CONVEX_HULL_2 = prove
1851 (`!a b x. x extreme_point_of (convex hull {a,b}) <=> x = a \/ x = b`,
1852 REWRITE_TAC[SET_RULE `x = a \/ x = b <=> x IN {a,b}`] THEN
1853 SIMP_TAC[EXTREME_POINT_OF_CONVEX_HULL_AFFINE_INDEPENDENT;
1854 AFFINE_INDEPENDENT_2]);;
1856 let EXTREME_POINT_OF_SEGMENT = prove
1857 (`!a b x:real^N. x extreme_point_of segment[a,b] <=> x = a \/ x = b`,
1858 REWRITE_TAC[SEGMENT_CONVEX_HULL; EXTREME_POINT_OF_CONVEX_HULL_2]);;
1860 let FACE_OF_CONVEX_HULL_SUBSET = prove
1861 (`!s t:real^N->bool.
1862 compact s /\ t face_of (convex hull s)
1863 ==> ?s'. s' SUBSET s /\ t = convex hull s'`,
1864 REPEAT STRIP_TAC THEN EXISTS_TAC `{x:real^N | x extreme_point_of t}` THEN
1865 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL
1866 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1867 MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL THEN
1868 ASM_MESON_TAC[FACE_OF_SING; FACE_OF_TRANS];
1869 MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
1870 ASM_MESON_TAC[FACE_OF_IMP_CONVEX; FACE_OF_IMP_COMPACT;
1871 COMPACT_CONVEX_HULL; CONVEX_CONVEX_HULL]]);;
1873 let FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT = prove
1874 (`!s t:real^N->bool.
1876 ==> (t face_of (convex hull s) <=>
1877 ?c. c SUBSET s /\ t = convex hull c)`,
1878 REPEAT STRIP_TAC THEN EQ_TAC THENL
1879 [ASM_MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE; FINITE_IMP_COMPACT;
1880 FACE_OF_CONVEX_HULL_SUBSET];
1881 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1882 MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN
1883 ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN
1884 MATCH_MP_TAC(SET_RULE `
1885 !t. u SUBSET t /\ DISJOINT s t ==> DISJOINT s u`) THEN
1886 EXISTS_TAC `affine hull (s DIFF c:real^N->bool)` THEN
1887 REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN
1888 MATCH_MP_TAC DISJOINT_AFFINE_HULL THEN
1889 EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]]);;
1891 let FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT = prove
1892 (`!s t:real^N->bool.
1894 ==> (t facet_of (convex hull s) <=>
1895 ~(t = {}) /\ ?u. u IN s /\ t = convex hull (s DELETE u))`,
1896 REPEAT STRIP_TAC THEN
1897 ASM_SIMP_TAC[facet_of; FACE_OF_CONVEX_HULL_AFFINE_INDEPENDENT] THEN
1898 REWRITE_TAC[AFF_DIM_CONVEX_HULL] THEN EQ_TAC THENL
1899 [DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
1900 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` MP_TAC) THEN
1901 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN
1903 `aff_dim(convex hull c:real^N->bool) = aff_dim(s:real^N->bool) - &1` THEN
1904 SUBGOAL_THEN `~affine_dependent(c:real^N->bool)` ASSUME_TAC THENL
1905 [ASM_MESON_TAC[AFFINE_INDEPENDENT_SUBSET];
1906 ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT; AFF_DIM_CONVEX_HULL]] THEN
1907 REWRITE_TAC[INT_ARITH `x - &1:int = y - &1 - &1 <=> y = x + &1`] THEN
1908 REWRITE_TAC[INT_OF_NUM_ADD; INT_OF_NUM_EQ] THEN DISCH_TAC THEN
1909 SUBGOAL_THEN `(s DIFF c:real^N->bool) HAS_SIZE 1` MP_TAC THENL
1910 [ASM_SIMP_TAC[HAS_SIZE; FINITE_DIFF; CARD_DIFF;
1911 AFFINE_INDEPENDENT_IMP_FINITE] THEN ARITH_TAC;
1912 CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN
1913 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N` THEN
1914 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
1915 `s DIFF t = {a} ==> t SUBSET s ==> s = a INSERT t`)) THEN
1916 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN
1917 UNDISCH_TAC `CARD((u:real^N) INSERT c) = CARD c + 1` THEN
1918 ASM_SIMP_TAC[CARD_CLAUSES; AFFINE_INDEPENDENT_IMP_FINITE] THEN
1919 COND_CASES_TAC THENL [ARITH_TAC; DISCH_THEN(K ALL_TAC)] THEN
1920 CONJ_TAC THENL [ALL_TAC; AP_TERM_TAC] THEN ASM SET_TAC[]];
1921 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
1922 DISCH_THEN(X_CHOOSE_THEN `u:real^N` MP_TAC) THEN
1923 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN
1924 CONJ_TAC THENL [MESON_TAC[DELETE_SUBSET]; ALL_TAC] THEN
1925 ASM_SIMP_TAC[AFF_DIM_CONVEX_HULL] THEN
1926 SUBGOAL_THEN `~affine_dependent(s DELETE (u:real^N))` ASSUME_TAC THENL
1927 [ASM_MESON_TAC[AFFINE_INDEPENDENT_SUBSET; DELETE_SUBSET];
1928 ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT]] THEN
1929 REWRITE_TAC[INT_ARITH `x - &1:int = y - &1 - &1 <=> y = x + &1`] THEN
1930 REWRITE_TAC[INT_OF_NUM_ADD; INT_OF_NUM_EQ] THEN
1931 ASM_SIMP_TAC[CARD_DELETE; AFFINE_INDEPENDENT_IMP_FINITE] THEN
1932 MATCH_MP_TAC(ARITH_RULE `~(s = 0) ==> s = s - 1 + 1`) THEN
1933 ASM_SIMP_TAC[CARD_EQ_0; AFFINE_INDEPENDENT_IMP_FINITE] THEN
1936 let FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT = prove
1937 (`!s t:real^N->bool.
1939 ==> (t facet_of (convex hull s) <=>
1940 2 <= CARD s /\ ?u. u IN s /\ t = convex hull (s DELETE u))`,
1941 REPEAT STRIP_TAC THEN
1942 ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT] THEN
1943 REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN AP_TERM_TAC THEN
1944 GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
1945 X_GEN_TAC `u:real^N` THEN
1946 ASM_CASES_TAC `t = convex hull (s DELETE (u:real^N))` THEN
1947 ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN
1948 ASM_CASES_TAC `(u:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
1949 SUBGOAL_THEN `CARD s = 1 + CARD(s DELETE (u:real^N))` SUBST1_TAC THENL
1950 [ASM_SIMP_TAC[CARD_DELETE; AFFINE_INDEPENDENT_IMP_FINITE] THEN
1951 MATCH_MP_TAC(ARITH_RULE `~(s = 0) ==> s = 1 + s - 1`) THEN
1952 ASM_SIMP_TAC[CARD_EQ_0; AFFINE_INDEPENDENT_IMP_FINITE] THEN
1954 REWRITE_TAC[ARITH_RULE `2 <= 1 + x <=> ~(x = 0)`] THEN
1955 ASM_SIMP_TAC[CARD_EQ_0; AFFINE_INDEPENDENT_IMP_FINITE; FINITE_DELETE]]);;
1957 let SEGMENT_FACE_OF = prove
1959 segment[a,b] face_of s ==> a extreme_point_of s /\ b extreme_point_of s`,
1960 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
1961 MATCH_MP_TAC FACE_OF_TRANS THEN EXISTS_TAC `segment[a:real^N,b]` THEN
1962 ASM_REWRITE_TAC[] THEN REWRITE_TAC[FACE_OF_SING; EXTREME_POINT_OF_SEGMENT]);;
1964 let SEGMENT_EDGE_OF = prove
1966 segment[a,b] edge_of s
1967 ==> ~(a = b) /\ a extreme_point_of s /\ b extreme_point_of s`,
1968 REPEAT GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL
1969 [ALL_TAC; ASM_MESON_TAC[edge_of; SEGMENT_FACE_OF]] THEN
1970 POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
1971 SIMP_TAC[SEGMENT_REFL; edge_of; AFF_DIM_SING] THEN INT_ARITH_TAC);;
1973 let COMPACT_CONVEX_COLLINEAR_SEGMENT = prove
1975 ~(s = {}) /\ compact s /\ convex s /\ collinear s
1976 ==> ?a b. s = segment[a,b]`,
1977 REPEAT STRIP_TAC THEN
1978 MP_TAC(ISPEC `s:real^N->bool` KREIN_MILMAN_MINKOWSKI) THEN
1979 FIRST_ASSUM(MP_TAC o MATCH_MP COLLINEAR_EXTREME_POINTS) THEN
1980 REWRITE_TAC[ARITH_RULE `n <= 2 <=> n = 0 \/ n = 1 \/ n = 2`] THEN
1981 REWRITE_TAC[LEFT_OR_DISTRIB; GSYM HAS_SIZE] THEN
1982 CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN
1983 STRIP_TAC THEN ASM_REWRITE_TAC[CONVEX_HULL_EMPTY; SEGMENT_CONVEX_HULL] THEN
1984 DISCH_THEN SUBST1_TAC THEN MESON_TAC[SET_RULE `{a} = {a,a}`]);;
1986 let KREIN_MILMAN_RELATIVE_FRONTIER = prove
1988 convex s /\ compact s /\ ~(?a. s = {a})
1989 ==> s = convex hull (s DIFF relative_interior s)`,
1990 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
1991 [MATCH_MP_TAC SUBSET_TRANS THEN
1992 EXISTS_TAC `convex hull {x:real^N | x extreme_point_of s}` THEN
1994 [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; SUBSET_REFL];
1995 MATCH_MP_TAC HULL_MONO THEN SIMP_TAC[SUBSET; IN_ELIM_THM; IN_DIFF] THEN
1996 ASM_MESON_TAC[EXTREME_POINT_NOT_IN_RELATIVE_INTERIOR; extreme_point_of]];
1997 MATCH_MP_TAC SUBSET_TRANS THEN
1998 EXISTS_TAC `convex hull s:real^N->bool` THEN CONJ_TAC THENL
1999 [MATCH_MP_TAC HULL_MONO THEN SET_TAC[];
2000 ASM_SIMP_TAC[HULL_P; SUBSET_REFL]]]);;
2002 let KREIN_MILMAN_FRONTIER = prove
2004 convex s /\ compact s
2005 ==> s = convex hull (frontier s)`,
2006 REPEAT STRIP_TAC THEN
2007 ASM_SIMP_TAC[frontier; COMPACT_IMP_CLOSED; CLOSURE_CLOSED] THEN
2008 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
2009 [MATCH_MP_TAC SUBSET_TRANS THEN
2010 EXISTS_TAC `convex hull {x:real^N | x extreme_point_of s}` THEN
2012 [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; SUBSET_REFL];
2013 MATCH_MP_TAC HULL_MONO THEN SIMP_TAC[SUBSET; IN_ELIM_THM; IN_DIFF] THEN
2014 ASM_MESON_TAC[EXTREME_POINT_NOT_IN_INTERIOR; extreme_point_of]];
2015 MATCH_MP_TAC SUBSET_TRANS THEN
2016 EXISTS_TAC `convex hull s:real^N->bool` THEN CONJ_TAC THENL
2017 [MATCH_MP_TAC HULL_MONO THEN SET_TAC[];
2018 ASM_SIMP_TAC[HULL_P; SUBSET_REFL]]]);;
2020 let EXTREME_POINT_OF_CONVEX_HULL_INSERT_EQ = prove
2022 FINITE s /\ ~(a IN affine hull s)
2023 ==> (x extreme_point_of (convex hull (a INSERT s)) <=>
2024 x = a \/ x extreme_point_of (convex hull s))`,
2025 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM AFFINE_HULL_CONVEX_HULL] THEN
2026 STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
2027 ONCE_REWRITE_TAC[HULL_UNION_RIGHT] THEN
2028 MP_TAC(ISPEC `convex hull s:real^N->bool` KREIN_MILMAN_MINKOWSKI) THEN
2030 [ASM_SIMP_TAC[CONVEX_CONVEX_HULL; COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT];
2032 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] FINITE_SUBSET)) THEN
2033 DISCH_THEN(MP_TAC o SPEC
2034 `{x:real^N | x extreme_point_of convex hull s}`) THEN
2035 REWRITE_TAC[EXTREME_POINTS_OF_CONVEX_HULL] THEN
2036 ABBREV_TAC `v = {x:real^N | x extreme_point_of (convex hull s)}` THEN
2037 DISCH_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN
2038 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV)
2039 [AFFINE_HULL_CONVEX_HULL]) THEN
2040 ASM_CASES_TAC `(a:real^N) IN v` THEN ASM_SIMP_TAC[HULL_INC] THEN
2041 STRIP_TAC THEN REWRITE_TAC[GSYM HULL_UNION_RIGHT] THEN
2042 REWRITE_TAC[SET_RULE `{a} UNION s = a INSERT s`] THEN EQ_TAC THENL
2043 [DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINT_OF_CONVEX_HULL) THEN
2046 [ASM_REWRITE_TAC[] THEN
2047 MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_INSERT THEN
2048 ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET];
2049 REWRITE_TAC[GSYM FACE_OF_SING] THEN
2050 MATCH_MP_TAC FACE_OF_TRANS THEN
2051 EXISTS_TAC `convex hull v:real^N->bool` THEN
2052 ASM_REWRITE_TAC[FACE_OF_SING] THEN
2053 MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN
2054 ASM_SIMP_TAC[FINITE_INSERT; AFFINE_HULL_SING; CONVEX_HULL_SING;
2055 SET_RULE `~(a IN s) ==> a INSERT s DIFF s = {a}`] THEN
2058 let FACE_OF_CONVEX_HULL_INSERT_EQ = prove
2060 FINITE s /\ ~(a IN affine hull s)
2061 ==> (f face_of (convex hull (a INSERT s)) <=>
2062 f face_of (convex hull s) \/
2063 ?f'. f' face_of (convex hull s) /\
2064 f = convex hull (a INSERT f'))`,
2066 (`!a b c p:real^N u v w x.
2067 x % p = u % a + v % b + w % c
2068 ==> !s. u + v + w = x /\ ~(x = &0) /\ affine s /\
2069 a IN s /\ b IN s /\ c IN s
2071 REPEAT STRIP_TAC THEN
2072 FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv x):real^N->real^N`) THEN
2073 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID] THEN
2074 DISCH_THEN SUBST1_TAC THEN
2075 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
2076 MATCH_MP_TAC(SET_RULE `!t. x IN t /\ t SUBSET s ==> x IN s`) THEN
2077 EXISTS_TAC `affine hull {a:real^N,b,c}` THEN
2078 ASM_SIMP_TAC[HULL_MINIMAL; INSERT_SUBSET; EMPTY_SUBSET] THEN
2079 REWRITE_TAC[AFFINE_HULL_3; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC
2080 [`inv x * u:real`; `inv x * v:real`; `inv x * w:real`] THEN
2081 REWRITE_TAC[] THEN UNDISCH_TAC `u + v + w:real = x` THEN
2082 UNDISCH_TAC `~(x = &0)` THEN CONV_TAC REAL_FIELD) in
2083 REPEAT STRIP_TAC THEN EQ_TAC THENL
2084 [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
2085 FACE_OF_CONVEX_HULL_SUBSET)) THEN
2086 ASM_SIMP_TAC[COMPACT_INSERT; FINITE_IMP_COMPACT] THEN
2087 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
2088 FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_CASES_TAC `(a:real^N) IN t` THENL
2090 DISJ1_TAC THEN MATCH_MP_TAC FACE_OF_SUBSET THEN
2091 EXISTS_TAC `convex hull ((a:real^N) INSERT s)` THEN
2092 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC HULL_MONO THEN
2095 EXISTS_TAC `(convex hull t) INTER (convex hull s):real^N->bool` THEN
2097 [MATCH_MP_TAC FACE_OF_SUBSET THEN
2098 EXISTS_TAC `convex hull ((a:real^N) INSERT s)` THEN
2099 SIMP_TAC[INTER_SUBSET; HULL_MONO; SET_RULE `s SUBSET (a INSERT s)`] THEN
2100 MATCH_MP_TAC FACE_OF_INTER THEN ASM_REWRITE_TAC[] THEN
2101 MATCH_MP_TAC FACE_OF_CONVEX_HULL_INSERT THEN
2102 ASM_REWRITE_TAC[FACE_OF_REFL_EQ; CONVEX_CONVEX_HULL];
2103 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN
2104 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_CONVEX_HULL] THEN
2105 ASM_SIMP_TAC[INSERT_SUBSET; HULL_INC; INTER_SUBSET] THEN
2106 REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_INC THEN
2107 ASM_CASES_TAC `x:real^N = a` THEN ASM_REWRITE_TAC[IN_INSERT] THEN
2108 REWRITE_TAC[IN_INTER] THEN CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN
2111 DISCH_THEN(DISJ_CASES_THEN ASSUME_TAC) THENL
2112 [MATCH_MP_TAC FACE_OF_CONVEX_HULL_INSERT THEN ASM_REWRITE_TAC[];
2113 FIRST_X_ASSUM(X_CHOOSE_THEN `f':real^N->bool` MP_TAC)] THEN
2114 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC) THEN
2115 SPEC_TAC(`f':real^N->bool`,`f:real^N->bool`) THEN REPEAT STRIP_TAC THEN
2116 ASM_CASES_TAC `s:real^N->bool = {}` THENL
2117 [UNDISCH_TAC `(f:real^N->bool) face_of convex hull s` THEN
2118 ASM_SIMP_TAC[FACE_OF_EMPTY; CONVEX_HULL_EMPTY; FACE_OF_REFL_EQ] THEN
2119 REWRITE_TAC[CONVEX_CONVEX_HULL];
2121 ASM_CASES_TAC `f:real^N->bool = {}` THENL
2122 [ASM_REWRITE_TAC[CONVEX_HULL_SING; FACE_OF_SING] THEN
2123 MATCH_MP_TAC EXTREME_POINT_OF_CONVEX_HULL_INSERT THEN
2124 ASM_REWRITE_TAC[] THEN
2125 ASM_MESON_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL; SUBSET];
2127 REWRITE_TAC[face_of; CONVEX_CONVEX_HULL] THEN CONJ_TAC THENL
2128 [MATCH_MP_TAC HULL_MINIMAL THEN
2129 SIMP_TAC[INSERT_SUBSET; HULL_INC; IN_INSERT; CONVEX_CONVEX_HULL] THEN
2130 MATCH_MP_TAC SUBSET_TRANS THEN
2131 EXISTS_TAC `convex hull s:real^N->bool` THEN
2132 ASM_SIMP_TAC[HULL_MONO; SET_RULE `s SUBSET (a INSERT s)`] THEN
2133 ASM_MESON_TAC[FACE_OF_IMP_SUBSET];
2135 ASM_REWRITE_TAC[CONVEX_HULL_INSERT_ALT] THEN
2136 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
2137 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
2138 X_GEN_TAC `ub:real` THEN STRIP_TAC THEN
2139 X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
2140 X_GEN_TAC `uc:real` THEN STRIP_TAC THEN
2141 X_GEN_TAC `c:real^N` THEN STRIP_TAC THEN
2142 X_GEN_TAC `ux:real` THEN STRIP_TAC THEN
2143 X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
2144 FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [face_of]) THEN
2145 SUBGOAL_THEN `convex hull f:real^N->bool = f` SUBST_ALL_TAC THENL
2146 [ASM_MESON_TAC[CONVEX_HULL_EQ]; ALL_TAC] THEN
2147 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN
2148 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `v:real` MP_TAC)) THEN
2149 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
2150 REWRITE_TAC[VECTOR_ARITH
2151 `(&1 - ux) % a + ux % x:real^N =
2152 (&1 - v) % ((&1 - ub) % a + ub % b) + v % ((&1 - uc) % a + uc % c) <=>
2153 ((&1 - ux) - ((&1 - v) * (&1 - ub) + v * (&1 - uc))) % a +
2154 (ux % x - (((&1 - v) * ub) % b + (v * uc) % c)) = vec 0`] THEN
2155 ASM_CASES_TAC `&1 - ux - ((&1 - v) * (&1 - ub) + v * (&1 - uc)) = &0` THENL
2156 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN
2157 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_RING
2158 `(&1 - ux) - ((&1 - v) * (&1 - ub) + v * (&1 - uc)) = &0
2159 ==> (&1 - v) * ub + v * uc = ux`)) THEN
2160 ASM_CASES_TAC `uc = &0` THENL
2161 [UNDISCH_THEN `uc = &0` SUBST_ALL_TAC THEN
2162 FIRST_X_ASSUM(SUBST_ALL_TAC o MATCH_MP (REAL_ARITH
2163 `a + v * &0 = b ==> b = a`)) THEN
2164 REWRITE_TAC[REAL_MUL_RZERO; VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN
2165 REWRITE_TAC[VECTOR_SUB_EQ; VECTOR_MUL_LCANCEL; REAL_ENTIRE] THEN
2167 [ASM_REAL_ARITH_TAC;
2168 ASM_MESON_TAC[VECTOR_MUL_LZERO];
2169 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
2170 REWRITE_TAC[IN_ELIM_THM] THEN
2171 MAP_EVERY EXISTS_TAC [`&0`; `x:real^N`] THEN
2172 ASM_REWRITE_TAC[] THEN CONV_TAC VECTOR_ARITH];
2174 ASM_CASES_TAC `ub = &0` THENL
2175 [UNDISCH_THEN `ub = &0` SUBST_ALL_TAC THEN
2176 FIRST_X_ASSUM(SUBST_ALL_TAC o MATCH_MP (REAL_ARITH
2177 `v * &0 + a = b ==> b = a`)) THEN
2178 REWRITE_TAC[REAL_MUL_RZERO; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN
2179 REWRITE_TAC[VECTOR_SUB_EQ; VECTOR_MUL_LCANCEL; REAL_ENTIRE] THEN
2181 [ASM_REAL_ARITH_TAC;
2182 ASM_MESON_TAC[VECTOR_MUL_LZERO];
2183 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
2184 REWRITE_TAC[IN_ELIM_THM] THEN
2185 MAP_EVERY EXISTS_TAC [`&0`; `x:real^N`] THEN
2186 ASM_REWRITE_TAC[] THEN CONV_TAC VECTOR_ARITH];
2188 DISCH_THEN(fun th ->
2190 `(b:real^N) IN f /\ (c:real^N) IN f`
2191 MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN MP_TAC th) THEN
2192 ASM_CASES_TAC `ux = &0` THENL
2193 [DISCH_THEN(K ALL_TAC) THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
2194 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN
2195 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
2196 `&1 - ux - a = &0 ==> ux = &0 ==> ~(a < &1)`)) THEN
2197 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
2198 MATCH_MP_TAC REAL_LTE_TRANS THEN
2199 EXISTS_TAC `(&1 - v) * &1 + v * &1` THEN
2200 CONJ_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN
2201 MATCH_MP_TAC(REAL_ARITH
2202 `x <= y /\ w <= z /\ ~(x = y /\ w = z) ==> x + w < y + z`) THEN
2203 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_SUB_LT; REAL_EQ_MUL_LCANCEL] THEN
2204 REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
2205 ASM_SIMP_TAC[REAL_SUB_0; REAL_LT_IMP_NE] THEN
2206 REWRITE_TAC[REAL_ARITH `&1 - x = &1 <=> x = &0`] THEN
2207 DISCH_THEN(CONJUNCTS_THEN SUBST_ALL_TAC) THEN
2208 ASM_MESON_TAC[VECTOR_MUL_LZERO];
2210 REWRITE_TAC[VECTOR_SUB_EQ] THEN ASM_CASES_TAC `c:real^N = b` THENL
2211 [ASM_REWRITE_TAC[GSYM VECTOR_ADD_RDISTRIB; VECTOR_MUL_LCANCEL] THEN
2214 DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
2215 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_SEGMENT] THEN
2216 EXISTS_TAC `(v * uc) / ux:real` THEN
2217 ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_ARITH
2218 `&0 <= x /\ ~(x = &0) ==> &0 < x`] THEN
2219 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN REPEAT CONJ_TAC THENL
2220 [MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC;
2221 EXPAND_TAC "ux" THEN REWRITE_TAC[REAL_ARITH `b < a + b <=> &0 < a`] THEN
2222 MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC;
2223 FIRST_X_ASSUM(MP_TAC o AP_TERM `(%) (inv ux) :real^N->real^N`) THEN
2224 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN
2225 REWRITE_TAC[VECTOR_MUL_LID] THEN DISCH_THEN SUBST1_TAC THEN
2226 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
2227 BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
2228 REWRITE_TAC[REAL_ARITH `inv u * v * uc:real = (v * uc) / u`] THEN
2229 UNDISCH_TAC `(&1 - v) * ub + v * uc = ux` THEN
2230 UNDISCH_TAC `~(ux = &0)` THEN CONV_TAC REAL_FIELD];
2231 DISCH_THEN(MP_TAC o MATCH_MP (VECTOR_ARITH
2232 `a + (b - c):real^N = vec 0 ==> a = c + --b`)) THEN
2233 REWRITE_TAC[GSYM VECTOR_ADD_ASSOC; GSYM VECTOR_MUL_LNEG] THEN
2234 DISCH_THEN(MP_TAC o SPEC `affine hull s:real^N->bool` o
2235 MATCH_MP lemma) THEN
2236 ASM_REWRITE_TAC[AFFINE_AFFINE_HULL] THEN
2237 MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
2238 CONJ_TAC THENL [CONV_TAC REAL_RING; REPEAT CONJ_TAC] THEN
2239 MATCH_MP_TAC(REWRITE_RULE[SUBSET] CONVEX_HULL_SUBSET_AFFINE_HULL) THEN
2240 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);;
2242 (* ------------------------------------------------------------------------- *)
2244 (* ------------------------------------------------------------------------- *)
2246 let polytope = new_definition
2247 `polytope s <=> ?v. FINITE v /\ s = convex hull v`;;
2249 let POLYTOPE_TRANSLATION_EQ = prove
2250 (`!a s. polytope (IMAGE (\x:real^N. a + x) s) <=> polytope s`,
2251 REWRITE_TAC[polytope] THEN GEOM_TRANSLATE_TAC[]);;
2253 add_translation_invariants [POLYTOPE_TRANSLATION_EQ];;
2255 let POLYTOPE_LINEAR_IMAGE = prove
2256 (`!f:real^M->real^N p.
2257 linear f /\ polytope p ==> polytope(IMAGE f p)`,
2258 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2259 REWRITE_TAC[polytope] THEN
2260 DISCH_THEN(X_CHOOSE_THEN `s:real^M->bool` STRIP_ASSUME_TAC) THEN
2261 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
2262 ASM_SIMP_TAC[CONVEX_HULL_LINEAR_IMAGE; FINITE_IMAGE]);;
2264 let POLYTOPE_LINEAR_IMAGE_EQ = prove
2265 (`!f:real^M->real^N s.
2266 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
2267 ==> (polytope (IMAGE f s) <=> polytope s)`,
2268 REPEAT STRIP_TAC THEN REWRITE_TAC[polytope] THEN
2269 MP_TAC(ISPEC `f:real^M->real^N` QUANTIFY_SURJECTION_THM) THEN
2270 ASM_REWRITE_TAC[] THEN
2271 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)[th]) THEN
2272 MP_TAC(end_itlist CONJ
2273 (mapfilter (ISPEC `f:real^M->real^N`) (!invariant_under_linear))) THEN
2274 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[]);;
2276 let POLYTOPE_EMPTY = prove
2278 REWRITE_TAC[polytope] THEN MESON_TAC[FINITE_EMPTY; CONVEX_HULL_EMPTY]);;
2280 let POLYTOPE_NEGATIONS = prove
2281 (`!s:real^N->bool. polytope s ==> polytope(IMAGE (--) s)`,
2282 SIMP_TAC[POLYTOPE_LINEAR_IMAGE; LINEAR_NEGATION]);;
2284 let POLYTOPE_CONVEX_HULL = prove
2285 (`!s. FINITE s ==> polytope(convex hull s)`,
2286 REWRITE_TAC[polytope] THEN MESON_TAC[]);;
2288 let POLYTOPE_PCROSS = prove
2289 (`!s:real^M->bool t:real^N->bool.
2290 polytope s /\ polytope t ==> polytope(s PCROSS t)`,
2291 REPEAT GEN_TAC THEN REWRITE_TAC[polytope] THEN
2292 MESON_TAC[CONVEX_HULL_PCROSS; FINITE_PCROSS]);;
2294 let POLYTOPE_PCROSS_EQ = prove
2295 (`!s:real^M->bool t:real^N->bool.
2296 polytope(s PCROSS t) <=>
2297 s = {} \/ t = {} \/ polytope s /\ polytope t`,
2299 ASM_CASES_TAC `s:real^M->bool = {}` THEN
2300 ASM_REWRITE_TAC[PCROSS_EMPTY; POLYTOPE_EMPTY] THEN
2301 ASM_CASES_TAC `t:real^N->bool = {}` THEN
2302 ASM_REWRITE_TAC[PCROSS_EMPTY; POLYTOPE_EMPTY] THEN
2303 EQ_TAC THEN REWRITE_TAC[POLYTOPE_PCROSS] THEN REPEAT STRIP_TAC THENL
2304 [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`;
2305 `(s:real^M->bool) PCROSS (t:real^N->bool)`]
2306 POLYTOPE_LINEAR_IMAGE) THEN
2307 ASM_REWRITE_TAC[LINEAR_FSTCART];
2308 MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`;
2309 `(s:real^M->bool) PCROSS (t:real^N->bool)`]
2310 POLYTOPE_LINEAR_IMAGE) THEN
2311 ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN
2312 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2313 REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS;
2314 FSTCART_PASTECART; SNDCART_PASTECART] THEN
2317 let FACE_OF_POLYTOPE_POLYTOPE = prove
2318 (`!f s:real^N->bool. polytope s /\ f face_of s ==> polytope f`,
2319 REWRITE_TAC[polytope] THEN
2320 MESON_TAC[FINITE_SUBSET; FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);;
2322 let FINITE_POLYTOPE_FACES = prove
2323 (`!s:real^N->bool. polytope s ==> FINITE {f | f face_of s}`,
2324 GEN_TAC THEN REWRITE_TAC[polytope; LEFT_IMP_EXISTS_THM] THEN
2325 X_GEN_TAC `v:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2326 MATCH_MP_TAC FINITE_SUBSET THEN
2327 EXISTS_TAC `IMAGE ((hull) convex) {t:real^N->bool | t SUBSET v}` THEN
2328 ASM_SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE] THEN
2329 GEN_REWRITE_TAC I [SUBSET] THEN
2330 REWRITE_TAC[FORALL_IN_GSPEC; IN_IMAGE; IN_ELIM_THM] THEN
2331 ASM_MESON_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);;
2333 let FINITE_POLYTOPE_FACETS = prove
2334 (`!s:real^N->bool. polytope s ==> FINITE {f | f facet_of s}`,
2335 REWRITE_TAC[facet_of] THEN ONCE_REWRITE_TAC[SET_RULE
2336 `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN
2337 SIMP_TAC[FINITE_RESTRICT; FINITE_POLYTOPE_FACES]);;
2339 let POLYTOPE_SCALING = prove
2340 (`!c s:real^N->bool. polytope s ==> polytope (IMAGE (\x. c % x) s)`,
2341 REPEAT GEN_TAC THEN REWRITE_TAC[polytope] THEN DISCH_THEN
2342 (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
2343 EXISTS_TAC `IMAGE (\x:real^N. c % x) u` THEN
2344 ASM_SIMP_TAC[CONVEX_HULL_SCALING; FINITE_IMAGE]);;
2346 let POLYTOPE_SCALING_EQ = prove
2347 (`!c s:real^N->bool.
2348 ~(c = &0) ==> (polytope (IMAGE (\x. c % x) s) <=> polytope s)`,
2349 REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[POLYTOPE_SCALING] THEN
2350 DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP POLYTOPE_SCALING) THEN
2351 ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; VECTOR_MUL_ASSOC;
2352 REAL_MUL_LINV; VECTOR_MUL_LID; IMAGE_ID]);;
2354 let POLYTOPE_SUMS = prove
2355 (`!s t:real^N->bool.
2356 polytope s /\ polytope t ==> polytope {x + y | x IN s /\ y IN t}`,
2357 REPEAT GEN_TAC THEN REWRITE_TAC[polytope] THEN DISCH_THEN(CONJUNCTS_THEN2
2358 (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC)
2359 (X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC)) THEN
2360 EXISTS_TAC `{x + y:real^N | x IN u /\ y IN v}` THEN
2361 ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; CONVEX_HULL_SUMS]);;
2363 let POLYTOPE_IMP_COMPACT = prove
2364 (`!s. polytope s ==> compact s`,
2365 SIMP_TAC[polytope; LEFT_IMP_EXISTS_THM; COMPACT_CONVEX_HULL;
2366 FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]);;
2368 let POLYTOPE_IMP_CONVEX = prove
2369 (`!s. polytope s ==> convex s`,
2370 SIMP_TAC[polytope; LEFT_IMP_EXISTS_THM; CONVEX_CONVEX_HULL]);;
2372 let POLYTOPE_IMP_CLOSED = prove
2373 (`!s. polytope s ==> closed s`,
2374 SIMP_TAC[POLYTOPE_IMP_COMPACT; COMPACT_IMP_CLOSED]);;
2376 let POLYTOPE_IMP_BOUNDED = prove
2377 (`!s. polytope s ==> bounded s`,
2378 SIMP_TAC[POLYTOPE_IMP_COMPACT; COMPACT_IMP_BOUNDED]);;
2380 let POLYTOPE_INTERVAL = prove
2381 (`!a b. polytope(interval[a,b])`,
2382 REWRITE_TAC[polytope] THEN MESON_TAC[CLOSED_INTERVAL_AS_CONVEX_HULL]);;
2384 let POLYTOPE_SING = prove
2385 (`!a. polytope {a}`,
2386 MESON_TAC[POLYTOPE_INTERVAL; INTERVAL_SING]);;
2388 (* ------------------------------------------------------------------------- *)
2389 (* Approximation of bounded convex sets by polytopes. *)
2390 (* ------------------------------------------------------------------------- *)
2392 let CONVEX_INNER_APPROXIMATION = prove
2393 (`!s:real^N->bool e.
2394 bounded s /\ convex s /\ &0 < e
2395 ==> ?k. FINITE k /\ convex hull k SUBSET s /\
2396 hausdist(convex hull k,s) < e /\
2397 (k = {} ==> s = {})`,
2398 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
2399 [EXISTS_TAC `{}:real^N->bool` THEN
2400 ASM_SIMP_TAC[FINITE_EMPTY; CONVEX_HULL_EMPTY; HAUSDIST_REFL; SUBSET_REFL];
2402 MP_TAC(ISPEC `closure s:real^N->bool` COMPACT_EQ_HEINE_BOREL) THEN
2403 ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN
2404 DISCH_THEN(MP_TAC o SPEC `{ball(x:real^N,e / &2) | x IN s}`) THEN
2405 REWRITE_TAC[FORALL_IN_GSPEC; OPEN_BALL] THEN ANTS_TAC THENL
2406 [REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM; CLOSURE_APPROACHABLE] THEN
2407 X_GEN_TAC `x:real^N` THEN DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
2408 ASM_REWRITE_TAC[IN_BALL; REAL_HALF];
2409 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
2410 REWRITE_TAC[SIMPLE_IMAGE; EXISTS_FINITE_SUBSET_IMAGE]] THEN
2411 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
2412 ASM_CASES_TAC `k:real^N->bool = {}` THEN
2413 ASM_REWRITE_TAC[IMAGE_CLAUSES; UNIONS_0; SUBSET_EMPTY; CLOSURE_EQ_EMPTY] THEN
2414 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2415 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
2416 [ASM_SIMP_TAC[HULL_MINIMAL]; DISCH_TAC] THEN
2417 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
2418 `&0 < e ==> x <= e / &2 ==> x < e`)) THEN
2419 MATCH_MP_TAC REAL_HAUSDIST_LE THEN
2420 ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN CONJ_TAC THENL
2421 [RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN
2422 ASM_SIMP_TAC[SETDIST_SING_IN_SET] THEN ASM_REAL_ARITH_TAC;
2424 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN UNDISCH_TAC
2425 `closure s SUBSET UNIONS (IMAGE (\x:real^N. ball (x,e / &2)) k)` THEN
2426 REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
2427 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN
2428 REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_BALL] THEN
2429 ONCE_REWRITE_TAC[DIST_SYM] THEN
2430 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
2431 TRANS_TAC REAL_LE_TRANS `dist(x:real^N,y)` THEN
2432 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC SETDIST_LE_DIST THEN
2433 ASM_SIMP_TAC[IN_SING; HULL_INC]);;
2435 let CONVEX_OUTER_APPROXIMATION = prove
2436 (`!s:real^N->bool e.
2437 bounded s /\ convex s /\ &0 < e
2438 ==> ?k. FINITE k /\ s SUBSET convex hull k /\
2439 hausdist(convex hull k,s) < e`,
2440 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
2441 [EXISTS_TAC `{}:real^N->bool` THEN
2442 ASM_REWRITE_TAC[FINITE_EMPTY; EMPTY_SUBSET; HAUSDIST_EMPTY;
2445 MP_TAC(ISPECL [`{x + y:real^N | x IN s /\ y IN ball(vec 0,e / &2)}`;
2446 `e / &2`] CONVEX_INNER_APPROXIMATION) THEN
2447 ASM_SIMP_TAC[CONVEX_SUMS; CONVEX_BALL; BOUNDED_SUMS; BOUNDED_BALL] THEN
2448 ASM_REWRITE_TAC[REAL_HALF; BALL_EQ_EMPTY; GSYM REAL_NOT_LT; SET_RULE
2449 `{f x y | x IN s /\ y IN t} = {} <=> s = {} \/ t = {}`] THEN
2450 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
2451 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2452 FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[REAL_NOT_LE]
2453 (ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM] REAL_LE_HAUSDIST))) THEN
2454 REWRITE_TAC[TAUT `~(p /\ q) <=> p ==> ~q`; RIGHT_FORALL_IMP_THM] THEN
2455 ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY; LEFT_FORALL_IMP_THM] THEN
2456 ASM_REWRITE_TAC[REAL_HALF; BALL_EQ_EMPTY; GSYM REAL_NOT_LT; SET_RULE
2457 `{f x y | x IN s /\ y IN t} = {} <=> s = {} \/ t = {}`] THEN
2458 REWRITE_TAC[DE_MORGAN_THM; REAL_NOT_LT; FORALL_AND_THM] THEN ANTS_TAC THENL
2459 [EXISTS_TAC `hausdist(convex hull k,
2460 {x + y:real^N | x IN s /\ y IN ball(vec 0,e / &2)})` THEN
2461 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
2462 MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN
2463 ASM_SIMP_TAC[BOUNDED_CONVEX_HULL; FINITE_IMP_BOUNDED] THEN
2464 ASM_SIMP_TAC[BOUNDED_SUMS; BOUNDED_BALL];
2467 [EXISTS_TAC `hausdist(convex hull k,
2468 {x + y:real^N | x IN s /\ y IN ball(vec 0,e / &2)})` THEN
2469 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
2470 ONCE_REWRITE_TAC[HAUSDIST_SYM] THEN
2471 MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN
2472 ASM_SIMP_TAC[BOUNDED_CONVEX_HULL; FINITE_IMP_BOUNDED] THEN
2473 ASM_SIMP_TAC[BOUNDED_SUMS; BOUNDED_BALL];
2474 REWRITE_TAC[TAUT `~p \/ q <=> p ==> q`] THEN DISCH_TAC] THEN
2476 [MATCH_MP_TAC SUBSET_SUMS_RCANCEL THEN
2477 EXISTS_TAC `ball(vec 0:real^N,e / &2)` THEN
2478 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL; FINITE_IMP_COMPACT;
2479 CONVEX_CONVEX_HULL; BALL_EQ_EMPTY; BOUNDED_BALL; REAL_NOT_LE] THEN
2480 ASM_REWRITE_TAC[REAL_HALF; SUBSET] THEN X_GEN_TAC `z:real^N` THEN
2481 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:real^N` o CONJUNCT2) THEN
2482 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP
2483 (ONCE_REWRITE_RULE[IMP_CONJ_ALT] (REWRITE_RULE[CONJ_ASSOC]
2484 REAL_SETDIST_LT_EXISTS))) THEN
2485 ASM_REWRITE_TAC[NOT_INSERT_EMPTY; CONVEX_HULL_EQ_EMPTY; IN_SING] THEN
2486 REWRITE_TAC[IN_BALL_0; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN
2487 REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
2488 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
2489 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `z - y:real^N` THEN
2490 ASM_REWRITE_TAC[GSYM dist] THEN CONV_TAC VECTOR_ARITH;
2491 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
2492 `&0 < e ==> x <= e / &2 ==> x < e`)) THEN
2493 MATCH_MP_TAC REAL_HAUSDIST_LE THEN
2494 ASM_REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN CONJ_TAC THENL
2495 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
2496 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
2497 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
2498 ASM_REWRITE_TAC[IN_ELIM_THM] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
2499 REWRITE_TAC[VECTOR_ARITH `x:real^N = z + y <=> x - z = y`] THEN
2500 REWRITE_TAC[UNWIND_THM1; IN_BALL_0; GSYM dist] THEN
2501 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
2502 TRANS_TAC REAL_LE_TRANS `dist(x:real^N,y)` THEN
2503 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC SETDIST_LE_DIST THEN
2504 ASM_REWRITE_TAC[IN_SING];
2505 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
2506 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N` o CONJUNCT2) THEN
2507 ANTS_TAC THENL [ALL_TAC; REWRITE_TAC[REAL_LT_IMP_LE]] THEN
2508 REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `x:real^N` THEN
2509 EXISTS_TAC `vec 0:real^N` THEN ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN
2510 ASM_REWRITE_TAC[REAL_HALF; VECTOR_ADD_RID]]]);;
2512 let CONVEX_INNER_POLYTOPE = prove
2513 (`!s:real^N->bool e.
2514 bounded s /\ convex s /\ &0 < e
2515 ==> ?p. polytope p /\ p SUBSET s /\ hausdist(p,s) < e /\
2516 (p = {} ==> s = {})`,
2517 REPEAT GEN_TAC THEN DISCH_TAC THEN
2518 FIRST_ASSUM(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC o
2519 MATCH_MP CONVEX_INNER_APPROXIMATION) THEN
2520 EXISTS_TAC `convex hull k:real^N->bool` THEN
2521 ASM_SIMP_TAC[CONVEX_HULL_EQ_EMPTY; POLYTOPE_CONVEX_HULL]);;
2523 let CONVEX_OUTER_POLYTOPE = prove
2524 (`!s:real^N->bool e.
2525 bounded s /\ convex s /\ &0 < e
2526 ==> ?p. polytope p /\ s SUBSET p /\ hausdist(p,s) < e`,
2527 REPEAT GEN_TAC THEN DISCH_TAC THEN
2528 FIRST_ASSUM(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC o
2529 MATCH_MP CONVEX_OUTER_APPROXIMATION) THEN
2530 EXISTS_TAC `convex hull k:real^N->bool` THEN
2531 ASM_SIMP_TAC[CONVEX_HULL_EQ_EMPTY; POLYTOPE_CONVEX_HULL]);;
2533 (* ------------------------------------------------------------------------- *)
2535 (* ------------------------------------------------------------------------- *)
2537 let polyhedron = new_definition
2541 (!h. h IN f ==> ?a b. ~(a = vec 0) /\ h = {x | a dot x <= b})`;;
2543 let POLYHEDRON_INTER = prove
2544 (`!s t:real^N->bool.
2545 polyhedron s /\ polyhedron t ==> polyhedron (s INTER t)`,
2546 REPEAT GEN_TAC THEN REWRITE_TAC[polyhedron] THEN
2547 DISCH_THEN(CONJUNCTS_THEN2
2548 (X_CHOOSE_TAC `f:(real^N->bool)->bool`)
2549 (X_CHOOSE_TAC `g:(real^N->bool)->bool`)) THEN
2550 EXISTS_TAC `f UNION g:(real^N->bool)->bool` THEN
2551 ASM_REWRITE_TAC[SET_RULE `INTERS(f UNION g) = INTERS f INTER INTERS g`] THEN
2552 REWRITE_TAC[FINITE_UNION; IN_UNION] THEN
2553 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);;
2555 let POLYHEDRON_UNIV = prove
2556 (`polyhedron(:real^N)`,
2557 REWRITE_TAC[polyhedron] THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN
2558 REWRITE_TAC[INTERS_0; NOT_IN_EMPTY; FINITE_RULES]);;
2560 let POLYHEDRON_POSITIVE_ORTHANT = prove
2561 (`polyhedron {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`,
2562 REWRITE_TAC[polyhedron] THEN
2563 EXISTS_TAC `IMAGE (\i. {x:real^N | &0 <= x$i}) (1..dimindex(:N))` THEN
2564 SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN CONJ_TAC THENL
2565 [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[INTERS_IMAGE] THEN
2566 REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG];
2567 X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
2568 MAP_EVERY EXISTS_TAC [`--basis k:real^N`; `&0`] THEN
2569 ASM_SIMP_TAC[VECTOR_NEG_EQ_0; DOT_LNEG; DOT_BASIS; BASIS_NONZERO] THEN
2570 REWRITE_TAC[REAL_ARITH `--x <= &0 <=> &0 <= x`]]);;
2572 let POLYHEDRON_INTERS = prove
2573 (`!f:(real^N->bool)->bool.
2574 FINITE f /\ (!s. s IN f ==> polyhedron s) ==> polyhedron(INTERS f)`,
2575 REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2576 REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; POLYHEDRON_UNIV] THEN
2577 ASM_SIMP_TAC[INTERS_INSERT; FORALL_IN_INSERT; POLYHEDRON_INTER]);;
2579 let POLYHEDRON_EMPTY = prove
2580 (`polyhedron({}:real^N->bool)`,
2581 REWRITE_TAC[polyhedron] THEN
2582 EXISTS_TAC `{{x:real^N | basis 1 dot x <= -- &1},
2583 {x | --(basis 1) dot x <= -- &1}}` THEN
2584 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; INTERS_2; FORALL_IN_INSERT] THEN
2585 REWRITE_TAC[NOT_IN_EMPTY; INTER; IN_ELIM_THM; DOT_LNEG] THEN
2586 REWRITE_TAC[REAL_ARITH `~(a <= -- &1 /\ --a <= -- &1)`; EMPTY_GSPEC] THEN
2588 [MAP_EVERY EXISTS_TAC [`basis 1:real^N`; `-- &1`];
2589 MAP_EVERY EXISTS_TAC [`--(basis 1):real^N`; `-- &1`]] THEN
2590 SIMP_TAC[VECTOR_NEG_EQ_0; BASIS_NONZERO; DOT_LNEG;
2591 DIMINDEX_GE_1; LE_REFL]);;
2593 let POLYHEDRON_HALFSPACE_LE = prove
2594 (`!a b. polyhedron {x:real^N | a dot x <= b}`,
2595 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
2596 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
2597 COND_CASES_TAC THEN ASM_REWRITE_TAC[POLYHEDRON_EMPTY; POLYHEDRON_UNIV];
2598 REWRITE_TAC[polyhedron] THEN EXISTS_TAC `{{x:real^N | a dot x <= b}}` THEN
2599 REWRITE_TAC[FINITE_SING; INTERS_1; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN
2600 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN ASM_REWRITE_TAC[]]);;
2602 let POLYHEDRON_HALFSPACE_GE = prove
2603 (`!a b. polyhedron {x:real^N | a dot x >= b}`,
2604 REWRITE_TAC[REAL_ARITH `a:real >= b <=> --a <= --b`] THEN
2605 REWRITE_TAC[GSYM DOT_LNEG; POLYHEDRON_HALFSPACE_LE]);;
2607 let POLYHEDRON_HYPERPLANE = prove
2608 (`!a b. polyhedron {x:real^N | a dot x = b}`,
2609 REWRITE_TAC[REAL_ARITH `x:real = b <=> x <= b /\ x >= b`] THEN
2610 REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
2611 SIMP_TAC[POLYHEDRON_INTER; POLYHEDRON_HALFSPACE_LE;
2612 POLYHEDRON_HALFSPACE_GE]);;
2614 let AFFINE_IMP_POLYHEDRON = prove
2615 (`!s:real^N->bool. affine s ==> polyhedron s`,
2616 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool`
2617 AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES) THEN
2618 ASM_SIMP_TAC[HULL_P; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2619 STRIP_TAC THEN ASM_SIMP_TAC[] THEN
2620 MATCH_MP_TAC POLYHEDRON_INTERS THEN ASM_REWRITE_TAC[] THEN
2621 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2622 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2623 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
2624 REWRITE_TAC[POLYHEDRON_HYPERPLANE]);;
2626 let POLYHEDRON_IMP_CLOSED = prove
2627 (`!s:real^N->bool. polyhedron s ==> closed s`,
2628 REWRITE_TAC[polyhedron; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2629 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2630 MATCH_MP_TAC CLOSED_INTERS THEN
2631 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2632 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2633 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
2634 REWRITE_TAC[CLOSED_HALFSPACE_LE]);;
2636 let POLYHEDRON_IMP_CONVEX = prove
2637 (`!s:real^N->bool. polyhedron s ==> convex s`,
2638 REWRITE_TAC[polyhedron; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2639 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2640 MATCH_MP_TAC CONVEX_INTERS THEN
2641 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2642 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2643 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
2644 REWRITE_TAC[CONVEX_HALFSPACE_LE]);;
2646 let POLYHEDRON_AFFINE_HULL = prove
2647 (`!s. polyhedron(affine hull s)`,
2648 SIMP_TAC[AFFINE_IMP_POLYHEDRON; AFFINE_AFFINE_HULL]);;
2650 (* ------------------------------------------------------------------------- *)
2651 (* Canonical polyedron representation making facial structure explicit. *)
2652 (* ------------------------------------------------------------------------- *)
2654 let POLYHEDRON_INTER_AFFINE = prove
2655 (`!s. polyhedron s <=>
2657 s = (affine hull s) INTER (INTERS f) /\
2659 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b})`,
2660 GEN_TAC THEN EQ_TAC THENL
2661 [REWRITE_TAC[polyhedron] THEN MATCH_MP_TAC MONO_EXISTS THEN
2662 GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THEN
2663 TRY(FIRST_ASSUM ACCEPT_TAC) THEN
2664 MATCH_MP_TAC(SET_RULE `s = t /\ s SUBSET u ==> s = u INTER t`) THEN
2665 REWRITE_TAC[HULL_SUBSET] THEN ASM_REWRITE_TAC[];
2666 STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
2667 MATCH_MP_TAC POLYHEDRON_INTER THEN REWRITE_TAC[POLYHEDRON_AFFINE_HULL] THEN
2668 MATCH_MP_TAC POLYHEDRON_INTERS THEN ASM_REWRITE_TAC[] THEN
2669 ASM_MESON_TAC[POLYHEDRON_HALFSPACE_LE]]);;
2671 let POLYHEDRON_INTER_AFFINE_PARALLEL = prove
2675 s = (affine hull s) INTER (INTERS f) /\
2677 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b} /\
2678 (!x. x IN affine hull s
2679 ==> (x + a) IN affine hull s))`,
2680 GEN_TAC THEN REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN EQ_TAC THENL
2681 [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]] THEN
2682 DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` MP_TAC) THEN
2683 ASM_CASES_TAC `s:real^N->bool = {}` THENL
2684 [DISCH_THEN(K ALL_TAC) THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN
2685 ASM_SIMP_TAC[AFFINE_HULL_EMPTY; INTER_EMPTY; NOT_IN_EMPTY; FINITE_EMPTY];
2687 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL
2688 [ASM_REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; INTER_UNIV] THEN
2689 DISCH_THEN(ASSUME_TAC o SYM o CONJUNCT2) THEN
2690 EXISTS_TAC `{}:(real^N->bool)->bool` THEN
2691 ASM_REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; INTER_UNIV; FINITE_EMPTY];
2693 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o GSYM) MP_TAC)) THEN
2694 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
2695 [RIGHT_IMP_EXISTS_THM] THEN
2696 REWRITE_TAC[LEFT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2698 [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN
2699 DISCH_THEN(ASSUME_TAC o GSYM) THEN
2701 `!h. h IN f /\ ~(affine hull s SUBSET h)
2702 ==> ?a' b'. ~(a' = vec 0) /\
2703 affine hull s INTER {x:real^N | a' dot x <= b'} =
2704 affine hull s INTER h /\
2705 !w. w IN affine hull s ==> (w + a') IN affine hull s`
2707 [GEN_TAC THEN STRIP_TAC THEN
2708 FIRST_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2709 REWRITE_TAC[ASSUME `(h:real^N->bool) IN f`] THEN
2710 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC o GSYM) THEN
2711 MP_TAC(ISPECL [`affine hull s:real^N->bool`;
2712 `(a:(real^N->bool)->real^N) h`;
2713 `(b:(real^N->bool)->real) h`]
2714 AFFINE_PARALLEL_SLICE) THEN
2715 REWRITE_TAC[AFFINE_AFFINE_HULL] THEN MATCH_MP_TAC(TAUT
2716 `~p /\ ~q /\ (r ==> r') ==> (p \/ q \/ r ==> r')`) THEN
2717 ASM_SIMP_TAC[] THEN CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
2719 UNDISCH_TAC `~(s:real^N->bool = {})` THEN
2720 EXPAND_TAC "s" THEN REWRITE_TAC[GSYM INTERS_INSERT] THEN
2721 MATCH_MP_TAC(SET_RULE
2722 `!t. t SUBSET s /\ INTERS t = {} ==> INTERS s = {}`) THEN
2723 EXISTS_TAC `{affine hull s,h:real^N->bool}` THEN
2724 ASM_REWRITE_TAC[INTERS_2] THEN ASM SET_TAC[];
2726 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
2727 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
2728 FIRST_X_ASSUM(K ALL_TAC o SPEC `{}:real^N->bool`) THEN
2730 [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN
2732 EXISTS_TAC `IMAGE (\h:real^N->bool. {x:real^N | a h dot x <= b h})
2733 {h | h IN f /\ ~(affine hull s SUBSET h)}` THEN
2734 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; FORALL_IN_IMAGE] THEN
2735 REWRITE_TAC[FORALL_IN_GSPEC] THEN CONJ_TAC THENL
2737 X_GEN_TAC `h:real^N->bool` THEN STRIP_TAC THEN
2738 MAP_EVERY EXISTS_TAC
2739 [`(a:(real^N->bool)->real^N) h`; `(b:(real^N->bool)->real) h`] THEN
2740 ASM_MESON_TAC[]] THEN
2741 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN
2742 GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN
2743 REWRITE_TAC[INTERS_IMAGE; IN_INTER; IN_ELIM_THM] THEN
2744 ASM_CASES_TAC `(x:real^N) IN affine hull s` THEN
2745 ASM_REWRITE_TAC[IN_INTERS] THEN AP_TERM_TAC THEN ABS_TAC THEN
2748 let POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL = prove
2749 (`!s. polyhedron s <=>
2751 s = (affine hull s) INTER (INTERS f) /\
2753 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b} /\
2754 (!x. x IN affine hull s
2755 ==> (x + a) IN affine hull s)) /\
2756 !f'. f' PSUBSET f ==> s PSUBSET (affine hull s) INTER (INTERS f')`,
2757 GEN_TAC THEN REWRITE_TAC[POLYHEDRON_INTER_AFFINE_PARALLEL] THEN
2758 EQ_TAC THENL [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]] THEN
2759 GEN_REWRITE_TAC LAND_CONV
2761 `(?f. FINITE f /\ P f) <=> (?n f. f HAS_SIZE n /\ P f)`] THEN
2762 GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN
2763 DISCH_THEN(X_CHOOSE_THEN `n:num` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
2764 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[HAS_SIZE] THEN
2765 X_GEN_TAC `f:(real^N->bool)->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2766 CONJ_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
2767 X_GEN_TAC `f':(real^N->bool)->bool` THEN DISCH_TAC THEN
2768 FIRST_X_ASSUM(MP_TAC o SPEC `CARD(f':(real^N->bool)->bool)`) THEN
2769 ANTS_TAC THENL [ASM_MESON_TAC[CARD_PSUBSET]; ALL_TAC] THEN
2770 REWRITE_TAC[NOT_EXISTS_THM; HAS_SIZE] THEN
2771 DISCH_THEN(MP_TAC o SPEC `f':(real^N->bool)->bool`) THEN
2772 MATCH_MP_TAC(TAUT `a /\ c /\ (~b ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN
2773 CONJ_TAC THENL [ASM_MESON_TAC[PSUBSET; FINITE_SUBSET]; ALL_TAC] THEN
2775 [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[];
2776 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(s = t) ==> s PSUBSET t`) THEN
2777 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
2780 let POLYHEDRON_INTER_AFFINE_MINIMAL = prove
2781 (`!s. polyhedron s <=>
2783 s = (affine hull s) INTER (INTERS f) /\
2785 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b}) /\
2786 !f'. f' PSUBSET f ==> s PSUBSET (affine hull s) INTER (INTERS f')`,
2787 GEN_TAC THEN EQ_TAC THENL
2788 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL];
2789 REWRITE_TAC[POLYHEDRON_INTER_AFFINE]] THEN
2790 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN MESON_TAC[]);;
2792 let RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT = prove
2793 (`!s:real^N->bool f a b.
2795 s = affine hull s INTER INTERS f /\
2796 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
2797 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
2798 ==> relative_interior s =
2799 {x | x IN s /\ !h. h IN f ==> a h dot x < b h}`,
2800 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2801 DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) STRIP_ASSUME_TAC) THEN
2802 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN
2803 X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
2805 STRIP_TAC THEN ASM_REWRITE_TAC[RELATIVE_INTERIOR; IN_ELIM_THM] THEN
2806 EXISTS_TAC `INTERS {interior h | (h:real^N->bool) IN f}` THEN
2807 ASM_SIMP_TAC[SIMPLE_IMAGE; OPEN_INTERS; FINITE_IMAGE; OPEN_INTERIOR;
2808 FORALL_IN_IMAGE; IN_INTERS] THEN
2810 [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2811 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`)) THEN
2812 ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN
2813 FIRST_ASSUM(SUBST1_TAC o CONJUNCT2) THEN
2814 ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; IN_ELIM_THM];
2815 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN
2816 MATCH_MP_TAC(SET_RULE
2817 `(!s. s IN f ==> i s SUBSET s)
2818 ==> INTERS (IMAGE i f) INTER t SUBSET t INTER INTERS f`) THEN
2819 REWRITE_TAC[INTERIOR_SUBSET]]] THEN
2821 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN
2822 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:real^N->bool` THEN
2824 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (i:real^N->bool)`) THEN ANTS_TAC THENL
2826 REWRITE_TAC[PSUBSET_ALT; IN_INTER; IN_INTERS; IN_DELETE]] THEN
2827 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2828 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2829 SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot z > b i` ASSUME_TAC THENL
2830 [UNDISCH_TAC `~((z:real^N) IN s)` THEN
2831 FIRST_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[IN_INTER; IN_INTERS] THEN
2832 ASM_REWRITE_TAC[REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN ASM SET_TAC[];
2834 SUBGOAL_THEN `~(z:real^N = x)` ASSUME_TAC THENL
2835 [ASM_MESON_TAC[]; ALL_TAC] THEN
2837 `?l. &0 < l /\ l < &1 /\ (l % z + (&1 - l) % x:real^N) IN s`
2838 STRIP_ASSUME_TAC THENL
2839 [FIRST_ASSUM(X_CHOOSE_THEN `e:real` MP_TAC o CONJUNCT2) THEN
2840 REWRITE_TAC[SUBSET; IN_INTER; IN_BALL; dist] THEN STRIP_TAC THEN
2841 EXISTS_TAC `min (&1 / &2) (e / &2 / norm(z - x:real^N))` THEN
2842 REWRITE_TAC[REAL_MIN_LT; REAL_LT_MIN] THEN
2843 CONV_TAC REAL_RAT_REDUCE_CONV THEN
2844 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2845 FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL
2846 [REWRITE_TAC[VECTOR_ARITH
2847 `x - (l % z + (&1 - l) % x):real^N = --l % (z - x)`] THEN
2848 REWRITE_TAC[NORM_MUL; REAL_ABS_NEG] THEN
2849 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2850 MATCH_MP_TAC(REAL_ARITH
2851 `&0 < a /\ &0 < b /\ b < c ==> abs(min a b) < c`) THEN
2852 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2853 REWRITE_TAC[REAL_LT_01; real_div; REAL_MUL_ASSOC] THEN
2854 MATCH_MP_TAC REAL_LT_RMUL THEN
2855 ASM_REWRITE_TAC[REAL_LT_INV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2856 UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC;
2857 ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN
2858 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
2861 MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN EXISTS_TAC `&1 - l` THEN
2862 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
2863 REWRITE_TAC[REAL_ARITH `a < b * (&1 - l) <=> l * b + a < b`] THEN
2864 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC
2865 `l * (a:(real^N->bool)->real^N) i dot z + (a i dot x) * (&1 - l)` THEN
2866 ASM_SIMP_TAC[REAL_LT_RADD; REAL_LT_LMUL_EQ; GSYM real_gt] THEN
2867 ONCE_REWRITE_TAC[REAL_ARITH `a * (&1 - b) = (&1 - b) * a`] THEN
2868 REWRITE_TAC[GSYM DOT_RMUL; GSYM DOT_RADD] THEN ASM SET_TAC[]);;
2870 let FACET_OF_POLYHEDRON_EXPLICIT = prove
2871 (`!s:real^N->bool f a b.
2873 s = affine hull s INTER INTERS f /\
2874 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
2875 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
2876 ==> !c. c facet_of s <=>
2877 ?h. h IN f /\ c = s INTER {x | a h dot x = b h}`,
2878 REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
2879 [ASM_REWRITE_TAC[INTER_EMPTY; AFFINE_HULL_EMPTY; SET_RULE `~(s PSUBSET s)`;
2880 FACET_OF_EMPTY] THEN
2881 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
2882 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
2883 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
2884 DISCH_THEN(X_CHOOSE_TAC `h:real^N->bool`) THEN DISCH_THEN
2885 (MP_TAC o SPEC `f DELETE (h:real^N->bool)` o last o CONJUNCTS) THEN
2888 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
2889 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
2890 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
2892 FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN
2895 h IN f ==> (s INTER {x:real^N | a h dot x = b h}) facet_of s`
2896 (LABEL_TAC "face") THENL
2897 [REPEAT STRIP_TAC THEN REWRITE_TAC[facet_of] THEN CONJ_TAC THENL
2898 [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
2900 [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN
2901 REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
2902 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
2903 X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN
2904 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
2905 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN
2906 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
2907 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2908 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
2910 MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_EQ_EMPTY) THEN
2911 ASM_SIMP_TAC[] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
2912 DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN
2913 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN
2915 FIRST_ASSUM(MP_TAC o SPEC `f DELETE (h:real^N->bool)`) THEN
2918 REWRITE_TAC[PSUBSET_ALT; IN_INTER; IN_INTERS; IN_DELETE]] THEN
2919 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2920 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2921 SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot z > b h` ASSUME_TAC THENL
2922 [UNDISCH_TAC `~((z:real^N) IN s)` THEN
2923 FIRST_ASSUM(SUBST1_TAC o SYM) THEN
2924 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
2925 ASM_REWRITE_TAC[REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN
2928 SUBGOAL_THEN `~(z:real^N = x)` ASSUME_TAC THENL
2929 [ASM_MESON_TAC[]; ALL_TAC] THEN
2930 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
2931 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
2932 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
2933 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
2934 [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
2935 GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN
2936 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
2937 ASM_REWRITE_TAC[IN_ELIM_THM] THEN
2938 DISCH_THEN(fun th ->
2939 MP_TAC(SPEC `h:real^N->bool` th) THEN ASM_REWRITE_TAC[] THEN
2940 DISCH_TAC THEN ASSUME_TAC th) THEN
2941 SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot x < a h dot z`
2942 ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2943 ABBREV_TAC `l = (b h - (a:(real^N->bool)->real^N) h dot x) /
2944 (a h dot z - a h dot x)` THEN
2945 SUBGOAL_THEN `&0 < l /\ l < &1` STRIP_ASSUME_TAC THENL
2946 [EXPAND_TAC "l" THEN
2947 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN
2950 ABBREV_TAC `w:real^N = (&1 - l) % x + l % z:real^N` THEN
2952 `!i. i IN f /\ ~(i = h) ==> (a:(real^N->bool)->real^N) i dot w < b i`
2954 [X_GEN_TAC `i:real^N->bool` THEN STRIP_TAC THEN EXPAND_TAC "w" THEN
2955 REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
2956 MATCH_MP_TAC(REAL_ARITH
2957 `(&1 - l) * x < (&1 - l) * z /\ l * y <= l * z
2958 ==> (&1 - l) * x + l * y < z`) THEN
2959 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_IMP_LE;
2960 REAL_LT_LMUL_EQ; REAL_SUB_LT] THEN
2961 UNDISCH_TAC `!t:real^N->bool. t IN f /\ ~(t = h) ==> z IN t` THEN
2962 DISCH_THEN(MP_TAC o SPEC `i:real^N->bool`) THEN ASM SET_TAC[];
2964 SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot w = b h` ASSUME_TAC THENL
2965 [EXPAND_TAC "w" THEN REWRITE_TAC[VECTOR_ARITH
2966 `(&1 - l) % x + l % z:real^N = x + l % (z - x)`] THEN
2967 EXPAND_TAC "l" THEN REWRITE_TAC[DOT_RADD; DOT_RSUB; DOT_RMUL] THEN
2968 ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NE; REAL_SUB_0] THEN
2971 SUBGOAL_THEN `(w:real^N) IN s` ASSUME_TAC THENL
2972 [FIRST_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [th]) THEN
2973 REWRITE_TAC[IN_INTER; IN_INTERS] THEN CONJ_TAC THENL
2974 [EXPAND_TAC "w" THEN
2975 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
2976 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_INC THEN
2977 ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET];
2979 X_GEN_TAC `i:real^N->bool` THEN DISCH_TAC THEN
2980 ASM_CASES_TAC `i:real^N->bool = h` THENL
2981 [ASM SET_TAC[REAL_LE_REFL]; ALL_TAC] THEN
2982 SUBGOAL_THEN `convex(i:real^N->bool)` MP_TAC THENL
2983 [REPEAT(FIRST_X_ASSUM(MP_TAC o C MATCH_MP
2984 (ASSUME `(i:real^N->bool) IN f`))) THEN
2985 REPEAT(DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th])) THEN
2986 REWRITE_TAC[CONVEX_HALFSPACE_LE];
2988 REWRITE_TAC[CONVEX_ALT] THEN EXPAND_TAC "w" THEN
2989 DISCH_THEN MATCH_MP_TAC THEN
2990 ASM_SIMP_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT1) THEN
2991 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN
2992 REWRITE_TAC[IN_INTER; IN_INTERS] THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
2994 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
2995 ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN
2997 `affine hull (s INTER {x | (a:(real^N->bool)->real^N) h dot x = b h}) =
2998 (affine hull s) INTER {x | a h dot x = b h}`
3001 SIMP_TAC[AFF_DIM_AFFINE_INTER_HYPERPLANE; AFFINE_AFFINE_HULL] THEN
3002 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
3003 COND_CASES_TAC THENL [ASM SET_TAC[REAL_LT_REFL]; REFL_TAC]] THEN
3004 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET_INTER] THEN
3005 REPEAT CONJ_TAC THENL
3006 [MATCH_MP_TAC HULL_MONO THEN SET_TAC[];
3007 MATCH_MP_TAC(SET_RULE
3008 `s SUBSET affine hull t /\ affine hull t = t ==> s SUBSET t`) THEN
3009 REWRITE_TAC[AFFINE_HULL_EQ; AFFINE_HYPERPLANE] THEN
3010 MATCH_MP_TAC HULL_MONO THEN SET_TAC[];
3012 REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
3013 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
3016 !j. j IN f /\ ~(j:real^N->bool = h)
3017 ==> t * (a j dot y - a j dot w) <= b j - a j dot (w:real^N)`
3018 STRIP_ASSUME_TAC THENL
3019 [ASM_CASES_TAC `f DELETE (h:real^N->bool) = {}` THENL
3020 [ASM_REWRITE_TAC[GSYM IN_DELETE; NOT_IN_EMPTY] THEN
3021 EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01];
3023 EXISTS_TAC `inf (IMAGE
3024 (\j. if &0 < a j dot y - a j dot (w:real^N)
3025 then (b j - a j dot w) / (a j dot y - a j dot w)
3026 else &1) (f DELETE (h:real^N->bool)))` THEN
3027 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
3028 [ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_DELETE;
3029 IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_DELETE] THEN
3030 ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN
3031 ASM_SIMP_TAC[REAL_LT_DIV; REAL_SUB_LT; REAL_LT_01; COND_ID];
3032 REWRITE_TAC[REAL_SUB_LT] THEN DISCH_TAC] THEN
3033 X_GEN_TAC `j:real^N->bool` THEN STRIP_TAC THEN
3034 ASM_CASES_TAC `a j dot (w:real^N) < a(j:real^N->bool) dot y` THENL
3035 [ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_INF_LE_FINITE; REAL_SUB_LT;
3036 FINITE_IMAGE; FINITE_DELETE; IMAGE_EQ_EMPTY] THEN
3037 REWRITE_TAC[EXISTS_IN_IMAGE] THEN EXISTS_TAC `j:real^N->bool` THEN
3038 ASM_REWRITE_TAC[IN_DELETE; REAL_LE_REFL];
3039 MATCH_MP_TAC(REAL_ARITH `&0 <= --x /\ &0 < y ==> x <= y`) THEN
3040 ASM_SIMP_TAC[REAL_SUB_LT; GSYM REAL_MUL_RNEG; REAL_LE_MUL_EQ] THEN
3041 ASM_REAL_ARITH_TAC];
3043 ABBREV_TAC `c:real^N = (&1 - t) % w + t % y` THEN
3044 SUBGOAL_THEN `y:real^N = (&1 - inv t) % w + inv(t) % c` SUBST1_TAC THENL
3045 [EXPAND_TAC "c" THEN
3046 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
3047 ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ;
3048 REAL_FIELD `&0 < x ==> inv x * (&1 - x) = inv x - &1`] THEN
3051 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
3052 CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN
3053 ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
3054 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
3055 [EXPAND_TAC "c" THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
3056 ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RING;
3058 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC RAND_CONV [t]) THEN
3059 REWRITE_TAC[IN_INTER; IN_INTERS] THEN CONJ_TAC THENL
3060 [EXPAND_TAC "c" THEN
3061 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
3062 ASM_SIMP_TAC[HULL_INC];
3064 X_GEN_TAC `j:real^N->bool` THEN DISCH_TAC THEN
3065 FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC o C MATCH_MP
3066 (ASSUME `(j:real^N->bool) IN f`)) THEN
3067 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
3068 ASM_CASES_TAC `j:real^N->bool = h` THEN ASM_SIMP_TAC[REAL_EQ_IMP_LE] THEN
3069 EXPAND_TAC "c" THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
3070 REWRITE_TAC[REAL_ARITH
3071 `(&1 - t) * x + t * y <= z <=> t * (y - x) <= z - x`] THEN
3074 X_GEN_TAC `c:real^N->bool` THEN EQ_TAC THENL
3075 [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[]] THEN
3076 REWRITE_TAC[facet_of] THEN STRIP_TAC THEN
3077 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
3078 SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL
3079 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN
3080 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
3081 DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN
3082 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3083 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3084 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3085 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
3086 GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN
3087 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
3088 SUBGOAL_THEN `~(c:real^N->bool = s)` ASSUME_TAC THENL
3089 [ASM_MESON_TAC[INT_ARITH`~(i:int = i - &1)`]; ALL_TAC] THEN
3090 SUBGOAL_THEN `~((x:real^N) IN relative_interior s)` ASSUME_TAC THENL
3091 [UNDISCH_TAC `~(c:real^N->bool = s)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN
3092 DISCH_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN
3093 EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN
3096 SUBGOAL_THEN `(x:real^N) IN s` MP_TAC THENL
3097 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o MATCH_MP
3098 FACE_OF_IMP_SUBSET) THEN
3099 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET];
3101 ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3102 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN
3103 REWRITE_TAC[IN_INTER; IN_INTERS] THEN STRIP_TAC THEN
3104 REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
3105 X_GEN_TAC `i:real^N->bool` THEN REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN
3106 ASM_REWRITE_TAC[] THEN
3107 SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot x = b i` ASSUME_TAC THENL
3108 [MATCH_MP_TAC(REAL_ARITH `x <= y /\ ~(x < y) ==> x = y`) THEN
3109 ASM_REWRITE_TAC[] THEN UNDISCH_THEN
3110 `!t:real^N->bool. t IN f ==> x IN t` (MP_TAC o SPEC `i:real^N->bool`) THEN
3111 ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o C MATCH_MP
3112 (ASSUME `(i:real^N->bool) IN f`)) THEN SET_TAC[];
3114 SUBGOAL_THEN `c SUBSET (s INTER {x:real^N | a(i:real^N->bool) dot x = b i})`
3116 [MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN
3117 ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THEN
3118 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[] THEN
3119 REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN
3120 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM];
3122 SUBGOAL_THEN `c face_of (s INTER {x:real^N | a(i:real^N->bool) dot x = b i})`
3124 [MP_TAC(ISPECL [`c:real^N->bool`; `s:real^N->bool`;
3125 `s INTER {x:real^N | a(i:real^N->bool) dot x = b i}`]
3127 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[];
3129 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3131 `aff_dim(c:real^N->bool) <
3132 aff_dim(s INTER {x:real^N | a(i:real^N->bool) dot x = b i})`
3134 [MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN
3135 ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE];
3136 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[INT_LT_REFL]]);;
3138 let FACE_OF_POLYHEDRON_SUBSET_EXPLICIT = prove
3139 (`!s:real^N->bool f a b.
3141 s = affine hull s INTER INTERS f /\
3142 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
3143 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
3144 ==> !c. c face_of s /\ ~(c = {}) /\ ~(c = s)
3145 ==> ?h. h IN f /\ c SUBSET (s INTER {x | a h dot x = b h})`,
3146 REPEAT GEN_TAC THEN ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL
3147 [DISCH_THEN(MP_TAC o SYM o CONJUNCT1 o CONJUNCT2) THEN
3148 ASM_REWRITE_TAC[INTERS_0; INTER_UNIV; AFFINE_HULL_EQ] THEN
3149 MESON_TAC[FACE_OF_AFFINE_TRIVIAL];
3151 DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN
3152 DISCH_THEN(ASSUME_TAC o MATCH_MP FACET_OF_POLYHEDRON_EXPLICIT) THEN
3153 REPEAT STRIP_TAC THEN
3154 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
3155 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
3156 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
3157 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3158 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3160 FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN
3163 h IN f ==> (s INTER {x:real^N | a h dot x = b h}) face_of s`
3165 [REPEAT STRIP_TAC THEN
3166 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN CONJ_TAC THENL
3167 [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN
3168 REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3169 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3170 X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN
3171 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
3172 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN
3173 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
3174 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
3175 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
3177 SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL
3178 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN
3179 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
3180 DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN
3181 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3182 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3183 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3184 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
3185 GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN
3186 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
3187 SUBGOAL_THEN `~((x:real^N) IN relative_interior s)` ASSUME_TAC THENL
3188 [UNDISCH_TAC `~(c:real^N->bool = s)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN
3189 DISCH_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN
3190 EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN
3193 SUBGOAL_THEN `(x:real^N) IN s` MP_TAC THENL
3194 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o MATCH_MP
3195 FACE_OF_IMP_SUBSET) THEN
3196 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET];
3198 ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3199 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN
3200 REWRITE_TAC[IN_INTER; IN_INTERS] THEN STRIP_TAC THEN
3201 REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
3202 X_GEN_TAC `i:real^N->bool` THEN REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN
3203 ASM_REWRITE_TAC[] THEN
3204 SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot x = b i` ASSUME_TAC THENL
3205 [MATCH_MP_TAC(REAL_ARITH `x <= y /\ ~(x < y) ==> x = y`) THEN
3206 ASM_REWRITE_TAC[] THEN UNDISCH_THEN
3207 `!t:real^N->bool. t IN f ==> x IN t` (MP_TAC o SPEC `i:real^N->bool`) THEN
3208 ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o C MATCH_MP
3209 (ASSUME `(i:real^N->bool) IN f`)) THEN SET_TAC[];
3211 MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN
3212 ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THEN
3213 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[] THEN
3214 REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN
3215 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]);;
3217 let FACE_OF_POLYHEDRON_EXPLICIT = prove
3218 (`!s:real^N->bool f a b.
3220 s = affine hull s INTER INTERS f /\
3221 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
3222 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
3223 ==> !c. c face_of s /\ ~(c = {}) /\ ~(c = s)
3224 ==> c = INTERS {s INTER {x | a h dot x = b h} |h|
3226 c SUBSET (s INTER {x | a h dot x = b h})}`,
3228 (`!t s. (!a. P a ==> t SUBSET s INTER INTERS {f x | P x})
3229 ==> t SUBSET INTERS {s INTER f x | P x}`,
3230 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
3231 REWRITE_TAC[INTERS_IMAGE] THEN SET_TAC[]) in
3233 DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN
3234 DISCH_THEN(ASSUME_TAC o MATCH_MP FACET_OF_POLYHEDRON_EXPLICIT) THEN
3235 REPEAT STRIP_TAC THEN
3236 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
3237 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
3238 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
3239 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3240 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3242 FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN
3245 h IN f ==> (s INTER {x:real^N | a h dot x = b h}) face_of s`
3247 [REPEAT STRIP_TAC THEN
3248 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN CONJ_TAC THENL
3249 [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN
3250 REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3251 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3252 X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN
3253 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
3254 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN
3255 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
3256 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
3257 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
3259 SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL
3260 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN
3261 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN
3262 X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN
3263 SUBGOAL_THEN `(z:real^N) IN s` ASSUME_TAC THENL
3264 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN
3265 MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN
3268 MATCH_MP_TAC FACE_OF_EQ THEN EXISTS_TAC `s:real^N->bool` THEN
3269 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
3270 [MATCH_MP_TAC FACE_OF_INTERS THEN ASM_SIMP_TAC[FORALL_IN_GSPEC] THEN
3271 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[IMAGE_EQ_EMPTY] THEN
3272 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
3273 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3274 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3275 FACE_OF_POLYHEDRON_SUBSET_EXPLICIT) THEN
3276 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL[FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
3277 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
3280 `{s INTER {x | a(h:real^N->bool) dot x = b h} |h|
3281 h IN f /\ c SUBSET (s INTER {x:real^N | a h dot x = b h})} =
3282 {s INTER {x | a(h:real^N->bool) dot x = b h} |h|
3283 h IN f /\ z IN s INTER {x:real^N | a h dot x = b h}}`
3285 [MATCH_MP_TAC(SET_RULE
3286 `(!x. P x <=> Q x) ==> {f x | P x} = {f x | Q x}`) THEN
3287 X_GEN_TAC `h:real^N->bool` THEN EQ_TAC THEN STRIP_TAC THEN
3288 ASM_REWRITE_TAC[] THENL
3289 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN
3290 MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN
3292 MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN
3293 ASM_SIMP_TAC[] THEN ASM SET_TAC[]];
3295 REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
3296 EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
3298 `?e. &0 < e /\ !h. h IN f /\ a(h:real^N->bool) dot z < b h
3299 ==> ball(z,e) SUBSET {w:real^N | a h dot w < b h}`
3300 (CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THENL
3301 [REWRITE_TAC[SET_RULE
3302 `(!h. P h ==> s SUBSET t h) <=> s SUBSET INTERS (IMAGE t {h | P h})`] THEN
3303 MATCH_MP_TAC(MESON[OPEN_CONTAINS_BALL]
3304 `open s /\ x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s`) THEN
3305 SIMP_TAC[IN_INTERS; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
3306 MATCH_MP_TAC OPEN_INTERS THEN
3307 ASM_SIMP_TAC[FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_RESTRICT] THEN
3308 REWRITE_TAC[OPEN_HALFSPACE_LT];
3310 ASM_REWRITE_TAC[IN_RELATIVE_INTERIOR] THEN
3311 ASM_SIMP_TAC[IN_INTERS; FORALL_IN_GSPEC; IN_ELIM_THM; IN_INTER] THEN
3312 EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN
3313 MATCH_MP_TAC lemma THEN X_GEN_TAC `i:real^N->bool` THEN STRIP_TAC THEN
3314 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [th]) THEN
3315 MATCH_MP_TAC(SET_RULE
3316 `ae SUBSET as /\ ae SUBSET hs /\
3317 b INTER hs SUBSET fs
3318 ==> (b INTER ae) SUBSET (as INTER fs) INTER hs`) THEN
3319 REPEAT CONJ_TAC THENL
3320 [MATCH_MP_TAC HULL_MONO THEN
3321 REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_GSPEC] THEN ASM SET_TAC[];
3322 SIMP_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN
3323 REWRITE_TAC[FORALL_IN_GSPEC] THEN X_GEN_TAC `j:real^N->bool` THEN
3324 STRIP_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN
3325 REWRITE_TAC[AFFINE_HYPERPLANE] THEN
3326 REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_GSPEC] THEN ASM SET_TAC[];
3328 REWRITE_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN
3329 X_GEN_TAC `j:real^N->bool` THEN DISCH_TAC THEN
3330 SUBGOAL_THEN `(a:(real^N->bool)->real^N) j dot z <= b j` MP_TAC THENL
3331 [ASM SET_TAC[]; REWRITE_TAC[REAL_LE_LT]] THEN
3332 STRIP_TAC THENL [ASM SET_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN
3333 MATCH_MP_TAC(SET_RULE
3334 `(?s. s IN f /\ s SUBSET t) ==> u INTER INTERS f SUBSET t`) THEN
3335 REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `j:real^N->bool` THEN
3336 ASM SET_TAC[REAL_LE_REFL]);;
3338 (* ------------------------------------------------------------------------- *)
3339 (* More general corollaries from the explicit representation. *)
3340 (* ------------------------------------------------------------------------- *)
3342 let FACET_OF_POLYHEDRON = prove
3343 (`!s:real^N->bool c.
3344 polyhedron s /\ c facet_of s
3345 ==> ?a b. ~(a = vec 0) /\
3346 s SUBSET {x | a dot x <= b} /\
3347 c = s INTER {x | a dot x = b}`,
3348 REPEAT STRIP_TAC THEN FIRST_ASSUM
3349 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3350 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
3351 [RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3352 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3354 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3355 `b:(real^N->bool)->real`] THEN
3357 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3358 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3359 FACET_OF_POLYHEDRON_EXPLICIT) THEN
3360 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3361 DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3362 DISCH_THEN(X_CHOOSE_THEN `i:real^N->bool` STRIP_ASSUME_TAC) THEN
3363 EXISTS_TAC `(a:(real^N->bool)->real^N) i` THEN
3364 EXISTS_TAC `(b:(real^N->bool)->real) i` THEN ASM_SIMP_TAC[] THEN
3365 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
3366 MATCH_MP_TAC(SET_RULE `t SUBSET u ==> (s INTER t) SUBSET u`) THEN
3367 MATCH_MP_TAC(SET_RULE `t IN f ==> INTERS f SUBSET t`) THEN ASM_MESON_TAC[]);;
3369 let FACE_OF_POLYHEDRON = prove
3370 (`!s:real^N->bool c.
3371 polyhedron s /\ c face_of s /\ ~(c = {}) /\ ~(c = s)
3372 ==> c = INTERS {f | f facet_of s /\ c SUBSET f}`,
3373 REPEAT STRIP_TAC THEN FIRST_ASSUM
3374 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3375 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3376 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3378 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3379 `b:(real^N->bool)->real`] THEN
3381 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3382 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3383 FACET_OF_POLYHEDRON_EXPLICIT) THEN
3384 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3385 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
3386 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3387 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3388 FACE_OF_POLYHEDRON_EXPLICIT) THEN
3389 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3390 DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3391 DISCH_THEN(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
3392 AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
3393 X_GEN_TAC `h:real^N->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[]);;
3395 let FACE_OF_POLYHEDRON_SUBSET_FACET = prove
3396 (`!s:real^N->bool c.
3397 polyhedron s /\ c face_of s /\ ~(c = {}) /\ ~(c = s)
3398 ==> ?f. f facet_of s /\ c SUBSET f`,
3399 REPEAT STRIP_TAC THEN
3400 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
3401 MP_TAC(ISPECL [`s:real^N->bool`; `c:real^N->bool`] FACE_OF_POLYHEDRON) THEN
3402 ASM_CASES_TAC `{f:real^N->bool | f facet_of s /\ c SUBSET f} = {}` THEN
3405 let EXPOSED_FACE_OF_POLYHEDRON = prove
3406 (`!s f:real^N->bool. polyhedron s ==> (f exposed_face_of s <=> f face_of s)`,
3407 REPEAT STRIP_TAC THEN EQ_TAC THENL [SIMP_TAC[exposed_face_of]; ALL_TAC] THEN
3408 DISCH_TAC THEN ASM_CASES_TAC `f:real^N->bool = {}` THEN
3409 ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF] THEN
3410 ASM_CASES_TAC `f:real^N->bool = s` THEN
3411 ASM_SIMP_TAC[EXPOSED_FACE_OF_REFL; POLYHEDRON_IMP_CONVEX] THEN
3412 MP_TAC(ISPECL [`s:real^N->bool`; `f:real^N->bool`] FACE_OF_POLYHEDRON) THEN
3413 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
3414 MATCH_MP_TAC EXPOSED_FACE_OF_INTERS THEN
3415 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; FORALL_IN_GSPEC] THEN
3416 ASM_SIMP_TAC[FACE_OF_POLYHEDRON_SUBSET_FACET; IN_ELIM_THM] THEN
3417 ASM_SIMP_TAC[exposed_face_of; FACET_OF_IMP_FACE_OF] THEN
3418 ASM_MESON_TAC[FACET_OF_POLYHEDRON]);;
3420 let FACE_OF_POLYHEDRON_POLYHEDRON = prove
3421 (`!s:real^N->bool c. polyhedron s /\ c face_of s ==> polyhedron c`,
3422 REPEAT STRIP_TAC THEN FIRST_ASSUM
3423 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3424 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3425 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3427 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3428 `b:(real^N->bool)->real`] THEN
3430 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3431 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3432 FACE_OF_POLYHEDRON_EXPLICIT) THEN
3433 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3434 DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3435 ASM_CASES_TAC `c:real^N->bool = {}` THEN
3436 ASM_REWRITE_TAC[POLYHEDRON_EMPTY] THEN
3437 ASM_CASES_TAC `c:real^N->bool = s` THEN ASM_REWRITE_TAC[] THEN
3438 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC POLYHEDRON_INTERS THEN
3439 REWRITE_TAC[FORALL_IN_GSPEC] THEN
3440 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
3441 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT] THEN
3442 REPEAT STRIP_TAC THEN REWRITE_TAC[IMAGE_ID] THEN
3443 MATCH_MP_TAC POLYHEDRON_INTER THEN
3444 ASM_REWRITE_TAC[POLYHEDRON_HYPERPLANE]);;
3446 let FINITE_POLYHEDRON_FACES = prove
3447 (`!s:real^N->bool. polyhedron s ==> FINITE {f | f face_of s}`,
3448 REPEAT STRIP_TAC THEN FIRST_ASSUM
3449 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3450 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3451 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3453 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3454 `b:(real^N->bool)->real`] THEN
3456 MATCH_MP_TAC(MESON[FINITE_DELETE]
3457 `!a b. FINITE (s DELETE a DELETE b) ==> FINITE s`) THEN
3458 MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `s:real^N->bool`] THEN
3459 MATCH_MP_TAC FINITE_SUBSET THEN
3461 `{INTERS {s INTER {x:real^N | a(h:real^N->bool) dot x = b h} | h | h IN f'}
3462 |f'| f' SUBSET f}` THEN
3463 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SIMPLE_IMAGE_GEN] THEN
3464 ASM_SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE] THEN
3465 GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[IN_DELETE; IN_ELIM_THM] THEN
3466 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3467 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3468 FACE_OF_POLYHEDRON_EXPLICIT) THEN
3469 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3470 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `c:real^N->bool` THEN
3471 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
3472 DISCH_TAC THEN EXISTS_TAC
3474 h IN f /\ c SUBSET s INTER {x:real^N | a h dot x = b h}}` THEN
3475 CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
3476 ASM_REWRITE_TAC[IN_ELIM_THM] THEN FIRST_ASSUM ACCEPT_TAC);;
3478 let FINITE_POLYHEDRON_EXPOSED_FACES = prove
3479 (`!s:real^N->bool. polyhedron s ==> FINITE {f | f exposed_face_of s}`,
3480 SIMP_TAC[EXPOSED_FACE_OF_POLYHEDRON; FINITE_POLYHEDRON_FACES]);;
3482 let FINITE_POLYHEDRON_EXTREME_POINTS = prove
3483 (`!s:real^N->bool. polyhedron s ==> FINITE {v | v extreme_point_of s}`,
3484 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
3485 ONCE_REWRITE_TAC[SET_RULE `{v} face_of s <=> {v} IN {f | f face_of s}`] THEN
3486 MATCH_MP_TAC FINITE_FINITE_PREIMAGE THEN
3487 ASM_SIMP_TAC[FINITE_POLYHEDRON_FACES] THEN X_GEN_TAC `f:real^N->bool` THEN
3488 DISCH_TAC THEN ASM_CASES_TAC `!a:real^N. ~({a} = f)` THEN
3489 ASM_REWRITE_TAC[EMPTY_GSPEC; FINITE_EMPTY] THEN
3490 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
3491 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
3492 GEN_TAC THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
3493 REWRITE_TAC[SET_RULE `{v | {v} = {a}} = {a}`; FINITE_SING]);;
3495 let FINITE_POLYHEDRON_FACETS = prove
3496 (`!s:real^N->bool. polyhedron s ==> FINITE {f | f facet_of s}`,
3497 REWRITE_TAC[facet_of] THEN ONCE_REWRITE_TAC[SET_RULE
3498 `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN
3499 SIMP_TAC[FINITE_RESTRICT; FINITE_POLYHEDRON_FACES]);;
3501 let RELATIVE_INTERIOR_OF_POLYHEDRON = prove
3504 ==> relative_interior s = s DIFF UNIONS {f | f facet_of s}`,
3505 REPEAT STRIP_TAC THEN FIRST_ASSUM
3506 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3507 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
3508 [RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3509 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3511 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3512 `b:(real^N->bool)->real`] THEN
3514 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3515 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3516 FACET_OF_POLYHEDRON_EXPLICIT) THEN
3517 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3518 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3519 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3520 ASM_REWRITE_TAC[] THEN
3521 ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN
3522 ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN
3523 ASM_REWRITE_TAC[] THEN
3524 MATCH_MP_TAC(SET_RULE
3525 `(!x. x IN s ==> P x \/ x IN t) /\ (!x. x IN t ==> ~P x)
3526 ==> {x | x IN s /\ P x} = s DIFF t`) THEN
3527 REWRITE_TAC[FORALL_IN_UNIONS] THEN
3528 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
3530 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
3531 REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN
3532 REWRITE_TAC[LEFT_AND_EXISTS_THM; TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
3533 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3534 ASM_REWRITE_TAC[UNWIND_THM2; IN_ELIM_THM; IN_INTER] THEN
3535 MATCH_MP_TAC(SET_RULE
3536 `(!x. P x ==> Q x \/ R x) ==> (!x. P x ==> Q x) \/ (?x. P x /\ R x)`) THEN
3537 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
3538 REWRITE_TAC[GSYM REAL_LE_LT] THEN
3539 SUBGOAL_THEN `(x:real^N) IN INTERS f` MP_TAC THENL
3540 [ASM SET_TAC[]; ALL_TAC] THEN
3541 REWRITE_TAC[IN_INTERS] THEN
3542 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN
3543 SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` MP_TAC THENL
3544 [ASM_MESON_TAC[]; ASM_REWRITE_TAC[] THEN SET_TAC[]];
3545 X_GEN_TAC `h:real^N->bool` THEN
3546 DISCH_THEN(X_CHOOSE_THEN `g:real^N->bool` STRIP_ASSUME_TAC) THEN
3547 X_GEN_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
3548 ASM_MESON_TAC[REAL_LT_REFL]]);;
3550 let RELATIVE_BOUNDARY_OF_POLYHEDRON = prove
3553 ==> s DIFF relative_interior s = UNIONS {f | f facet_of s}`,
3554 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[RELATIVE_INTERIOR_OF_POLYHEDRON] THEN
3555 MATCH_MP_TAC(SET_RULE `f SUBSET s ==> s DIFF (s DIFF f) = f`) THEN
3556 REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN
3557 MESON_TAC[FACET_OF_IMP_SUBSET; SUBSET]);;
3559 let RELATIVE_FRONTIER_OF_POLYHEDRON = prove
3561 polyhedron s ==> relative_frontier s = UNIONS {f | f facet_of s}`,
3562 SIMP_TAC[relative_frontier; POLYHEDRON_IMP_CLOSED; CLOSURE_CLOSED] THEN
3563 REWRITE_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON]);;
3565 let RELATIVE_FRONTIER_OF_POLYHEDRON_ALT = prove
3568 ==> relative_frontier s = UNIONS {f | f face_of s /\ ~(f = s)}`,
3569 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
3570 [ASM_SIMP_TAC[RELATIVE_FRONTIER_OF_POLYHEDRON; facet_of] THEN
3571 MATCH_MP_TAC SUBSET_UNIONS THEN SIMP_TAC[SUBSET; IN_ELIM_THM] THEN
3572 MESON_TAC[INT_ARITH `~(f - &1:int = f)`];
3573 REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN
3574 MESON_TAC[REWRITE_RULE[SUBSET] FACE_OF_SUBSET_RELATIVE_FRONTIER]]);;
3576 let FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT = prove
3577 (`!s:real^N->bool f a b.
3579 s = affine hull s INTER INTERS f /\
3580 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
3581 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
3582 ==> !h1 h2. h1 IN f /\ h2 IN f /\
3583 s INTER {x | a h1 dot x = b h1} =
3584 s INTER {x | a h2 dot x = b h2}
3586 REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
3587 [ASM_REWRITE_TAC[AFFINE_HULL_EMPTY; INTER_EMPTY; PSUBSET_IRREFL] THEN
3588 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
3589 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
3590 ASM_MESON_TAC[SET_RULE `~(s = {}) ==> {} PSUBSET s`];
3592 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
3593 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3594 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3596 SUBGOAL_THEN `~(relative_interior s:real^N->bool = {})` MP_TAC THENL
3597 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYHEDRON_IMP_CONVEX];
3598 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
3599 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC)] THEN
3600 DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3602 [`s:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3603 `b:(real^N->bool)->real`] RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3605 [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN
3606 REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
3607 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3608 FIRST_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`) THEN
3609 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[PSUBSET_ALT]] THEN
3610 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `x:real^N` MP_TAC)) THEN
3611 REWRITE_TAC[IN_INTER; IN_INTERS; IN_DELETE] THEN STRIP_TAC THEN
3612 MP_TAC(ISPECL [`segment[x:real^N,z]`; `s:real^N->bool`]
3613 CONNECTED_INTER_RELATIVE_FRONTIER) THEN
3614 PURE_REWRITE_TAC[relative_frontier] THEN ANTS_TAC THENL
3615 [REWRITE_TAC[CONNECTED_SEGMENT; GSYM MEMBER_NOT_EMPTY] THEN
3616 REPEAT CONJ_TAC THENL
3617 [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; AFFINE_AFFINE_HULL;
3618 HULL_INC; AFFINE_IMP_CONVEX];
3619 EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[IN_INTER; ENDS_IN_SEGMENT];
3620 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_DIFF; ENDS_IN_SEGMENT]];
3622 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
3623 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; CLOSURE_CLOSED;
3624 LEFT_IMP_EXISTS_THM; IN_INTER] THEN
3625 X_GEN_TAC `y:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3626 DISCH_THEN(fun th -> STRIP_ASSUME_TAC(REWRITE_RULE[IN_DIFF] th) THEN
3628 ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON] THEN
3630 [`s:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3631 `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN
3633 [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[];
3634 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th])] THEN
3635 REWRITE_TAC[SET_RULE `{y | ?x. x IN s /\ y = f x} = IMAGE f s`] THEN
3636 REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_INTER] THEN
3637 DISCH_THEN(X_CHOOSE_THEN `h:real^N->bool` STRIP_ASSUME_TAC) THEN
3639 `?k:real^N->bool. k IN f /\ ~(k = h2) /\ a k dot (y:real^N) = b k`
3640 STRIP_ASSUME_TAC THENL
3641 [ASM_CASES_TAC `h:real^N->bool = h2` THENL
3642 [EXISTS_TAC `h1:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
3643 UNDISCH_TAC `s INTER {x:real^N | a(h1:real^N->bool) dot x = b h1} =
3644 s INTER {x | a h2 dot x = b h2}` THEN
3645 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[];
3649 `(a:(real^N->bool)->real^N) k dot z < b k /\ a k dot x <= b k`
3650 STRIP_ASSUME_TAC THENL [ASM_SIMP_TAC[] THEN ASM SET_TAC[]; ALL_TAC] THEN
3651 SUBGOAL_THEN `y IN segment(x:real^N,z)` MP_TAC THENL
3652 [ASM_REWRITE_TAC[IN_OPEN_SEGMENT_ALT] THEN ASM_MESON_TAC[];
3653 REWRITE_TAC[IN_SEGMENT] THEN STRIP_TAC] THEN
3654 UNDISCH_TAC `(a:(real^N->bool)->real^N) k dot y = b k` THEN
3655 ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
3656 MATCH_MP_TAC(REAL_ARITH
3657 `(&1 - u) * x <= (&1 - u) * b /\ u * y < u * b
3658 ==> ~((&1 - u) * x + u * y = b)`) THEN
3659 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LE_LMUL_EQ; REAL_SUB_LT]);;
3661 (* ------------------------------------------------------------------------- *)
3662 (* A characterization of polyhedra as having finitely many faces. *)
3663 (* ------------------------------------------------------------------------- *)
3665 let POLYHEDRON_EQ_FINITE_EXPOSED_FACES = prove
3667 polyhedron s <=> closed s /\ convex s /\ FINITE {f | f exposed_face_of s}`,
3668 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
3669 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_IMP_CONVEX;
3670 FINITE_POLYHEDRON_EXPOSED_FACES] THEN
3671 ASM_CASES_TAC `s:real^N->bool = {}` THEN
3672 ASM_REWRITE_TAC[POLYHEDRON_EMPTY] THEN
3674 `f = {h:real^N->bool | h exposed_face_of s /\ ~(h = {}) /\ ~(h = s)}` THEN
3675 SUBGOAL_THEN `FINITE(f:(real^N->bool)->bool)` ASSUME_TAC THENL
3676 [EXPAND_TAC "f" THEN
3677 ONCE_REWRITE_TAC[SET_RULE
3678 `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN
3679 ASM_SIMP_TAC[FINITE_RESTRICT];
3685 ?a b. ~(a = vec 0) /\
3686 s SUBSET {x | a dot x <= b} /\
3687 h = s INTER {x | a dot x = b}`
3689 [EXPAND_TAC "f" THEN REWRITE_TAC[EXPOSED_FACE_OF; IN_ELIM_THM] THEN
3692 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; FORALL_AND_THM;
3693 TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
3694 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3695 DISCH_THEN(X_CHOOSE_THEN `a:(real^N->bool)->real^N` MP_TAC) THEN
3696 DISCH_THEN(X_CHOOSE_THEN `b:(real^N->bool)->real` STRIP_ASSUME_TAC) THEN
3698 `s = affine hull s INTER
3699 INTERS {{x:real^N | a(h:real^N->bool) dot x <= b h} | h IN f}`
3702 MATCH_MP_TAC POLYHEDRON_INTER THEN REWRITE_TAC[POLYHEDRON_AFFINE_HULL] THEN
3703 MATCH_MP_TAC POLYHEDRON_INTERS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
3704 ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; POLYHEDRON_HALFSPACE_LE]] THEN
3705 MATCH_MP_TAC SUBSET_ANTISYM THEN
3706 REWRITE_TAC[SUBSET_INTER; HULL_SUBSET;
3707 SET_RULE `s SUBSET INTERS f <=> !h. h IN f ==> s SUBSET h`] THEN
3708 ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN
3709 REWRITE_TAC[SUBSET; IN_INTER; IN_INTERS; FORALL_IN_GSPEC] THEN
3710 X_GEN_TAC `p:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
3711 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3712 SUBGOAL_THEN `~(relative_interior(s:real^N->bool) = {})` MP_TAC THENL
3713 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY];
3714 GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN
3715 DISCH_THEN(X_CHOOSE_TAC `c:real^N`)] THEN
3717 `?x:real^N. x IN segment[c,p] /\ x IN (s DIFF relative_interior s)`
3719 [MP_TAC(ISPEC `segment[c:real^N,p]` CONNECTED_OPEN_IN) THEN
3720 REWRITE_TAC[CONNECTED_SEGMENT; NOT_EXISTS_THM] THEN
3721 DISCH_THEN(MP_TAC o SPECL
3722 [`segment[c:real^N,p] INTER relative_interior s`;
3723 `segment[c:real^N,p] INTER (UNIV DIFF s)`]) THEN
3724 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
3725 REWRITE_TAC[IN_DIFF; NOT_EXISTS_THM] THEN DISCH_TAC THEN
3726 REPEAT CONJ_TAC THENL
3727 [MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN
3728 EXISTS_TAC `affine hull s:real^N->bool` THEN
3729 SIMP_TAC[OPEN_IN_RELATIVE_INTERIOR; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY;
3730 OPEN_IN_SUBTOPOLOGY_REFL; SUBSET_UNIV; OPEN_IN_INTER;
3731 TOPSPACE_EUCLIDEAN] THEN
3732 REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN
3733 SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL] THEN
3734 ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN
3735 ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; HULL_INC; SUBSET];
3736 REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC `(:real^N) DIFF s` THEN
3737 ASM_REWRITE_TAC[GSYM closed];
3738 MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN ASM SET_TAC[];
3739 MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN SET_TAC[];
3740 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
3741 ASM_MESON_TAC[ENDS_IN_SEGMENT];
3742 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_DIFF; IN_INTER; IN_UNIV] THEN
3743 ASM_MESON_TAC[ENDS_IN_SEGMENT]];
3744 REWRITE_TAC[IN_SEGMENT; LEFT_AND_EXISTS_THM] THEN
3745 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3746 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
3747 DISCH_THEN(X_CHOOSE_THEN `l:real` MP_TAC) THEN
3748 ASM_CASES_TAC `l = &0` THEN
3749 ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_MUL_LZERO; REAL_SUB_RZERO;
3750 VECTOR_MUL_LID; IN_DIFF] THEN
3751 ASM_CASES_TAC `l = &1` THEN
3752 ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO; REAL_SUB_REFL;
3753 VECTOR_MUL_LID; IN_DIFF] THEN
3754 ASM_REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC] THEN
3755 ABBREV_TAC `x:real^N = (&1 - l) % c + l % p` THEN
3756 SUBGOAL_THEN `?h:real^N->bool. h IN f /\ x IN h` STRIP_ASSUME_TAC THENL
3757 [MP_TAC(ISPECL [`s:real^N->bool`; `(&1 - l) % c + l % p:real^N`]
3758 SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER) THEN
3759 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN
3760 DISCH_THEN(X_CHOOSE_THEN `d:real^N` STRIP_ASSUME_TAC) THEN
3762 EXISTS_TAC `s INTER {y:real^N | d dot y = d dot x}` THEN
3763 ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL
3764 [MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN
3765 ASM_SIMP_TAC[real_ge; REWRITE_RULE[SUBSET] CLOSURE_SUBSET];
3767 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN
3768 DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN
3769 ASM_MESON_TAC[SUBSET; REAL_LT_REFL; RELATIVE_INTERIOR_SUBSET]];
3771 SUBGOAL_THEN `{y:real^N | a(h:real^N->bool) dot y = b h} face_of
3772 {y | a h dot y <= b h}`
3774 [MATCH_MP_TAC(MESON[]
3775 `(t INTER s) face_of t /\ t INTER s = s ==> s face_of t`) THEN
3777 [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
3778 REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_LE];
3779 SET_TAC[REAL_LE_REFL]];
3781 REWRITE_TAC[face_of] THEN
3782 DISCH_THEN(MP_TAC o SPECL [`c:real^N`; `p:real^N`; `x:real^N`] o
3783 CONJUNCT2 o CONJUNCT2) THEN
3784 ASM_SIMP_TAC[IN_ELIM_THM; NOT_IMP; GSYM CONJ_ASSOC] THEN
3785 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
3786 RELATIVE_INTERIOR_SUBSET)) THEN
3787 REPEAT CONJ_TAC THENL
3790 REWRITE_TAC[IN_SEGMENT] THEN ASM SET_TAC[];
3792 MP_TAC(ISPECL [`s:real^N->bool`; `h:real^N->bool`; `s:real^N->bool`]
3793 SUBSET_OF_FACE_OF) THEN
3796 let POLYHEDRON_EQ_FINITE_FACES = prove
3799 closed s /\ convex s /\ FINITE {f | f face_of s}`,
3800 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
3801 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_IMP_CONVEX;
3802 FINITE_POLYHEDRON_FACES] THEN
3803 REWRITE_TAC[POLYHEDRON_EQ_FINITE_EXPOSED_FACES] THEN
3804 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FINITE_SUBSET THEN
3805 EXISTS_TAC `{f:real^N->bool | f face_of s}` THEN
3806 ASM_REWRITE_TAC[] THEN
3807 SIMP_TAC[SUBSET; IN_ELIM_THM; exposed_face_of]);;
3809 let POLYHEDRON_TRANSLATION_EQ = prove
3810 (`!a s. polyhedron (IMAGE (\x:real^N. a + x) s) <=> polyhedron s`,
3811 REPEAT STRIP_TAC THEN REWRITE_TAC[POLYHEDRON_EQ_FINITE_FACES] THEN
3812 REWRITE_TAC[CLOSED_TRANSLATION_EQ] THEN AP_TERM_TAC THEN
3813 REWRITE_TAC[CONVEX_TRANSLATION_EQ] THEN AP_TERM_TAC THEN
3814 MP_TAC(ISPEC `IMAGE (\x:real^N. a + x)` QUANTIFY_SURJECTION_THM) THEN
3815 REWRITE_TAC[SURJECTIVE_IMAGE; EXISTS_REFL;
3816 VECTOR_ARITH `a + x:real^N = y <=> x = y - a`] THEN
3817 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
3818 REWRITE_TAC[FACE_OF_TRANSLATION_EQ] THEN
3819 MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN
3820 MATCH_MP_TAC(MESON[]
3821 `(!x y. Q x y ==> R x y) ==> (!x y. P x /\ P y /\ Q x y ==> R x y)`) THEN
3822 REWRITE_TAC[INJECTIVE_IMAGE] THEN VECTOR_ARITH_TAC);;
3824 add_translation_invariants [POLYHEDRON_TRANSLATION_EQ];;
3826 let POLYHEDRON_LINEAR_IMAGE_EQ = prove
3827 (`!f:real^M->real^N s.
3828 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
3829 ==> (polyhedron (IMAGE f s) <=> polyhedron s)`,
3830 REPEAT STRIP_TAC THEN REWRITE_TAC[POLYHEDRON_EQ_FINITE_FACES] THEN
3832 [ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]; ALL_TAC] THEN
3833 BINOP_TAC THENL [ASM_MESON_TAC[CONVEX_LINEAR_IMAGE_EQ]; ALL_TAC] THEN
3834 MP_TAC(ISPEC `IMAGE (f:real^M->real^N)` QUANTIFY_SURJECTION_THM) THEN
3835 ASM_REWRITE_TAC[SURJECTIVE_IMAGE] THEN
3836 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
3837 MP_TAC(ISPEC `f:real^M->real^N` FACE_OF_LINEAR_IMAGE) THEN
3838 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
3839 MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN
3840 FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [GSYM INJECTIVE_IMAGE]) THEN
3841 ASM_REWRITE_TAC[IMP_CONJ]);;
3843 add_linear_invariants [POLYHEDRON_LINEAR_IMAGE_EQ];;
3845 let POLYHEDRON_NEGATIONS = prove
3846 (`!s:real^N->bool. polyhedron s ==> polyhedron(IMAGE (--) s)`,
3847 GEN_TAC THEN MATCH_MP_TAC EQ_IMP THEN CONV_TAC SYM_CONV THEN
3848 MATCH_MP_TAC POLYHEDRON_LINEAR_IMAGE_EQ THEN
3849 REWRITE_TAC[VECTOR_ARITH `--x:real^N = y <=> x = --y`; EXISTS_REFL] THEN
3850 REWRITE_TAC[LINEAR_NEGATION] THEN VECTOR_ARITH_TAC);;
3852 (* ------------------------------------------------------------------------- *)
3853 (* Relation between polytopes and polyhedra. *)
3854 (* ------------------------------------------------------------------------- *)
3856 let POLYTOPE_EQ_BOUNDED_POLYHEDRON = prove
3857 (`!s:real^N->bool. polytope s <=> polyhedron s /\ bounded s`,
3858 GEN_TAC THEN EQ_TAC THENL
3859 [SIMP_TAC[FINITE_POLYTOPE_FACES; POLYHEDRON_EQ_FINITE_FACES;
3860 POLYTOPE_IMP_CLOSED; POLYTOPE_IMP_CONVEX; POLYTOPE_IMP_BOUNDED];
3861 STRIP_TAC THEN REWRITE_TAC[polytope] THEN
3862 EXISTS_TAC `{v:real^N | v extreme_point_of s}` THEN
3863 ASM_SIMP_TAC[FINITE_POLYHEDRON_EXTREME_POINTS] THEN
3864 MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
3865 ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; POLYHEDRON_IMP_CLOSED;
3866 POLYHEDRON_IMP_CONVEX]]);;
3868 let POLYTOPE_INTER = prove
3869 (`!s t. polytope s /\ polytope t ==> polytope(s INTER t)`,
3870 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER; BOUNDED_INTER]);;
3872 let POLYTOPE_INTER_POLYHEDRON = prove
3873 (`!s t:real^N->bool. polytope s /\ polyhedron t ==> polytope(s INTER t)`,
3874 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER] THEN
3875 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
3877 let POLYHEDRON_INTER_POLYTOPE = prove
3878 (`!s t:real^N->bool. polyhedron s /\ polytope t ==> polytope(s INTER t)`,
3879 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER] THEN
3880 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
3882 let POLYTOPE_IMP_POLYHEDRON = prove
3883 (`!p. polytope p ==> polyhedron p`,
3884 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON]);;
3886 let POLYTOPE_FACET_EXISTS = prove
3887 (`!p:real^N->bool. polytope p /\ &0 < aff_dim p ==> ?f. f facet_of p`,
3888 GEN_TAC THEN ASM_CASES_TAC `p:real^N->bool = {}` THEN
3889 ASM_REWRITE_TAC[AFF_DIM_EMPTY] THEN CONV_TAC INT_REDUCE_CONV THEN
3891 MP_TAC(ISPEC `p:real^N->bool` EXTREME_POINT_EXISTS_CONVEX) THEN
3892 ASM_SIMP_TAC[POLYTOPE_IMP_COMPACT; POLYTOPE_IMP_CONVEX] THEN
3893 DISCH_THEN(X_CHOOSE_TAC `v:real^N`) THEN
3894 MP_TAC(ISPECL [`p:real^N->bool`; `{v:real^N}`]
3895 FACE_OF_POLYHEDRON_SUBSET_FACET) THEN
3896 ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
3897 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON; FACE_OF_SING; NOT_INSERT_EMPTY] THEN
3898 ASM_MESON_TAC[AFF_DIM_SING; INT_LT_REFL]);;
3900 let POLYHEDRON_INTERVAL = prove
3901 (`!a b. polyhedron(interval[a,b])`,
3902 MESON_TAC[POLYTOPE_IMP_POLYHEDRON; POLYTOPE_INTERVAL]);;
3904 let POLYHEDRON_CONVEX_HULL = prove
3905 (`!s. FINITE s ==> polyhedron(convex hull s)`,
3906 SIMP_TAC[POLYTOPE_CONVEX_HULL; POLYTOPE_IMP_POLYHEDRON]);;
3908 (* ------------------------------------------------------------------------- *)
3909 (* Polytope is union of convex hulls of facets plus any point inside. *)
3910 (* ------------------------------------------------------------------------- *)
3912 let POLYTOPE_UNION_CONVEX_HULL_FACETS = prove
3913 (`!s p:real^N->bool.
3914 polytope p /\ &0 < aff_dim p /\ ~(s = {}) /\ s SUBSET p
3915 ==> p = UNIONS { convex hull (s UNION f) | f facet_of p}`,
3916 let lemma = SET_RULE `{f x | p x} = {y | ?x. p x /\ y = f x}` in
3917 MATCH_MP_TAC SET_PROVE_CASES THEN REWRITE_TAC[] THEN
3918 X_GEN_TAC `a:real^N` THEN ONCE_REWRITE_TAC[lemma] THEN
3919 GEOM_ORIGIN_TAC `a:real^N` THEN ONCE_REWRITE_TAC[GSYM lemma] THEN
3920 X_GEN_TAC `s:real^N->bool` THEN DISCH_THEN(K ALL_TAC) THEN
3921 MP_TAC(SET_RULE `(vec 0:real^N) IN (vec 0 INSERT s)`) THEN
3922 SPEC_TAC(`(vec 0:real^N) INSERT s`,`s:real^N->bool`) THEN
3923 X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN
3924 X_GEN_TAC `p:real^N->bool` THEN STRIP_TAC THEN
3925 FIRST_ASSUM(STRIP_ASSUME_TAC o
3926 GEN_REWRITE_RULE I [POLYTOPE_EQ_BOUNDED_POLYHEDRON]) THEN
3927 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
3929 REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IMP_CONJ] THEN
3930 REWRITE_TAC[FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM] THEN
3931 X_GEN_TAC `f:real^N->bool` THEN DISCH_TAC THEN
3932 REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN
3933 EXISTS_TAC `convex hull p:real^N->bool` THEN CONJ_TAC THENL
3934 [MATCH_MP_TAC HULL_MONO THEN
3935 FIRST_ASSUM(MP_TAC o MATCH_MP FACET_OF_IMP_SUBSET) THEN ASM SET_TAC[];
3936 ASM_MESON_TAC[CONVEX_HULL_EQ; POLYHEDRON_IMP_CONVEX; SUBSET_REFL]]] THEN
3937 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN
3938 ASM_CASES_TAC `v:real^N = vec 0` THENL
3939 [MP_TAC(ISPEC `p:real^N->bool` POLYTOPE_FACET_EXISTS) THEN
3940 ASM_REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
3941 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN
3942 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[HULL_INC; IN_UNION];
3944 SUBGOAL_THEN `?t. &1 < t /\ ~((t % v:real^N) IN p)` STRIP_ASSUME_TAC THENL
3945 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
3946 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
3947 EXISTS_TAC `max (&2) ((B + &1) / norm (v:real^N))` THEN
3948 CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
3949 FIRST_X_ASSUM(MATCH_MP_TAC o
3950 GEN_REWRITE_RULE BINDER_CONV [GSYM CONTRAPOS_THM]) THEN
3951 ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_RDIV_EQ; NORM_POS_LT] THEN
3952 MATCH_MP_TAC(REAL_ARITH `a < b ==> ~(abs(max (&2) b) <= a)`) THEN
3953 ASM_SIMP_TAC[REAL_LT_DIV2_EQ; NORM_POS_LT] THEN REAL_ARITH_TAC;
3955 SUBGOAL_THEN `(vec 0:real^N) IN p` ASSUME_TAC THENL
3956 [ASM SET_TAC[]; ALL_TAC] THEN
3957 MP_TAC(ISPECL [`segment[vec 0,t % v:real^N] INTER p`; `vec 0:real^N`]
3958 DISTANCE_ATTAINS_SUP) THEN
3960 [ASM_SIMP_TAC[COMPACT_INTER_CLOSED; POLYHEDRON_IMP_CLOSED; COMPACT_SEGMENT;
3961 GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
3962 ASM_MESON_TAC[ENDS_IN_SEGMENT];
3963 REWRITE_TAC[IN_INTER; GSYM CONJ_ASSOC; IMP_CONJ] THEN
3964 REWRITE_TAC[segment; FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN
3965 REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; DIST_0] THEN
3966 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; NORM_MUL; REAL_MUL_ASSOC] THEN
3967 ASM_SIMP_TAC[REAL_LE_RMUL_EQ; NORM_POS_LT; LEFT_IMP_EXISTS_THM;
3968 REAL_ARITH `&1 < t ==> &0 < abs t`] THEN
3969 X_GEN_TAC `u:real` THEN
3970 ASM_CASES_TAC `u = &1` THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN
3971 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3972 ASM_SIMP_TAC[real_abs] THEN DISCH_TAC] THEN
3973 SUBGOAL_THEN `inv(t) <= u` ASSUME_TAC THENL
3974 [FIRST_X_ASSUM MATCH_MP_TAC THEN
3975 ASM_SIMP_TAC[REAL_INV_LE_1; REAL_LT_IMP_LE; REAL_LE_INV_EQ;
3976 REAL_ARITH `&1 < t ==> &0 <= t`] THEN
3977 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID;
3978 REAL_ARITH `&1 < t ==> ~(t = &0)`];
3980 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH `&1 < t ==> &0 < t`)) THEN
3981 SUBGOAL_THEN `&0 < u /\ u < &1` STRIP_ASSUME_TAC THENL
3982 [ASM_REWRITE_TAC[REAL_LT_LE] THEN
3983 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
3984 UNDISCH_TAC `inv t <= &0` THEN REWRITE_TAC[REAL_NOT_LE] THEN
3985 ASM_REWRITE_TAC[REAL_LT_INV_EQ];
3987 MATCH_MP_TAC(SET_RULE `!t. t SUBSET s /\ x IN t ==> x IN s`) THEN
3988 EXISTS_TAC `convex hull {vec 0:real^N,u % t % v}` THEN CONJ_TAC THENL
3990 REWRITE_TAC[CONVEX_HULL_2; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN
3991 REWRITE_TAC[IN_ELIM_THM] THEN
3992 MAP_EVERY EXISTS_TAC [`&1 - inv(u * t)`; `inv(u * t):real`] THEN
3993 REWRITE_TAC[REAL_ARITH `&1 - x + x = &1`; REAL_SUB_LE; REAL_LE_INV_EQ] THEN
3994 ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; VECTOR_MUL_ASSOC] THEN
3995 ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_ENTIRE; REAL_MUL_LINV;
3996 REAL_LT_IMP_NZ; VECTOR_MUL_LID] THEN
3997 MATCH_MP_TAC REAL_INV_LE_1 THEN ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN
3998 ASM_REWRITE_TAC[real_div; REAL_MUL_LID]] THEN
4000 `(u % t % v:real^N) IN (p DIFF relative_interior p)`
4003 ASM_SIMP_TAC[RELATIVE_INTERIOR_OF_POLYHEDRON] THEN
4004 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
4005 `x IN s DIFF (s DIFF t) ==> x IN t`)) THEN
4006 REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
4007 DISCH_THEN(X_CHOOSE_THEN `f:real^N->bool` STRIP_ASSUME_TAC) THEN
4008 MATCH_MP_TAC(SET_RULE
4009 `(?s. s IN f /\ t SUBSET s) ==> t SUBSET UNIONS f`) THEN
4010 REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `f:real^N->bool` THEN
4011 ASM_SIMP_TAC[SUBSET_HULL; CONVEX_CONVEX_HULL] THEN
4012 ASM_SIMP_TAC[HULL_INC; IN_UNION; INSERT_SUBSET; EMPTY_SUBSET]] THEN
4013 ASM_REWRITE_TAC[IN_DIFF; IN_RELATIVE_INTERIOR] THEN
4014 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4015 REWRITE_TAC[SUBSET; IN_BALL; IN_INTER; dist] THEN
4016 ABBREV_TAC `k = min (e / &2 / norm(t % v:real^N)) (&1 - u)` THEN
4017 SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL
4018 [EXPAND_TAC "k" THEN REWRITE_TAC[REAL_LT_MIN] THEN
4019 ASM_REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_LT_DIV THEN
4020 ASM_SIMP_TAC[REAL_HALF; NORM_POS_LT; VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ];
4022 DISCH_THEN(MP_TAC o SPEC `(u + k) % t % v:real^N`) THEN
4023 REWRITE_TAC[VECTOR_ARITH `u % x - (u + k) % x:real^N = --k % x`] THEN
4024 ONCE_REWRITE_TAC[NORM_MUL] THEN REWRITE_TAC[REAL_ABS_NEG; NOT_IMP] THEN
4025 REPEAT CONJ_TAC THENL
4026 [MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
4027 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_MUL_EQ_0;
4028 REAL_LT_IMP_NZ] THEN
4029 ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN
4030 EXPAND_TAC "k" THEN REAL_ARITH_TAC;
4031 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN
4032 REPEAT(MATCH_MP_TAC SPAN_MUL) THEN ASM_SIMP_TAC[SPAN_SUPERSET];
4034 FIRST_X_ASSUM(MP_TAC o SPEC `u + k:real`) THEN
4035 ASM_REWRITE_TAC[NOT_IMP] THEN
4036 MATCH_MP_TAC(REAL_ARITH
4037 `&0 <= u /\ &0 < x /\ x <= &1 - u
4038 ==> (&0 <= u + x /\ u + x <= &1) /\ ~(u + x <= u)`) THEN
4039 ASM_REWRITE_TAC[] THEN EXPAND_TAC "k" THEN REAL_ARITH_TAC]);;
4041 (* ------------------------------------------------------------------------- *)
4042 (* Finitely generated cone is polyhedral, and hence closed. *)
4043 (* ------------------------------------------------------------------------- *)
4045 let POLYHEDRON_CONVEX_CONE_HULL = prove
4046 (`!s:real^N->bool. FINITE s ==> polyhedron(convex_cone hull s)`,
4047 GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN DISCH_TAC THENL
4048 [ASM_REWRITE_TAC[CONVEX_CONE_HULL_EMPTY] THEN
4049 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON; POLYTOPE_SING];
4052 `polyhedron(convex hull ((vec 0:real^N) INSERT s))`
4054 [MATCH_MP_TAC POLYTOPE_IMP_POLYHEDRON THEN
4055 REWRITE_TAC[polytope] THEN ASM_MESON_TAC[FINITE_INSERT];
4056 REWRITE_TAC[polyhedron] THEN
4057 DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
4058 RULE_ASSUM_TAC(REWRITE_RULE[SKOLEM_THM; RIGHT_IMP_EXISTS_THM]) THEN
4059 FIRST_X_ASSUM(X_CHOOSE_THEN `a:(real^N->bool)->real^N` MP_TAC) THEN
4060 DISCH_THEN(X_CHOOSE_TAC `b:(real^N->bool)->real`)] THEN
4061 SUBGOAL_THEN `~(f:(real^N->bool)->bool = {})` ASSUME_TAC THENL
4062 [DISCH_THEN SUBST_ALL_TAC THEN FIRST_X_ASSUM(MP_TAC o
4063 GEN_REWRITE_RULE RAND_CONV [INTERS_0]) THEN
4064 DISCH_THEN(MP_TAC o AP_TERM `bounded:(real^N->bool)->bool`) THEN
4065 ASM_SIMP_TAC[NOT_BOUNDED_UNIV; BOUNDED_CONVEX_HULL; FINITE_IMP_BOUNDED;
4066 FINITE_INSERT; FINITE_EMPTY];
4068 EXISTS_TAC `{h:real^N->bool | h IN f /\ b h = &0}` THEN
4069 ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM] THEN CONJ_TAC THENL
4071 X_GEN_TAC `h:real^N->bool` THEN STRIP_TAC THEN
4072 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
4073 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
4074 MAP_EVERY EXISTS_TAC
4075 [`(a:(real^N->bool)->real^N) h`; `(b:(real^N->bool)->real) h`] THEN
4076 ASM_REWRITE_TAC[]] THEN
4077 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4078 [MATCH_MP_TAC HULL_MINIMAL THEN CONJ_TAC THENL
4079 [MATCH_MP_TAC SUBSET_TRANS THEN
4080 EXISTS_TAC `convex hull ((vec 0:real^N) INSERT s)` THEN CONJ_TAC THENL
4081 [SIMP_TAC[SUBSET; HULL_INC; IN_INSERT]; ASM_REWRITE_TAC[]] THEN
4082 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> INTERS t SUBSET INTERS s`) THEN
4084 MATCH_MP_TAC CONVEX_CONE_INTERS THEN
4085 X_GEN_TAC `h:real^N->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN
4086 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
4087 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
4088 REWRITE_TAC[CONVEX_CONE_HALFSPACE_LE]];
4090 REWRITE_TAC[SUBSET; IN_INTERS; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
4092 SUBGOAL_THEN `!h:real^N->bool. h IN f ==> ?t. &0 < t /\ (t % x) IN h`
4094 [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
4095 ASM_CASES_TAC `(b:(real^N->bool)->real) h = &0` THENL
4096 [EXISTS_TAC `&1` THEN ASM_SIMP_TAC[REAL_LT_01; VECTOR_MUL_LID];
4098 SUBGOAL_THEN `&0 < (b:(real^N->bool)->real) h` ASSUME_TAC THENL
4099 [ASM_REWRITE_TAC[REAL_LT_LE] THEN
4100 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
4101 DISCH_THEN(MP_TAC o SPEC `vec 0:real^N`) THEN
4102 SIMP_TAC[HULL_INC; IN_INSERT; IN_INTERS] THEN
4103 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
4104 SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}`
4105 (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th])
4106 THENL [ASM_MESON_TAC[]; REWRITE_TAC[IN_ELIM_THM; DOT_RZERO]];
4108 SUBGOAL_THEN `(vec 0:real^N) IN interior h` MP_TAC THENL
4109 [SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` SUBST1_TAC THENL
4111 ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; IN_ELIM_THM; DOT_RZERO]];
4112 REWRITE_TAC[IN_INTERIOR; SUBSET; IN_BALL_0; LEFT_IMP_EXISTS_THM] THEN
4113 X_GEN_TAC `e:real` THEN STRIP_TAC THEN
4114 ASM_CASES_TAC `x:real^N = vec 0` THENL
4115 [EXISTS_TAC `&1` THEN
4116 ASM_SIMP_TAC[VECTOR_MUL_RZERO; REAL_LT_01; NORM_0];
4117 EXISTS_TAC `e / &2 / norm(x:real^N)` THEN
4118 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT] THEN
4119 FIRST_X_ASSUM MATCH_MP_TAC THEN
4120 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_NORM] THEN
4121 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC]];
4123 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
4124 X_GEN_TAC `t:(real^N->bool)->real` THEN DISCH_TAC THEN
4125 SUBGOAL_THEN `x:real^N = inv(inf(IMAGE t (f:(real^N->bool)->bool))) %
4128 [GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN
4129 REWRITE_TAC[VECTOR_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN
4130 CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MUL_LINV THEN
4131 MATCH_MP_TAC REAL_LT_IMP_NZ THEN
4132 ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
4133 ASM_SIMP_TAC[FORALL_IN_IMAGE];
4135 MATCH_MP_TAC(REWRITE_RULE[conic] CONIC_CONVEX_CONE_HULL) THEN
4136 ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LE_INF_FINITE; FINITE_IMAGE;
4137 IMAGE_EQ_EMPTY; REAL_LT_IMP_LE; FORALL_IN_IMAGE] THEN
4138 MATCH_MP_TAC(SET_RULE `!s t. s SUBSET t /\ x IN s ==> x IN t`) THEN
4139 EXISTS_TAC `convex hull ((vec 0:real^N) INSERT s)` THEN CONJ_TAC THENL
4140 [MATCH_MP_TAC HULL_MINIMAL THEN
4141 REWRITE_TAC[CONVEX_CONVEX_CONE_HULL] THEN
4142 ASM_SIMP_TAC[INSERT_SUBSET; HULL_SUBSET; CONVEX_CONE_HULL_CONTAINS_0];
4143 ASM_REWRITE_TAC[IN_INTERS] THEN X_GEN_TAC `h:real^N->bool` THEN
4145 SUBGOAL_THEN `inf(IMAGE (t:(real^N->bool)->real) f) % x:real^N =
4146 (&1 - inf(IMAGE t f) / t h) % vec 0 +
4147 (inf(IMAGE t f) / t h) % t h % x`
4149 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_MUL_RZERO; VECTOR_ADD_LID;
4150 REAL_DIV_RMUL; REAL_LT_IMP_NZ];
4152 MATCH_MP_TAC IN_CONVEX_SET THEN
4153 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN
4154 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN
4155 ASM_SIMP_TAC[REAL_INF_LE_FINITE; REAL_LE_INF_FINITE;
4156 FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
4157 ASM_REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
4158 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN REPEAT CONJ_TAC THENL
4159 [SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` SUBST1_TAC THENL
4160 [ASM_MESON_TAC[]; ASM_SIMP_TAC[CONVEX_HALFSPACE_LE]];
4161 SUBGOAL_THEN `(vec 0:real^N) IN convex hull (vec 0 INSERT s)` MP_TAC
4162 THENL [SIMP_TAC[HULL_INC; IN_INSERT]; ALL_TAC] THEN
4163 ASM_REWRITE_TAC[IN_INTERS] THEN ASM_MESON_TAC[];
4164 ASM SET_TAC[REAL_LE_REFL]]]);;
4166 let CLOSED_CONVEX_CONE_HULL = prove
4167 (`!s:real^N->bool. FINITE s ==> closed(convex_cone hull s)`,
4168 MESON_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_CONVEX_CONE_HULL]);;
4170 (* ------------------------------------------------------------------------- *)
4171 (* And conversely, a polyhedral cone is finitely generated. *)
4172 (* ------------------------------------------------------------------------- *)
4174 let FINITELY_GENERATED_CONIC_POLYHEDRON = prove
4176 polyhedron s /\ conic s /\ ~(s = {})
4177 ==> ?c. FINITE c /\ s = convex_cone hull c`,
4178 REPEAT STRIP_TAC THEN
4179 SUBGOAL_THEN `?p:real^N->bool. polytope p /\ vec 0 IN interior p`
4180 STRIP_ASSUME_TAC THENL
4181 [EXISTS_TAC `interval[--vec 1:real^N,vec 1:real^N]` THEN
4182 REWRITE_TAC[POLYTOPE_INTERVAL; INTERIOR_CLOSED_INTERVAL] THEN
4183 SIMP_TAC[IN_INTERVAL; VECTOR_NEG_COMPONENT; VEC_COMPONENT] THEN
4184 CONV_TAC REAL_RAT_REDUCE_CONV;
4186 SUBGOAL_THEN `polytope(s INTER p:real^N->bool)` MP_TAC THENL
4187 [REWRITE_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON] THEN
4188 ASM_SIMP_TAC[BOUNDED_INTER; POLYTOPE_IMP_BOUNDED]THEN
4189 ASM_SIMP_TAC[POLYHEDRON_INTER; POLYTOPE_IMP_POLYHEDRON];
4190 REWRITE_TAC[polytope] THEN MATCH_MP_TAC MONO_EXISTS] THEN
4191 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4192 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4194 ASM_SIMP_TAC[SUBSET_HULL; POLYHEDRON_IMP_CONVEX; convex_cone] THEN
4195 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `s INTER p:real^N->bool` THEN
4196 REWRITE_TAC[INTER_SUBSET] THEN ASM_REWRITE_TAC[HULL_SUBSET]] THEN
4197 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4198 SUBGOAL_THEN `?t. &0 < t /\ (t % x:real^N) IN p` STRIP_ASSUME_TAC THENL
4199 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN
4200 REWRITE_TAC[SUBSET; IN_BALL_0; LEFT_IMP_EXISTS_THM] THEN
4201 X_GEN_TAC `e:real` THEN STRIP_TAC THEN
4202 ASM_CASES_TAC `x:real^N = vec 0` THENL
4203 [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO; REAL_LT_01] THEN
4204 ASM_SIMP_TAC[NORM_0];
4205 EXISTS_TAC `e / &2 / norm(x:real^N)` THEN
4206 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT] THEN
4207 FIRST_X_ASSUM MATCH_MP_TAC THEN
4208 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NUM] THEN
4209 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC];
4211 SUBGOAL_THEN `x:real^N = inv t % t % x` SUBST1_TAC THENL
4212 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID;
4215 MATCH_MP_TAC(REWRITE_RULE[conic] CONIC_CONVEX_CONE_HULL) THEN
4216 ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LT_IMP_LE] THEN
4217 MATCH_MP_TAC(SET_RULE `!s. x IN s /\ s SUBSET t ==> x IN t`) THEN
4218 EXISTS_TAC `convex hull c:real^N->bool` THEN
4219 REWRITE_TAC[CONVEX_HULL_SUBSET_CONVEX_CONE_HULL] THEN
4220 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[IN_INTER] THEN
4221 FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [conic]) THEN
4222 ASM_SIMP_TAC[REAL_LT_IMP_LE]);;
4224 (* ------------------------------------------------------------------------- *)
4225 (* Decomposition of polyhedron into cone plus polytope and more corollaries. *)
4226 (* ------------------------------------------------------------------------- *)
4228 let POLYHEDRON_POLYTOPE_SUMS = prove
4229 (`!s t:real^N->bool.
4230 polyhedron s /\ polytope t ==> polyhedron {x + y | x IN s /\ y IN t}`,
4231 REPEAT STRIP_TAC THEN
4232 REWRITE_TAC[POLYHEDRON_EQ_FINITE_EXPOSED_FACES] THEN REPEAT CONJ_TAC THENL
4233 [MATCH_MP_TAC CLOSED_COMPACT_SUMS THEN
4234 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYTOPE_IMP_COMPACT];
4235 MATCH_MP_TAC CONVEX_SUMS THEN
4236 ASM_SIMP_TAC[POLYHEDRON_IMP_CONVEX; POLYTOPE_IMP_CONVEX];
4237 MATCH_MP_TAC FINITE_SUBSET THEN
4238 EXISTS_TAC `{ {x + y:real^N | x IN k /\ y IN l} |
4239 k exposed_face_of s /\ l exposed_face_of t}` THEN
4241 [ONCE_REWRITE_TAC[SET_RULE `k exposed_face_of s <=>
4242 k IN {f | f exposed_face_of s}`] THEN
4243 MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN
4244 ASM_SIMP_TAC[FINITE_POLYHEDRON_EXPOSED_FACES;
4245 POLYTOPE_IMP_POLYHEDRON];
4246 REWRITE_TAC[SUBSET; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN
4247 REPEAT STRIP_TAC THEN MATCH_MP_TAC EXPOSED_FACE_OF_SUMS THEN
4248 ASM_SIMP_TAC[POLYHEDRON_IMP_CONVEX; POLYTOPE_IMP_CONVEX]]]);;
4250 let POLYHEDRON_AS_CONE_PLUS_CONV = prove
4252 polyhedron s <=> ?t u. FINITE t /\ FINITE u /\
4253 s = {x + y | x IN convex_cone hull t /\
4254 y IN convex hull u}`,
4255 REPEAT GEN_TAC THEN EQ_TAC THENL
4256 [REWRITE_TAC[polyhedron; LEFT_IMP_EXISTS_THM];
4257 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4258 MATCH_MP_TAC POLYHEDRON_POLYTOPE_SUMS THEN
4259 ASM_SIMP_TAC[POLYTOPE_CONVEX_HULL; POLYHEDRON_CONVEX_CONE_HULL]] THEN
4260 REWRITE_TAC[polyhedron; LEFT_IMP_EXISTS_THM] THEN
4261 X_GEN_TAC `f:(real^N->bool)->bool` THEN
4262 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4263 DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) MP_TAC) THEN
4264 GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4265 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
4266 [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN
4267 ONCE_REWRITE_TAC[MESON[] `h = {x | P x} <=> {x | P x} = h`] THEN
4270 `s':real^(N,1)finite_sum->bool =
4271 {x | &0 <= drop(sndcart x) /\
4273 h IN f ==> a h dot (fstcart x) <= b h * drop(sndcart x)}` THEN
4275 `?t u. FINITE t /\ FINITE u /\
4276 (!y:real^(N,1)finite_sum. y IN t ==> drop(sndcart y) = &0) /\
4277 (!y. y IN u ==> drop(sndcart y) = &1) /\
4278 s' = convex_cone hull (t UNION u)`
4279 STRIP_ASSUME_TAC THENL
4280 [MP_TAC(ISPEC `s':real^(N,1)finite_sum->bool`
4281 FINITELY_GENERATED_CONIC_POLYHEDRON) THEN
4283 [EXPAND_TAC "s'" THEN REPEAT CONJ_TAC THENL
4284 [REWRITE_TAC[polyhedron] THEN
4286 `{ x:real^(N,1)finite_sum |
4287 pastecart (vec 0) (--vec 1) dot x <= &0} INSERT
4288 { {x | pastecart (a h) (--lift(b h)) dot x <= &0} |
4289 (h:real^N->bool) IN f}` THEN
4290 REWRITE_TAC[FINITE_INSERT; INTERS_INSERT; SIMPLE_IMAGE] THEN
4291 ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_INSERT; FORALL_IN_IMAGE] THEN
4292 REPEAT CONJ_TAC THENL
4293 [EXPAND_TAC "s'" THEN
4294 REWRITE_TAC[EXTENSION; IN_ELIM_THM; FORALL_PASTECART; IN_INTER;
4295 DOT_PASTECART; INTERS_IMAGE; FSTCART_PASTECART;
4296 SNDCART_PASTECART; DOT_1; GSYM drop; DROP_NEG; LIFT_DROP] THEN
4297 REWRITE_TAC[DROP_VEC; DOT_LZERO; REAL_MUL_LNEG; GSYM real_sub] THEN
4298 REWRITE_TAC[REAL_MUL_LID; REAL_ARITH `x - y <= &0 <=> x <= y`];
4299 EXISTS_TAC `pastecart (vec 0) (--vec 1):real^(N,1)finite_sum` THEN
4300 EXISTS_TAC `&0` THEN
4301 REWRITE_TAC[PASTECART_EQ_VEC; VECTOR_NEG_EQ_0; VEC_EQ] THEN
4303 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC
4304 [`pastecart (a(h:real^N->bool)) (--lift(b h)):real^(N,1)finite_sum`;
4306 ASM_SIMP_TAC[PASTECART_EQ_VEC]];
4307 REWRITE_TAC[conic; IN_ELIM_THM; FSTCART_CMUL; SNDCART_CMUL] THEN
4308 SIMP_TAC[DROP_CMUL; DOT_RMUL; REAL_LE_MUL] THEN
4309 MESON_TAC[REAL_LE_LMUL; REAL_MUL_AC];
4310 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
4311 EXISTS_TAC `vec 0:real^(N,1)finite_sum` THEN
4312 REWRITE_TAC[IN_ELIM_THM; FSTCART_VEC; SNDCART_VEC] THEN
4313 REWRITE_TAC[DROP_VEC; DOT_RZERO; REAL_LE_REFL; REAL_MUL_RZERO]];
4314 DISCH_THEN(X_CHOOSE_THEN `c:real^(N,1)finite_sum->bool`
4315 STRIP_ASSUME_TAC) THEN
4316 MAP_EVERY EXISTS_TAC
4317 [`{x:real^(N,1)finite_sum | x IN c /\ drop(sndcart x) = &0}`;
4318 `IMAGE (\x. inv(drop(sndcart x)) % x)
4319 {x:real^(N,1)finite_sum | x IN c /\ ~(drop(sndcart x) = &0)}`] THEN
4320 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; FORALL_IN_IMAGE] THEN
4321 SIMP_TAC[IN_ELIM_THM; SNDCART_CMUL; DROP_CMUL; REAL_MUL_LINV] THEN
4323 `!x:real^(N,1)finite_sum. x IN c ==> &0 <= drop(sndcart x)`
4325 [GEN_TAC THEN DISCH_TAC THEN
4326 SUBGOAL_THEN `(x:real^(N,1)finite_sum) IN s'` MP_TAC THENL
4327 [ASM_MESON_TAC[HULL_INC]; EXPAND_TAC "s'"] THEN
4328 SIMP_TAC[IN_ELIM_THM];
4330 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN
4331 MATCH_MP_TAC HULL_MINIMAL THEN
4332 REWRITE_TAC[CONVEX_CONE_CONVEX_CONE_HULL; UNION_SUBSET] THEN
4333 SIMP_TAC[SUBSET; IN_ELIM_THM; HULL_INC; FORALL_IN_IMAGE] THEN
4334 X_GEN_TAC `x:real^(N,1)finite_sum` THEN DISCH_TAC THEN
4335 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^(N,1)finite_sum`) THEN
4336 ASM_SIMP_TAC[CONVEX_CONE_HULL_MUL; HULL_INC; REAL_LE_INV_EQ] THEN
4337 ASM_REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN
4339 [MATCH_MP_TAC HULL_INC THEN ASM_REWRITE_TAC[IN_UNION; IN_ELIM_THM];
4341 `x:real^(N,1)finite_sum =
4342 drop(sndcart x) % inv(drop(sndcart x)) % x`
4344 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
4345 REWRITE_TAC[VECTOR_MUL_LID];
4346 MATCH_MP_TAC CONVEX_CONE_HULL_MUL THEN
4347 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC HULL_INC THEN
4348 REWRITE_TAC[IN_UNION] THEN DISJ2_TAC THEN
4349 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `x:real^(N,1)finite_sum` THEN
4350 ASM_SIMP_TAC[IN_ELIM_THM; REAL_LT_IMP_NZ]]]];
4351 EXISTS_TAC `IMAGE fstcart (t:real^(N,1)finite_sum->bool)` THEN
4352 EXISTS_TAC `IMAGE fstcart (u:real^(N,1)finite_sum->bool)` THEN
4353 ASM_SIMP_TAC[FINITE_IMAGE] THEN
4354 SUBGOAL_THEN `s = {x:real^N | pastecart x (vec 1:real^1) IN s'}`
4356 [MAP_EVERY EXPAND_TAC ["s"; "s'"] THEN
4357 REWRITE_TAC[IN_ELIM_THM; SNDCART_PASTECART; DROP_VEC; REAL_POS] THEN
4358 GEN_REWRITE_TAC I [EXTENSION] THEN
4359 REWRITE_TAC[FSTCART_PASTECART; IN_ELIM_THM; IN_INTERS; REAL_MUL_RID] THEN
4361 ASM_REWRITE_TAC[CONVEX_CONE_HULL_UNION]] THEN
4362 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `z:real^N` THEN
4363 SIMP_TAC[CONVEX_CONE_HULL_LINEAR_IMAGE; CONVEX_HULL_LINEAR_IMAGE;
4364 LINEAR_FSTCART] THEN
4365 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM] THEN
4366 REWRITE_TAC[EXISTS_IN_IMAGE] THEN
4367 AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
4368 X_GEN_TAC `a:real^(N,1)finite_sum` THEN REWRITE_TAC[] THEN
4369 MATCH_MP_TAC(TAUT `(p ==> (q <=> r)) ==> (p /\ q <=> p /\ r)`) THEN
4370 DISCH_TAC THEN AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
4371 X_GEN_TAC `b:real^(N,1)finite_sum` THEN REWRITE_TAC[PASTECART_EQ] THEN
4372 REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; FSTCART_ADD;
4374 ASM_CASES_TAC `fstcart(a:real^(N,1)finite_sum) +
4375 fstcart(b:real^(N,1)finite_sum) = z` THEN
4376 ASM_REWRITE_TAC[] THEN
4377 SUBGOAL_THEN `sndcart(a:real^(N,1)finite_sum) = vec 0` SUBST1_TAC THENL
4378 [UNDISCH_TAC `(a:real^(N,1)finite_sum) IN convex_cone hull t` THEN
4379 SPEC_TAC(`a:real^(N,1)finite_sum`,`a:real^(N,1)finite_sum`) THEN
4380 MATCH_MP_TAC HULL_INDUCT THEN ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC] THEN
4381 REWRITE_TAC[convex_cone; convex; conic; IN_ELIM_THM] THEN
4382 SIMP_TAC[SNDCART_ADD; SNDCART_CMUL; DROP_ADD; DROP_CMUL] THEN
4383 REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_RID; GSYM MEMBER_NOT_EMPTY] THEN
4384 EXISTS_TAC `vec 0:real^(N,1)finite_sum` THEN
4385 REWRITE_TAC[IN_ELIM_THM; SNDCART_VEC; DROP_VEC];
4386 REWRITE_TAC[VECTOR_ADD_LID]] THEN
4387 ASM_CASES_TAC `u:real^(N,1)finite_sum->bool = {}` THENL
4388 [ASM_REWRITE_TAC[CONVEX_CONE_HULL_EMPTY; CONVEX_HULL_EMPTY] THEN
4389 REWRITE_TAC[IN_SING; NOT_IN_EMPTY] THEN
4390 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4391 ASM_REWRITE_TAC[SNDCART_VEC; VEC_EQ] THEN ARITH_TAC;
4393 ASM_SIMP_TAC[CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY; IN_ELIM_THM] THEN
4395 `!y:real^(N,1)finite_sum. y IN convex hull u ==> sndcart y = vec 1`
4398 [MATCH_MP_TAC HULL_INDUCT THEN ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC] THEN
4399 REWRITE_TAC[convex; IN_ELIM_THM] THEN
4400 SIMP_TAC[SNDCART_ADD; SNDCART_CMUL; DROP_ADD; DROP_CMUL] THEN
4401 SIMP_TAC[REAL_MUL_RID];
4403 EQ_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THENL
4404 [MAP_EVERY X_GEN_TAC [`c:real`; `d:real^(N,1)finite_sum`] THEN
4405 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
4406 ASM_SIMP_TAC[SNDCART_CMUL; VECTOR_MUL_EQ_0; VECTOR_ARITH
4407 `x:real^N = c % x <=> (c - &1) % x = vec 0`] THEN
4408 ASM_SIMP_TAC[REAL_SUB_0; VEC_EQ; ARITH_EQ; VECTOR_MUL_LID];
4409 DISCH_TAC THEN ASM_SIMP_TAC[] THEN EXISTS_TAC `&1` THEN
4410 ASM_REWRITE_TAC[REAL_POS; VECTOR_MUL_LID] THEN ASM_MESON_TAC[]]]);;
4412 let POLYHEDRON_LINEAR_IMAGE = prove
4413 (`!f:real^M->real^N s.
4414 linear f /\ polyhedron s ==> polyhedron(IMAGE f s)`,
4415 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4416 REWRITE_TAC[POLYHEDRON_AS_CONE_PLUS_CONV; LEFT_IMP_EXISTS_THM] THEN
4417 MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^M->bool`] THEN STRIP_TAC THEN
4418 EXISTS_TAC `IMAGE (f:real^M->real^N) t` THEN
4419 EXISTS_TAC `IMAGE (f:real^M->real^N) u` THEN
4420 ASM_SIMP_TAC[FINITE_IMAGE] THEN
4421 ASM_SIMP_TAC[CONVEX_CONE_HULL_LINEAR_IMAGE; CONVEX_HULL_LINEAR_IMAGE] THEN
4422 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN
4423 FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_ADD) THEN MESON_TAC[]);;
4425 let POLYHEDRON_SUMS = prove
4426 (`!s t:real^N->bool.
4427 polyhedron s /\ polyhedron t ==> polyhedron {x + y | x IN s /\ y IN t}`,
4428 REPEAT GEN_TAC THEN REWRITE_TAC[POLYHEDRON_AS_CONE_PLUS_CONV] THEN
4429 REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
4430 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
4432 [`t1:real^N->bool`; `u1:real^N->bool`;
4433 `t2:real^N->bool`; `u2:real^N->bool`] THEN
4434 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4435 EXISTS_TAC `t1 UNION t2:real^N->bool` THEN
4436 EXISTS_TAC `{u + v:real^N | u IN u1 /\ v IN u2}` THEN
4437 REWRITE_TAC[CONVEX_CONE_HULL_UNION; CONVEX_HULL_SUMS] THEN
4438 ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FINITE_UNION] THEN
4439 REWRITE_TAC[SET_RULE
4440 `{h x y | x IN {f a b | P a /\ Q b} /\
4441 y IN {g a b | R a /\ S b}} =
4442 {h (f a b) (g c d) | P a /\ Q b /\ R c /\ S d}`] THEN
4443 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_AC]);;
4445 let POLYHEDRAL_CONVEX_CONE = prove
4447 polyhedron s /\ convex_cone s <=>
4448 ?k. FINITE k /\ s = convex_cone hull k`,
4449 GEN_TAC THEN EQ_TAC THENL
4450 [ALL_TAC; MESON_TAC[POLYHEDRON_CONVEX_CONE_HULL;
4451 CONVEX_CONE_CONVEX_CONE_HULL]] THEN
4453 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_AS_CONE_PLUS_CONV]) THEN
4454 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
4455 MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `c:real^N->bool`] THEN
4456 ASM_CASES_TAC `c:real^N->bool = {}` THENL
4457 [ASM_REWRITE_TAC[CONVEX_HULL_EMPTY; NOT_IN_EMPTY] THEN
4458 REWRITE_TAC[SET_RULE `{f x y | x,y | F} = {}`] THEN
4459 ASM_MESON_TAC[CONVEX_CONE_NONEMPTY];
4460 DISCH_THEN(STRIP_ASSUME_TAC o GSYM)] THEN
4461 EXISTS_TAC `k UNION c:real^N->bool` THEN
4462 ASM_REWRITE_TAC[FINITE_UNION] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4464 [EXPAND_TAC "s" THEN REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
4465 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONVEX_CONE_HULL_ADD THEN
4466 CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
4467 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
4468 MESON_TAC[HULL_MONO; SUBSET_UNION; SUBSET_TRANS;
4469 CONVEX_HULL_SUBSET_CONVEX_CONE_HULL];
4470 MATCH_MP_TAC HULL_MINIMAL THEN
4471 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]]] THEN
4472 REWRITE_TAC[UNION_SUBSET] THEN REWRITE_TAC[SUBSET] THEN
4473 CONJ_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THENL
4475 EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_THM] THEN
4476 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN
4477 ASM_SIMP_TAC[HULL_INC; VECTOR_ADD_LID; CONVEX_CONE_HULL_CONTAINS_0]] THEN
4478 FIRST_ASSUM(MP_TAC o MATCH_MP POLYHEDRON_IMP_CLOSED) THEN
4479 DISCH_THEN(MP_TAC o MATCH_MP CLOSED_APPROACHABLE) THEN
4480 DISCH_THEN(fun th -> GEN_REWRITE_TAC I [GSYM th]) THEN
4481 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
4482 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
4483 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4484 EXISTS_TAC `e / (norm y + &1) % ((norm y + &1) / e % x + y):real^N` THEN
4486 [MATCH_MP_TAC CONVEX_CONE_MUL THEN
4487 ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; NORM_POS_LE; REAL_POS;
4488 REAL_LT_IMP_LE] THEN
4489 EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC
4490 [`(norm(y:real^N) + &1) / e % x:real^N`; `y:real^N`] THEN
4491 ASM_SIMP_TAC[HULL_INC] THEN MATCH_MP_TAC CONVEX_CONE_HULL_MUL THEN
4492 ASM_SIMP_TAC[HULL_INC] THEN MATCH_MP_TAC REAL_LE_DIV THEN
4493 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN CONV_TAC NORM_ARITH;
4494 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
4495 ASM_SIMP_TAC[NORM_POS_LE; VECTOR_MUL_LID; REAL_FIELD
4496 `&0 <= y /\ &0 < e ==> e / (y + &1) * (y + &1) / e = &1`] THEN
4497 REWRITE_TAC[NORM_ARITH `dist(x + e:real^N,x) = norm e`] THEN
4498 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV] THEN
4499 MATCH_MP_TAC(REAL_ARITH
4500 `&0 < e /\ e * z / y < e * &1 ==> abs e / y * z < e`) THEN
4501 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ;
4502 NORM_ARITH `&0 < abs(norm(y:real^N) + &1)`] THEN
4505 (* ------------------------------------------------------------------------- *)
4506 (* Farkas's lemma (2 variants) and stronger separation for polyhedra. *)
4507 (* ------------------------------------------------------------------------- *)
4509 let FARKAS_LEMMA = prove
4513 (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i)) <=>
4516 (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= (transp A ** y)$i))`,
4517 REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT
4518 `(q ==> ~p) /\ (~p ==> q) ==> (p <=> ~q)`) THEN
4520 [REPEAT STRIP_TAC THEN
4521 SUBGOAL_THEN `y dot ((A:real^N^M) ** x - b) = &0` MP_TAC THENL
4522 [ASM_REWRITE_TAC[VECTOR_SUB_REFL; DOT_RZERO]; ALL_TAC] THEN
4523 RULE_ASSUM_TAC(ONCE_REWRITE_RULE[DOT_SYM]) THEN
4524 REWRITE_TAC[DOT_RSUB; REAL_SUB_0] THEN
4525 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
4526 `y < &0 ==> &0 <= x ==> ~(x = y)`)) THEN
4527 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4528 REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; dot] THEN
4529 MATCH_MP_TAC SUM_POS_LE THEN
4530 ASM_SIMP_TAC[REAL_LE_MUL; IN_NUMSEG; FINITE_NUMSEG];
4531 DISCH_TAC THEN MP_TAC(ISPECL
4532 [`{(A:real^N^M) ** (x:real^N) |
4533 !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`;
4534 `b:real^M`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN
4535 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
4536 [REWRITE_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN
4537 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
4538 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
4539 SIMP_TAC[CONVEX_POSITIVE_ORTHANT; CONVEX_LINEAR_IMAGE;
4540 MATRIX_VECTOR_MUL_LINEAR] THEN
4541 MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN
4542 MATCH_MP_TAC POLYHEDRON_LINEAR_IMAGE THEN
4543 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; POLYHEDRON_POSITIVE_ORTHANT];
4544 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^M` THEN
4545 DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN
4546 ONCE_REWRITE_TAC[DOT_SYM] THEN
4547 FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N`) THEN
4548 REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO; DOT_RZERO] THEN
4549 REWRITE_TAC[real_gt; VEC_COMPONENT; REAL_LE_REFL] THEN
4550 DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
4551 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
4552 ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
4553 FIRST_X_ASSUM(MP_TAC o SPEC
4554 `c / (transp(A:real^N^M) ** (y:real^M))$k % basis k:real^N`) THEN
4555 ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
4556 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4557 ASM_SIMP_TAC[DOT_RMUL; DOT_BASIS; VECTOR_MATRIX_MUL_TRANSP] THEN
4558 ASM_SIMP_TAC[REAL_FIELD `y < &0 ==> x / y * y = x`] THEN
4559 REWRITE_TAC[REAL_LT_REFL; real_gt] THEN
4560 GEN_TAC THEN COND_CASES_TAC THEN
4561 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_LE_REFL; REAL_MUL_RID] THEN
4562 ONCE_REWRITE_TAC[REAL_ARITH `x / y:real = --x * -- inv y`] THEN
4563 MATCH_MP_TAC REAL_LE_MUL THEN
4564 REWRITE_TAC[REAL_ARITH `&0 <= --x <=> ~(&0 < x)`; REAL_LT_INV_EQ] THEN
4565 ASM_REAL_ARITH_TAC]]);;
4567 let FARKAS_LEMMA_ALT = prove
4570 (!i. 1 <= i /\ i <= dimindex(:M) ==> (A ** x)$i <= b$i)) <=>
4572 (!i. 1 <= i /\ i <= dimindex(:M) ==> &0 <= y$i) /\
4573 y ** A = vec 0 /\ b dot y < &0)`,
4575 MATCH_MP_TAC(TAUT `~(p /\ q) /\ (~p ==> q) ==> (p <=> ~q)`) THEN
4576 REPEAT STRIP_TAC THENL
4577 [SUBGOAL_THEN `&0 <= (b - (A:real^N^M) ** x) dot y` MP_TAC THENL
4578 [REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_POS_LE THEN
4579 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
4580 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
4581 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_SUB_LE];
4582 REWRITE_TAC[DOT_LSUB; REAL_SUB_LE] THEN REWRITE_TAC[REAL_NOT_LE] THEN
4583 GEN_REWRITE_TAC RAND_CONV [DOT_SYM] THEN
4584 REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4585 ASM_REWRITE_TAC[DOT_LZERO]];
4587 [`{(A:real^N^M) ** (x:real^N) + s |x,s|
4588 !i. 1 <= i /\ i <= dimindex(:M) ==> &0 <= s$i}`;
4589 `b:real^M`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN
4590 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
4591 [REWRITE_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN CONJ_TAC THENL
4592 [ONCE_REWRITE_TAC[SET_RULE
4593 `{f x + y | x,y | P y} =
4594 {z + y | z,y | z IN IMAGE (f:real^M->real^N) (:real^M) /\
4595 y IN {w | P w}}`] THEN
4596 SIMP_TAC[CONVEX_SUMS; CONVEX_POSITIVE_ORTHANT; CONVEX_LINEAR_IMAGE;
4597 MATRIX_VECTOR_MUL_LINEAR; CONVEX_UNIV] THEN
4598 MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN
4599 MATCH_MP_TAC POLYHEDRON_SUMS THEN
4600 ASM_SIMP_TAC[POLYHEDRON_LINEAR_IMAGE; POLYHEDRON_UNIV;
4601 MATRIX_VECTOR_MUL_LINEAR; POLYHEDRON_POSITIVE_ORTHANT];
4602 POP_ASSUM MP_TAC THEN REWRITE_TAC[CONTRAPOS_THM] THEN
4603 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
4604 ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; REAL_LE_ADDR]];
4605 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^M` THEN
4606 DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN
4607 ONCE_REWRITE_TAC[DOT_SYM] THEN
4608 FIRST_ASSUM(MP_TAC o SPECL [`vec 0:real^N`; `vec 0:real^M`]) THEN
4609 REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO; VECTOR_ADD_RID; DOT_RZERO] THEN
4610 REWRITE_TAC[real_gt; VEC_COMPONENT; REAL_LE_REFL] THEN
4611 DISCH_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN
4612 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN CONJ_TAC THENL
4613 [X_GEN_TAC `k:num` THEN STRIP_TAC THEN
4614 ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
4615 FIRST_X_ASSUM(MP_TAC o SPECL
4616 [`vec 0:real^N`; `--c / --((y:real^M)$k) % basis k:real^M`]) THEN
4617 ASM_SIMP_TAC[MATRIX_VECTOR_MUL_RZERO; VECTOR_ADD_LID;
4618 DOT_RMUL; DOT_BASIS; REAL_FIELD
4619 `y < &0 ==> c / --y * y = --c`] THEN
4620 SIMP_TAC[REAL_NEG_NEG; REAL_LT_REFL; VECTOR_MUL_COMPONENT; real_gt] THEN
4621 ASM_SIMP_TAC[BASIS_COMPONENT] THEN REPEAT STRIP_TAC THEN
4623 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID; REAL_LE_REFL] THEN
4624 MATCH_MP_TAC REAL_LE_DIV THEN ASM_REAL_ARITH_TAC;
4625 FIRST_X_ASSUM(MP_TAC o SPECL
4626 [`c / norm((y:real^M) ** (A:real^N^M)) pow 2 %
4627 (transp A ** y)`; `vec 0:real^M`]) THEN
4628 SIMP_TAC[VEC_COMPONENT; REAL_LE_REFL; VECTOR_ADD_RID] THEN
4629 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4630 REWRITE_TAC[GSYM VECTOR_MATRIX_MUL_TRANSP; DOT_RMUL] THEN
4631 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
4632 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_POW_2; DOT_EQ_0] THEN
4633 REAL_ARITH_TAC]]]);;
4635 let SEPARATING_HYPERPLANE_POLYHEDRA = prove
4636 (`!s t:real^N->bool.
4637 polyhedron s /\ polyhedron t /\ ~(s = {}) /\ ~(t = {}) /\ DISJOINT s t
4638 ==> ?a b. ~(a = vec 0) /\
4639 (!x. x IN s ==> a dot x < b) /\
4640 (!x. x IN t ==> a dot x > b)`,
4641 REPEAT STRIP_TAC THEN
4642 MP_TAC(ISPEC `{x + y:real^N | x IN s /\ y IN IMAGE (--) t}`
4643 SEPARATING_HYPERPLANE_CLOSED_0) THEN
4645 [ASM_SIMP_TAC[CONVEX_SUMS; CONVEX_NEGATIONS; POLYHEDRON_IMP_CONVEX] THEN
4647 [MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN
4648 MATCH_MP_TAC POLYHEDRON_SUMS THEN ASM_SIMP_TAC[POLYHEDRON_NEGATIONS];
4649 REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN
4650 REWRITE_TAC[VECTOR_ARITH `y = --x:real^N <=> --y = x`] THEN
4651 REWRITE_TAC[UNWIND_THM1] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
4652 REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = x + y <=> y = --x`] THEN
4653 REWRITE_TAC[UNWIND_THM2; VECTOR_NEG_NEG] THEN ASM SET_TAC[]];
4654 REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4655 REWRITE_TAC[FORALL_IN_IMAGE; GSYM VECTOR_SUB; LEFT_IMP_EXISTS_THM] THEN
4656 MAP_EVERY X_GEN_TAC [`a:real^N`; `k:real`] THEN
4657 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; DOT_RSUB] THEN STRIP_TAC THEN
4658 EXISTS_TAC `--a:real^N` THEN ASM_REWRITE_TAC[VECTOR_NEG_EQ_0] THEN
4659 MP_TAC(ISPEC `IMAGE (\x:real^N. a dot x) s` INF) THEN
4660 MP_TAC(ISPEC `IMAGE (\x:real^N. a dot x) t` SUP) THEN
4661 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
4662 MAP_EVERY ABBREV_TAC
4663 [`u = inf(IMAGE (\x:real^N. a dot x) s)`;
4664 `v = sup(IMAGE (\x:real^N. a dot x) t)`] THEN
4666 [MP_TAC(GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]
4667 (ASSUME `~(s:real^N->bool = {})`)) THEN
4668 DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN
4669 EXISTS_TAC `a dot (z:real^N) - k` THEN
4670 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4671 FIRST_X_ASSUM(MP_TAC o SPECL [`z:real^N`; `x:real^N`]) THEN
4672 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
4675 [MP_TAC(GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]
4676 (ASSUME `~(t:real^N->bool = {})`)) THEN
4677 DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN
4678 EXISTS_TAC `a dot (z:real^N) + k` THEN
4679 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4680 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `z:real^N`]) THEN
4681 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
4683 SUBGOAL_THEN `k <= u - v` ASSUME_TAC THENL
4684 [REWRITE_TAC[REAL_LE_SUB_LADD] THEN EXPAND_TAC "u" THEN
4685 MATCH_MP_TAC REAL_LE_INF THEN
4686 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
4687 GEN_TAC THEN DISCH_TAC THEN
4688 ONCE_REWRITE_TAC[REAL_ARITH `k + v <= u <=> v <= u - k`] THEN
4689 EXPAND_TAC "v" THEN MATCH_MP_TAC REAL_SUP_LE THEN
4690 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
4691 ASM_MESON_TAC[REAL_ARITH `x - y > k ==> y <= x - k`];
4692 EXISTS_TAC `--((u + v) / &2)` THEN REWRITE_TAC[real_gt] THEN
4693 REWRITE_TAC[DOT_LNEG; REAL_LT_NEG2] THEN REPEAT STRIP_TAC THENL
4694 [MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `u:real`;
4695 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `v:real`] THEN
4696 ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC]]);;
4698 (* ------------------------------------------------------------------------- *)
4699 (* Relative and absolute frontier of a polytope. *)
4700 (* ------------------------------------------------------------------------- *)
4702 let RELATIVE_BOUNDARY_OF_CONVEX_HULL = prove
4705 ==> (convex hull s) DIFF relative_interior(convex hull s) =
4706 UNIONS { convex hull (s DELETE a) | a | a IN s}`,
4707 REPEAT STRIP_TAC THEN
4708 FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN
4709 REPEAT_TCL DISJ_CASES_THEN MP_TAC (ARITH_RULE
4710 `CARD(s:real^N->bool) = 0 \/ CARD s = 1 \/ 2 <= CARD s`)
4712 [ASM_SIMP_TAC[CARD_EQ_0; CONVEX_HULL_EMPTY] THEN SET_TAC[];
4713 DISCH_TAC THEN MP_TAC(HAS_SIZE_CONV `(s:real^N->bool) HAS_SIZE 1`) THEN
4714 ASM_SIMP_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM; CONVEX_HULL_SING] THEN
4715 REWRITE_TAC[RELATIVE_INTERIOR_SING; DIFF_EQ_EMPTY] THEN
4716 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[EMPTY_UNIONS] THEN
4717 REWRITE_TAC[FORALL_IN_GSPEC; IN_SING; FORALL_UNWIND_THM2] THEN
4718 REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN SET_TAC[];
4720 ASM_SIMP_TAC[POLYHEDRON_CONVEX_HULL; RELATIVE_BOUNDARY_OF_POLYHEDRON] THEN
4721 ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT] THEN
4724 let RELATIVE_FRONTIER_OF_CONVEX_HULL = prove
4727 ==> relative_frontier(convex hull s) =
4728 UNIONS { convex hull (s DELETE a) | a | a IN s}`,
4729 REPEAT STRIP_TAC THEN
4730 FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN
4731 ASM_SIMP_TAC[relative_frontier; GSYM RELATIVE_BOUNDARY_OF_CONVEX_HULL] THEN
4732 AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC CLOSURE_CLOSED THEN
4733 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);;
4735 let FRONTIER_OF_CONVEX_HULL = prove
4737 s HAS_SIZE (dimindex(:N) + 1)
4738 ==> frontier(convex hull s) =
4739 UNIONS { convex hull (s DELETE a) | a | a IN s}`,
4740 REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN
4741 ASM_CASES_TAC `affine_dependent(s:real^N->bool)` THENL
4742 [REWRITE_TAC[frontier] THEN MATCH_MP_TAC EQ_TRANS THEN
4743 EXISTS_TAC `(convex hull s:real^N->bool) DIFF {}` THEN CONJ_TAC THENL
4745 ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EQ_EMPTY; frontier; HAS_SIZE] THEN
4746 MATCH_MP_TAC CLOSURE_CLOSED THEN
4747 ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL;
4748 FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY];
4749 REWRITE_TAC[DIFF_EMPTY] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4751 [GEN_REWRITE_TAC LAND_CONV [CARATHEODORY_AFF_DIM] THEN
4752 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
4753 GEN_REWRITE_TAC I [SUBSET] THEN
4754 REWRITE_TAC[IN_ELIM_THM; UNIONS_IMAGE] THEN
4755 X_GEN_TAC `x:real^N` THEN
4756 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
4757 MP_TAC(ISPEC `s:real^N->bool` AFFINE_INDEPENDENT_IFF_CARD) THEN
4758 ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN
4759 REWRITE_TAC[INT_ARITH `(x + &1) - &1:int = x`] THEN DISCH_TAC THEN
4760 SUBGOAL_THEN `(t:real^N->bool) PSUBSET s` ASSUME_TAC THENL
4761 [ASM_REWRITE_TAC[PSUBSET] THEN
4762 DISCH_THEN(MP_TAC o AP_TERM `CARD:(real^N->bool)->num`) THEN
4763 MATCH_MP_TAC(ARITH_RULE `t:num < s ==> t = s ==> F`) THEN
4764 ASM_REWRITE_TAC[ARITH_RULE `x < n + 1 <=> x <= n`] THEN
4765 REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN MATCH_MP_TAC INT_LE_TRANS THEN
4766 EXISTS_TAC `aff_dim(s:real^N->bool) + &1` THEN
4767 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(INT_ARITH
4768 `s:int <= n /\ ~(s = n) ==> s + &1 <= n`) THEN
4769 ASM_REWRITE_TAC[AFF_DIM_LE_UNIV];
4770 SUBGOAL_THEN `?a:real^N. a IN s /\ ~(a IN t)` MP_TAC THENL
4771 [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
4772 X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4774 `(convex hull t) SUBSET convex hull (s DELETE (a:real^N))`
4776 [MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]; ASM SET_TAC[]]];
4777 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[UNIONS_IMAGE] THEN
4778 REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4779 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
4780 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; GSYM SUBSET] THEN
4781 REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MONO THEN SET_TAC[]]];
4782 MATCH_MP_TAC EQ_TRANS THEN
4784 `(convex hull s) DIFF relative_interior(convex hull s):real^N->bool` THEN
4786 [ASM_SIMP_TAC[GSYM RELATIVE_BOUNDARY_OF_CONVEX_HULL; frontier] THEN
4788 [MATCH_MP_TAC CLOSURE_CLOSED THEN
4789 ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL;
4790 FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY];
4791 CONV_TAC SYM_CONV THEN MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN
4792 REWRITE_TAC[AFFINE_HULL_CONVEX_HULL] THEN
4793 REWRITE_TAC[GSYM AFF_DIM_EQ_FULL] THEN
4794 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
4795 [AFFINE_INDEPENDENT_IFF_CARD]) THEN
4796 ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC];
4797 ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON;
4798 POLYHEDRON_CONVEX_HULL; FINITE_INSERT; FINITE_EMPTY] THEN
4799 ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT] THEN
4800 REWRITE_TAC[ARITH_RULE `2 <= n + 1 <=> 1 <= n`; DIMINDEX_GE_1] THEN
4803 (* ------------------------------------------------------------------------- *)
4804 (* Special case of a triangle. *)
4805 (* ------------------------------------------------------------------------- *)
4807 let RELATIVE_BOUNDARY_OF_TRIANGLE = prove
4810 ==> convex hull {a,b,c} DIFF relative_interior(convex hull {a,b,c}) =
4811 segment[a,b] UNION segment[b,c] UNION segment[c,a]`,
4812 REPEAT STRIP_TAC THEN
4813 ONCE_REWRITE_TAC[SET_RULE `s UNION t UNION u = t UNION u UNION s`] THEN
4814 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV
4815 [COLLINEAR_3_EQ_AFFINE_DEPENDENT]) THEN
4816 REWRITE_TAC[DE_MORGAN_THM; SEGMENT_CONVEX_HULL] THEN STRIP_TAC THEN
4817 ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_CONVEX_HULL] THEN
4818 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
4819 REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; UNIONS_0; UNION_EMPTY] THEN
4820 REPEAT BINOP_TAC THEN REWRITE_TAC[] THEN ASM SET_TAC[]);;
4822 let RELATIVE_FRONTIER_OF_TRIANGLE = prove
4825 ==> relative_frontier(convex hull {a,b,c}) =
4826 segment[a,b] UNION segment[b,c] UNION segment[c,a]`,
4827 REPEAT STRIP_TAC THEN
4828 ASM_SIMP_TAC[GSYM RELATIVE_BOUNDARY_OF_TRIANGLE; relative_frontier] THEN
4829 AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC CLOSURE_CLOSED THEN
4830 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL;
4831 FINITE_INSERT; FINITE_EMPTY]);;
4833 let FRONTIER_OF_TRIANGLE = prove
4835 frontier(convex hull {a,b,c}) =
4836 segment[a,b] UNION segment[b,c] UNION segment[c,a]`,
4837 REPEAT STRIP_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN
4838 ONCE_REWRITE_TAC[SET_RULE `s UNION t UNION u = t UNION u UNION s`] THEN
4839 MAP_EVERY (fun t -> ASM_CASES_TAC t THENL
4840 [ASM_REWRITE_TAC[INSERT_AC; UNION_ACI] THEN
4841 SIMP_TAC[GSYM SEGMENT_CONVEX_HULL; frontier; CLOSURE_SEGMENT;
4842 INTERIOR_SEGMENT; DIMINDEX_2; LE_REFL; DIFF_EMPTY] THEN
4843 REWRITE_TAC[CONVEX_HULL_SING] THEN
4844 REWRITE_TAC[SET_RULE `s = s UNION {a} <=> a IN s`;
4845 SET_RULE `s = {a} UNION s <=> a IN s`] THEN
4846 REWRITE_TAC[ENDS_IN_SEGMENT];
4848 [`b:real^2 = a`; `c:real^2 = a`; `c:real^2 = b`] THEN
4849 SUBGOAL_THEN `{a:real^2,b,c} HAS_SIZE (dimindex(:2) + 1)` ASSUME_TAC THENL
4850 [SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
4851 ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; DIMINDEX_2] THEN
4852 CONV_TAC NUM_REDUCE_CONV;
4853 ASM_SIMP_TAC[FRONTIER_OF_CONVEX_HULL] THEN
4854 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
4855 REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; UNIONS_0; UNION_EMPTY] THEN
4856 REPEAT BINOP_TAC THEN REWRITE_TAC[] THEN ASM SET_TAC[]]);;
4858 let INSIDE_OF_TRIANGLE = prove
4860 inside(segment[a,b] UNION segment[b,c] UNION segment[c,a]) =
4861 interior(convex hull {a,b,c})`,
4862 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FRONTIER_OF_TRIANGLE] THEN
4863 MATCH_MP_TAC INSIDE_FRONTIER_EQ_INTERIOR THEN
4864 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN
4865 MATCH_MP_TAC FINITE_IMP_BOUNDED THEN
4866 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY]);;
4868 let INTERIOR_OF_TRIANGLE = prove
4870 interior(convex hull {a,b,c}) =
4871 (convex hull {a,b,c}) DIFF
4872 (segment[a,b] UNION segment[b,c] UNION segment[c,a])`,
4873 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FRONTIER_OF_TRIANGLE; frontier] THEN
4874 MATCH_MP_TAC(SET_RULE `i SUBSET s /\ c = s ==> i = s DIFF (c DIFF i)`) THEN
4875 REWRITE_TAC[INTERIOR_SUBSET] THEN MATCH_MP_TAC CLOSURE_CONVEX_HULL THEN
4876 SIMP_TAC[FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]);;
4878 (* ------------------------------------------------------------------------- *)
4879 (* A ridge is the intersection of precisely two facets. *)
4880 (* ------------------------------------------------------------------------- *)
4882 let POLYHEDRON_RIDGE_TWO_FACETS = prove
4883 (`!p:real^N->bool r.
4884 polyhedron p /\ r face_of p /\ ~(r = {}) /\ aff_dim r = aff_dim p - &2
4885 ==> ?f1 f2. f1 face_of p /\ aff_dim f1 = aff_dim p - &1 /\
4886 f2 face_of p /\ aff_dim f2 = aff_dim p - &1 /\
4887 ~(f1 = f2) /\ r SUBSET f1 /\ r SUBSET f2 /\ f1 INTER f2 = r /\
4888 !f. f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f
4889 ==> f = f1 \/ f = f2`,
4890 REPEAT STRIP_TAC THEN
4891 MP_TAC(ISPECL [`p:real^N->bool`; `r:real^N->bool`] FACE_OF_POLYHEDRON) THEN
4892 ANTS_TAC THENL [ASM_MESON_TAC[INT_ARITH `~(p:int = p - &2)`]; ALL_TAC] THEN
4893 SUBGOAL_THEN `&2 <= aff_dim(p:real^N->bool)` ASSUME_TAC THENL
4894 [MP_TAC(ISPEC `r:real^N->bool` AFF_DIM_GE) THEN
4895 MP_TAC(ISPEC `r:real^N->bool` AFF_DIM_EQ_MINUS1) THEN
4896 ASM_REWRITE_TAC[] THEN INT_ARITH_TAC;
4899 `{f:real^N->bool | f facet_of p /\ r SUBSET f} =
4900 {f | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}`
4902 [GEN_REWRITE_TAC I [EXTENSION] THEN
4903 ASM_REWRITE_TAC[IN_ELIM_THM; facet_of] THEN
4904 X_GEN_TAC `f:real^N->bool` THEN
4905 ASM_CASES_TAC `f:real^N->bool = {}` THEN
4906 ASM_REWRITE_TAC[AFF_DIM_EMPTY; GSYM CONJ_ASSOC] THEN ASM_INT_ARITH_TAC;
4907 DISCH_THEN(MP_TAC o SYM)] THEN
4909 `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}
4912 [ASM_REWRITE_TAC[INTERS_0] THEN DISCH_THEN(ASSUME_TAC o SYM) THEN
4913 UNDISCH_TAC `aff_dim(r:real^N->bool) = aff_dim(p:real^N->bool) - &2` THEN
4914 ASM_REWRITE_TAC[AFF_DIM_UNIV; DIMINDEX_3] THEN
4915 MP_TAC(ISPEC `p:real^N->bool` AFF_DIM_LE_UNIV) THEN INT_ARITH_TAC;
4917 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
4918 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN
4919 X_GEN_TAC `f1:real^N->bool` THEN STRIP_TAC THEN
4921 `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}
4924 [ASM_REWRITE_TAC[INTERS_1] THEN
4925 ASM_MESON_TAC[INT_ARITH `~(x - &2:int = x - &1)`];
4927 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
4928 `~(s = {a}) ==> a IN s ==> ?b. ~(b = a) /\ b IN s`)) THEN
4929 ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4930 X_GEN_TAC `f2:real^N->bool` THEN STRIP_TAC THEN
4932 `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}
4935 [ASM_REWRITE_TAC[INTERS_2] THEN DISCH_TAC THEN
4936 MAP_EVERY EXISTS_TAC [`f1:real^N->bool`; `f2:real^N->bool`] THEN
4937 ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
4939 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
4941 ==> a IN s /\ b IN s ==> ?c. ~(c = a) /\ ~(c = b) /\ c IN s`)) THEN
4942 ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4943 X_GEN_TAC `f3:real^N->bool` THEN STRIP_TAC THEN DISCH_TAC THEN
4944 UNDISCH_TAC `aff_dim(r:real^N->bool) = aff_dim(p:real^N->bool) - &2` THEN
4945 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
4946 MATCH_MP_TAC(INT_ARITH `~(p - &2:int <= x:int) ==> ~(x = p - &2)`) THEN
4947 DISCH_TAC THEN SUBGOAL_THEN
4948 `~(f1:real^N->bool = {}) /\
4949 ~(f2:real^N->bool = {}) /\
4950 ~(f3:real^N->bool = {})`
4951 STRIP_ASSUME_TAC THENL
4952 [REPEAT CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN
4953 RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_EMPTY]) THEN ASM_INT_ARITH_TAC;
4955 MP_TAC(ISPEC `p:real^N->bool` POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL) THEN
4956 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
4957 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
4958 ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
4959 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
4960 `b:(real^N->bool)->real`] THEN
4961 ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
4962 REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = v <=> v = vec 0`] THEN
4963 STRIP_TAC THEN MP_TAC(ISPECL
4964 [`p:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
4965 `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN
4966 ASM_SIMP_TAC[] THEN DISCH_THEN(fun th ->
4967 MP_TAC(SPEC `f1:real^N->bool` th) THEN
4968 MP_TAC(SPEC `f2:real^N->bool` th) THEN
4969 MP_TAC(SPEC `f3:real^N->bool` th)) THEN
4970 ASM_REWRITE_TAC[facet_of] THEN
4971 DISCH_THEN(X_CHOOSE_THEN `h3:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
4972 DISCH_THEN(X_CHOOSE_THEN `h2:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
4973 DISCH_THEN(X_CHOOSE_THEN `h1:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
4974 SUBGOAL_THEN `~((a:(real^N->bool)->real^N) h1 = a h2) /\
4975 ~(a h2 = a h3) /\ ~(a h1 = a h3)`
4976 STRIP_ASSUME_TAC THENL
4977 [REPEAT CONJ_TAC THENL
4978 [DISJ_CASES_TAC(REAL_ARITH
4979 `b(h1:real^N->bool) <= b h2 \/ b h2 <= b h1`)
4981 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`);
4982 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN
4983 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4984 MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN
4986 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
4989 [SUBGOAL_THEN `f DELETE h2 = h1 INSERT (f DIFF {h1,h2}) /\
4990 f = (h2:real^N->bool) INSERT h1 INSERT (f DIFF {h1,h2})`
4991 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
4992 SUBGOAL_THEN `f DELETE h1 = h2 INSERT (f DIFF {h1,h2}) /\
4993 f = (h1:real^N->bool) INSERT h2 INSERT (f DIFF {h1,h2})`
4994 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
4995 REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE
4996 `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN
4997 FIRST_X_ASSUM(fun th ->
4998 MP_TAC(SPEC `h1:real^N->bool` th) THEN
4999 MP_TAC(SPEC `h2:real^N->bool` th)) THEN
5000 ASM_REWRITE_TAC[IMP_IMP] THEN
5001 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
5002 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC;
5003 DISJ_CASES_TAC(REAL_ARITH
5004 `b(h2:real^N->bool) <= b h3 \/ b h3 <= b h2`)
5006 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`);
5007 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`)] THEN
5008 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5009 MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN
5011 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
5014 [SUBGOAL_THEN `f DELETE h3 = h2 INSERT (f DIFF {h2,h3}) /\
5015 f = (h3:real^N->bool) INSERT h2 INSERT (f DIFF {h2,h3})`
5016 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
5017 SUBGOAL_THEN `f DELETE h2 = h3 INSERT (f DIFF {h2,h3}) /\
5018 f = (h2:real^N->bool) INSERT h3 INSERT (f DIFF {h2,h3})`
5019 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
5020 REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE
5021 `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN
5022 FIRST_X_ASSUM(fun th ->
5023 MP_TAC(SPEC `h2:real^N->bool` th) THEN
5024 MP_TAC(SPEC `h3:real^N->bool` th)) THEN
5025 ASM_REWRITE_TAC[IMP_IMP] THEN
5026 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
5027 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC;
5028 DISJ_CASES_TAC(REAL_ARITH
5029 `b(h1:real^N->bool) <= b h3 \/ b h3 <= b h1`)
5031 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`);
5032 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN
5033 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5034 MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN
5036 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
5039 [SUBGOAL_THEN `f DELETE h3 = h1 INSERT (f DIFF {h1,h3}) /\
5040 f = (h3:real^N->bool) INSERT h1 INSERT (f DIFF {h1,h3})`
5041 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
5042 SUBGOAL_THEN `f DELETE h1 = h3 INSERT (f DIFF {h1,h3}) /\
5043 f = (h1:real^N->bool) INSERT h3 INSERT (f DIFF {h1,h3})`
5044 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
5045 REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE
5046 `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN
5047 FIRST_X_ASSUM(fun th ->
5048 MP_TAC(SPEC `h1:real^N->bool` th) THEN
5049 MP_TAC(SPEC `h3:real^N->bool` th)) THEN
5050 ASM_REWRITE_TAC[IMP_IMP] THEN
5051 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
5052 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC];
5055 `~({x | a h1 dot x <= b h1} INTER {x | a h2 dot x <= b h2}
5056 SUBSET {x | a h3 dot x <= b h3}) /\
5057 ~({x | a h1 dot x <= b h1} INTER {x | a h3 dot x <= b h3}
5058 SUBSET {x | a h2 dot x <= b h2}) /\
5059 ~({x | a h2 dot x <= b h2} INTER {x | a h3 dot x <= b h3}
5060 SUBSET {x:real^N | a(h1:real^N->bool) dot x <= b h1})`
5062 [ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THENL
5063 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`);
5064 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`);
5065 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN
5066 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5067 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC
5068 (LAND_CONV o LAND_CONV) [SYM th]) THEN
5069 MATCH_MP_TAC(SET_RULE `s = t ==> s PSUBSET t ==> F`) THEN
5073 `f DELETE (h3:real^N->bool) = h1 INSERT h2 INSERT (f DELETE h3) /\
5074 f = h1 INSERT h2 INSERT h3 INSERT (f DELETE h3)`
5075 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
5077 `f DELETE (h2:real^N->bool) = h1 INSERT h3 INSERT (f DELETE h2) /\
5078 f = h2 INSERT h1 INSERT h3 INSERT (f DELETE h2)`
5079 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
5081 `f DELETE (h1:real^N->bool) = h2 INSERT h3 INSERT (f DELETE h1) /\
5082 f = h1 INSERT h2 INSERT h3 INSERT (f DELETE h1)`
5083 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
5084 REWRITE_TAC[INTERS_INSERT] THEN REWRITE_TAC[GSYM INTER_ASSOC] THEN
5085 AP_THM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[];
5088 `?w. (a:(real^N->bool)->real^N) h1 dot w < b h1 /\
5089 a h2 dot w < b h2 /\ a h3 dot w < b h3`
5090 (CHOOSE_THEN MP_TAC)
5092 [SUBGOAL_THEN `~(relative_interior p :real^N->bool = {})` MP_TAC THENL
5093 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYHEDRON_IMP_CONVEX] THEN
5097 [`p:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
5098 `b:(real^N->bool)->real`] RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
5099 ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN
5100 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
5101 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
5102 DISCH_THEN(MP_TAC o CONJUNCT2) THEN ASM_SIMP_TAC[];
5105 `!x. x IN r ==> (a h1) dot (x:real^N) = b h1 /\
5106 (a h2) dot x = b h2 /\
5107 (a (h3:real^N->bool)) dot x = b h3`
5108 MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5109 SUBGOAL_THEN `?z:real^N. z IN r` CHOOSE_TAC THENL
5110 [ASM SET_TAC[]; ALL_TAC] THEN
5111 MAP_EVERY UNDISCH_TAC
5112 [`~((a:(real^N->bool)->real^N) h1 = a h2)`;
5113 `~((a:(real^N->bool)->real^N) h1 = a h3)`;
5114 `~((a:(real^N->bool)->real^N) h2 = a h3)`;
5115 `aff_dim(p:real^N->bool) - &2 <= aff_dim(r:real^N->bool)`] THEN
5117 FIRST_X_ASSUM(fun th -> MP_TAC(SPEC t th) THEN ASM_REWRITE_TAC[] THEN
5119 DISCH_THEN(MP_TAC o SPEC `z:real^N` o CONJUNCT2 o CONJUNCT2))
5120 [`h1:real^N->bool`; `h2:real^N->bool`; `h3:real^N->bool`] THEN
5121 SUBGOAL_THEN `(z:real^N) IN (affine hull p)` ASSUME_TAC THENL
5122 [MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[];
5123 ASM_REWRITE_TAC[]] THEN
5124 UNDISCH_TAC `(z:real^N) IN (affine hull p)` THEN
5125 SUBGOAL_THEN `(a h1) dot (z:real^N) = b h1 /\
5126 (a h2) dot z = b h2 /\
5127 (a (h3:real^N->bool)) dot z = b h3`
5128 (REPEAT_TCL CONJUNCTS_THEN (SUBST1_TAC o SYM))
5129 THENL [ASM SET_TAC[]; ALL_TAC] THEN
5130 SUBGOAL_THEN `(r:real^N->bool) SUBSET affine hull p` MP_TAC THENL
5131 [ASM_MESON_TAC[FACE_OF_IMP_SUBSET; HULL_SUBSET; SUBSET_TRANS]; ALL_TAC] THEN
5133 `~((a:(real^N->bool)->real^N) h1 = vec 0) /\
5134 ~((a:(real^N->bool)->real^N) h2 = vec 0) /\
5135 ~((a:(real^N->bool)->real^N) h3 = vec 0)`
5136 MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
5137 UNDISCH_TAC `(z:real^N) IN r` THEN POP_ASSUM_LIST(K ALL_TAC) THEN
5139 [`(a:(real^N->bool)->real^N) h1`,`a1:real^N`;
5140 `(a:(real^N->bool)->real^N) h2`,`a2:real^N`;
5141 `(a:(real^N->bool)->real^N) h3`,`a3:real^N`] THEN
5143 GEN_GEOM_ORIGIN_TAC `z:real^N` ["a1"; "a2"; "a3"] THEN
5144 REWRITE_TAC[VECTOR_ADD_RID; VECTOR_ADD_LID] THEN
5145 REWRITE_TAC[DOT_RADD; IMAGE_CLAUSES;
5146 REAL_ARITH `a + b:real <= a <=> b <= &0`;
5147 REAL_ARITH `a + b:real < a <=> b < &0`;
5148 REAL_ARITH `a + b:real = a <=> b = &0`] THEN
5150 REPEAT STRIP_TAC THEN
5151 SUBGOAL_THEN `aff_dim(p:real^N->bool) = &(dim p)` SUBST_ALL_TAC THENL
5152 [ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]; ALL_TAC] THEN
5153 SUBGOAL_THEN `aff_dim(r:real^N->bool) = &(dim r)` SUBST_ALL_TAC THENL
5154 [ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]; ALL_TAC] THEN
5155 RULE_ASSUM_TAC(REWRITE_RULE[INT_OF_NUM_ADD; INT_OF_NUM_LE;
5156 INT_ARITH `p - &2:int <= q <=> p <= q + &2`]) THEN
5158 [`{a1:real^N,a2,a3}`; `r:real^N->bool`] DIM_ORTHOGONAL_SUM) THEN
5159 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5160 ASM_SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN
5161 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE
5162 `p <= r + 2 ==> u <= p /\ 3 <= t ==> ~(u = t + r)`)) THEN
5163 SUBGOAL_THEN `affine hull p :real^N->bool = span p` SUBST_ALL_TAC THENL
5164 [ASM_MESON_TAC[AFFINE_HULL_EQ_SPAN]; ALL_TAC] THEN
5166 [GEN_REWRITE_TAC RAND_CONV [GSYM DIM_SPAN] THEN
5167 MATCH_MP_TAC DIM_SUBSET THEN ASM SET_TAC[];
5169 MP_TAC(ISPEC `{a1:real^N,a2,a3}` DEPENDENT_BIGGERSET_GENERAL) THEN
5170 SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; ARITH] THEN
5171 ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH] THEN
5172 GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
5173 REWRITE_TAC[ARITH_RULE `~(3 > x) <=> 3 <= x`] THEN
5174 DISCH_THEN MATCH_MP_TAC THEN
5175 REWRITE_TAC[dependent; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN
5176 ASM_REWRITE_TAC[DELETE_INSERT; EMPTY_DELETE] THEN
5177 REWRITE_TAC[SPAN_2; IN_ELIM_THM; IN_UNIV] THEN
5178 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN
5179 W(fun (asl,w) -> let fv = frees w
5180 and av = [`a1:real^N`; `a2:real^N`; `a3:real^N`] in
5181 MAP_EVERY (fun t -> SPEC_TAC(t,t)) (subtract fv av @ av)) THEN
5182 REWRITE_TAC[LEFT_FORALL_IMP_THM] THEN
5183 MATCH_MP_TAC(MESON[]
5184 `(!a1 a2 a3. P a1 a2 a3 ==> P a2 a1 a3 /\ P a3 a1 a2) /\
5185 (!a1 a2 a3. Q a1 a2 a3 ==> ~(P a1 a2 a3))
5186 ==> !a3 a2 a1. P a1 a2 a3
5187 ==> ~(Q a1 a2 a3 \/ Q a2 a1 a3 \/ Q a3 a1 a2)`) THEN
5189 [REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
5190 `(p ==> q) /\ (p ==> r) ==> p ==> q /\ r`) THEN
5191 CONJ_TAC THEN REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
5192 REWRITE_TAC[CONJ_ACI] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
5195 REPEAT GEN_TAC THEN DISCH_THEN
5196 (X_CHOOSE_THEN `u:real` (X_CHOOSE_TAC `v:real`)) THEN
5197 REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT GEN_TAC THEN
5198 ASM_CASES_TAC `u = &0` THENL
5199 [ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO] THEN
5200 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH
5201 `v = &0 \/ &0 < v \/ &0 < --v`)
5203 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO];
5204 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b <= &0 <=> &0 <= a * --b`] THEN
5205 ASM_SIMP_TAC[REAL_LE_MUL_EQ] THEN
5206 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN REAL_ARITH_TAC;
5207 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b < &0 <=> &0 < --a * b`] THEN
5208 ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN REAL_ARITH_TAC];
5210 ASM_CASES_TAC `v = &0` THENL
5211 [ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_MUL_LZERO] THEN
5212 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH
5213 `u = &0 \/ &0 < u \/ &0 < --u`)
5215 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO];
5216 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b <= &0 <=> &0 <= a * --b`] THEN
5217 ASM_SIMP_TAC[REAL_LE_MUL_EQ] THEN
5218 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN REAL_ARITH_TAC;
5219 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b < &0 <=> &0 < --a * b`] THEN
5220 ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN REAL_ARITH_TAC];
5224 `&0 < u /\ &0 < v \/ &0 < u /\ &0 < --v \/
5225 &0 < --u /\ &0 < v \/ &0 < --u /\ &0 < --v`
5226 STRIP_ASSUME_TAC THENL
5227 [ASM_REAL_ARITH_TAC;
5229 `~({x | a2 dot x <= &0} INTER {x | a3 dot x <= &0} SUBSET
5230 {x:real^N | a1 dot x <= &0})` THEN
5231 ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
5232 REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5233 REWRITE_TAC[REAL_ARITH `x <= &0 <=> &0 <= --x`] THEN
5234 REWRITE_TAC[REAL_NEG_ADD; GSYM REAL_MUL_RNEG] THEN
5235 ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_ADD; REAL_LT_IMP_LE];
5237 `~({x | a1 dot x <= &0} INTER {x | a3 dot x <= &0} SUBSET
5238 {x:real^N | a2 dot x <= &0})` THEN
5239 ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
5240 GEN_TAC THEN REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5241 MATCH_MP_TAC(REAL_ARITH
5242 `(&0 < u * a2 <=> &0 < a2) /\ (&0 < --v * a3 <=> &0 < a3)
5243 ==> u * a2 + v * a3 <= &0 /\ a3 <= &0 ==> a2 <= &0`) THEN
5244 ASM_SIMP_TAC[REAL_LT_MUL_EQ];
5246 `~({x | a1 dot x <= &0} INTER {x | a2 dot x <= &0} SUBSET
5247 {x:real^N | a3 dot x <= &0})` THEN
5248 ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
5249 GEN_TAC THEN REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5250 MATCH_MP_TAC(REAL_ARITH
5251 `(&0 < --u * a2 <=> &0 < a2) /\ (&0 < v * a3 <=> &0 < a3)
5252 ==> u * a2 + v * a3 <= &0 /\ a2 <= &0 ==> a3 <= &0`) THEN
5253 ASM_SIMP_TAC[REAL_LT_MUL_EQ];
5254 UNDISCH_TAC `(a1:real^N) dot w < &0` THEN
5255 ASM_REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5256 MATCH_MP_TAC(REAL_ARITH
5257 `&0 < --u * --a /\ &0 < --v * --b ==> ~(u * a + v * b < &0)`) THEN
5258 CONJ_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC]);;
5260 (* ------------------------------------------------------------------------- *)
5261 (* Lower bounds on then number of 0 and n-1 dimensional faces. *)
5262 (* ------------------------------------------------------------------------- *)
5264 let POLYTOPE_VERTEX_LOWER_BOUND = prove
5266 polytope p ==> aff_dim p + &1 <= &(CARD {v | v extreme_point_of p})`,
5267 REPEAT STRIP_TAC THEN
5268 MATCH_MP_TAC INT_LE_TRANS THEN
5269 EXISTS_TAC `aff_dim(convex hull {v:real^N | v extreme_point_of p}) + &1` THEN
5271 [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; POLYTOPE_IMP_CONVEX;
5272 POLYTOPE_IMP_COMPACT; INT_LE_REFL];
5273 REWRITE_TAC[AFF_DIM_CONVEX_HULL; GSYM INT_LE_SUB_LADD] THEN
5274 MATCH_MP_TAC AFF_DIM_LE_CARD THEN
5275 MATCH_MP_TAC FINITE_POLYHEDRON_EXTREME_POINTS THEN
5276 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON]]);;
5278 let POLYTOPE_FACET_LOWER_BOUND = prove
5280 polytope p /\ ~(aff_dim p = &0)
5281 ==> aff_dim p + &1 <= &(CARD {f | f facet_of p})`,
5282 GEN_TAC THEN ASM_CASES_TAC `p:real^N->bool = {}` THEN
5283 ASM_SIMP_TAC[AFF_DIM_EMPTY; FACET_OF_EMPTY; EMPTY_GSPEC; CARD_CLAUSES] THEN
5284 CONV_TAC INT_REDUCE_CONV THEN STRIP_TAC THEN
5286 `?n. {f:real^N->bool | f facet_of p} HAS_SIZE n /\ aff_dim p + &1 <= &n`
5287 (fun th -> MESON_TAC[th; HAS_SIZE]) THEN
5288 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
5289 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
5290 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN
5291 GEOM_ORIGIN_TAC `z:real^N` THEN REPEAT GEN_TAC THEN REPEAT STRIP_TAC THEN
5292 EXISTS_TAC `CARD {f:real^N->bool | f facet_of p}` THEN
5293 ASM_SIMP_TAC[FINITE_POLYTOPE_FACETS; HAS_SIZE] THEN
5294 UNDISCH_TAC `~(aff_dim(p:real^N->bool) = &0)` THEN
5295 ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; INT_OF_NUM_ADD; INT_OF_NUM_LE] THEN
5296 REWRITE_TAC[INT_OF_NUM_EQ] THEN DISCH_TAC THEN
5297 MP_TAC(ISPEC `p:real^N->bool` POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL) THEN
5298 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON] THEN
5299 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
5300 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
5301 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
5302 [`H:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
5303 `b:(real^N->bool)->real`] THEN
5304 ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
5305 REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = v <=> v = vec 0`] THEN
5306 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN
5307 STRIP_TAC THEN MP_TAC(ISPECL
5308 [`p:real^N->bool`; `H:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
5309 `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN
5310 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN DISCH_THEN(K ALL_TAC) THEN
5311 SUBGOAL_THEN `!h:real^N->bool. h IN H ==> &0 <= b h` ASSUME_TAC THENL
5312 [UNDISCH_TAC `(vec 0:real^N) IN p` THEN EXPAND_TAC "p" THEN
5313 REWRITE_TAC[IN_INTER; IN_INTERS] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN
5314 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `h:real^N->bool` THEN
5315 ASM_CASES_TAC `(h:real^N->bool) IN H` THEN ASM_REWRITE_TAC[] THEN
5316 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
5317 DISCH_THEN(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM t]) THEN
5318 REWRITE_TAC[IN_ELIM_THM; DOT_RZERO];
5320 MATCH_MP_TAC LE_TRANS THEN
5321 EXISTS_TAC `(CARD(H:(real^N->bool)->bool))` THEN CONJ_TAC THENL
5322 [MATCH_MP_TAC(ARITH_RULE `~(h <= a) ==> a + 1 <= h`) THEN DISCH_TAC THEN
5323 ASM_CASES_TAC `H:(real^N->bool)->bool = {}` THENL
5324 [UNDISCH_THEN `H:(real^N->bool)->bool = {}` SUBST_ALL_TAC THEN
5325 RULE_ASSUM_TAC(REWRITE_RULE[INTERS_0; INTER_UNIV]) THEN
5326 UNDISCH_TAC `~(dim(p:real^N->bool) = 0)` THEN
5327 REWRITE_TAC[DIM_EQ_0] THEN EXPAND_TAC "p" THEN
5328 REWRITE_TAC[ASSUME `H:(real^N->bool)->bool = {}`; INTERS_0] THEN
5329 REWRITE_TAC[INTER_UNIV] THEN
5330 ASM_CASES_TAC `?n:real^N. n IN span p /\ ~(n = vec 0)` THENL
5331 [ALL_TAC; ASM SET_TAC[]] THEN
5332 FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN
5333 FIRST_ASSUM(MP_TAC o MATCH_MP POLYTOPE_IMP_BOUNDED) THEN
5334 REWRITE_TAC[BOUNDED_POS] THEN DISCH_THEN(X_CHOOSE_THEN `B:real`
5335 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5336 DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm n % n:real^N`) THEN
5337 ANTS_TAC THENL [ASM_MESON_TAC[SPAN_MUL]; ALL_TAC] THEN
5338 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
5339 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN REAL_ARITH_TAC;
5341 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
5342 DISCH_THEN(X_CHOOSE_TAC `h:real^N->bool`) THEN
5344 `span(IMAGE (a:(real^N->bool)->real^N) (H DELETE h))
5347 [REWRITE_TAC[PSUBSET] THEN CONJ_TAC THENL
5348 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
5349 REWRITE_TAC[SUBSPACE_SPAN; SUBSET; FORALL_IN_IMAGE; IN_DELETE] THEN
5350 ASM_MESON_TAC[SPAN_ADD; SPAN_SUPERSET; VECTOR_ADD_LID];
5351 DISCH_THEN(MP_TAC o AP_TERM `dim:(real^N->bool)->num`) THEN
5352 REWRITE_TAC[DIM_SPAN] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
5353 (ARITH_RULE `h <= p ==> h':num < h ==> ~(h' = p)`)) THEN
5354 MATCH_MP_TAC LET_TRANS THEN
5355 EXISTS_TAC `CARD(IMAGE (a:(real^N->bool)->real^N) (H DELETE h))` THEN
5356 ASM_SIMP_TAC[DIM_LE_CARD; FINITE_DELETE; FINITE_IMAGE] THEN
5357 MATCH_MP_TAC LET_TRANS THEN
5358 EXISTS_TAC `CARD(H DELETE (h:real^N->bool))` THEN
5359 ASM_SIMP_TAC[CARD_IMAGE_LE; FINITE_DELETE] THEN
5360 ASM_SIMP_TAC[CARD_DELETE; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
5361 ASM_SIMP_TAC[CARD_EQ_0] THEN ASM SET_TAC[]];
5362 DISCH_THEN(MP_TAC o MATCH_MP ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN)] THEN
5363 REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `n:real^N` THEN STRIP_TAC THEN
5364 FIRST_ASSUM(MP_TAC o MATCH_MP POLYTOPE_IMP_BOUNDED) THEN
5365 REWRITE_TAC[BOUNDED_POS] THEN
5366 DISCH_THEN(X_CHOOSE_THEN `B:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5367 DISJ_CASES_TAC(REAL_ARITH
5368 `&0 <= (a:(real^N->bool)->real^N) h dot n \/
5369 &0 <= --((a:(real^N->bool)->real^N) h dot n)`)
5371 [DISCH_THEN(MP_TAC o SPEC `--(B + &1) / norm(n) % n:real^N`);
5372 DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm(n) % n:real^N`)] THEN
5373 (ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM;
5374 REAL_DIV_RMUL; NORM_EQ_0; REAL_ABS_NEG;
5375 REAL_ARITH `~(abs(B + &1) <= B)`] THEN
5376 EXPAND_TAC "p" THEN REWRITE_TAC[IN_INTER; IN_INTERS] THEN
5377 ASM_SIMP_TAC[SPAN_MUL] THEN X_GEN_TAC `k:real^N->bool` THEN
5379 SUBGOAL_THEN `k = {x:real^N | a k dot x <= b k}` SUBST1_TAC THENL
5380 [ASM_SIMP_TAC[]; ALL_TAC] THEN
5381 ASM_CASES_TAC `k:real^N->bool = h` THEN
5382 ASM_REWRITE_TAC[IN_ELIM_THM; DOT_RMUL] THENL
5384 MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 <= y ==> x <= y`) THEN
5385 ASM_SIMP_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN
5386 FIRST_X_ASSUM(MP_TAC o SPEC `(a:(real^N->bool)->real^N) k`) THEN
5387 REWRITE_TAC[orthogonal; DOT_SYM] THEN DISCH_THEN MATCH_MP_TAC THEN
5388 MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]]) THENL
5389 [MATCH_MP_TAC(REAL_ARITH `&0 <= --x * y /\ &0 <= z ==> x * y <= z`);
5390 MATCH_MP_TAC(REAL_ARITH `&0 <= x * --y /\ &0 <= z ==> x * y <= z`)] THEN
5391 ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN
5392 REWRITE_TAC[REAL_ARITH `--a / b:real = --(a / b)`; REAL_NEG_NEG] THEN
5393 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; NORM_POS_LT] THEN ASM_REAL_ARITH_TAC;
5394 REWRITE_TAC[SET_RULE `{f | ?h. h IN s /\ f = g h} = IMAGE g s`] THEN
5395 MATCH_MP_TAC(ARITH_RULE `m:num = n ==> n <= m`) THEN
5396 MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN
5397 MATCH_MP_TAC FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT THEN
5398 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC]]);;
5400 (* ------------------------------------------------------------------------- *)
5401 (* The notion of n-simplex where n is an integer >= -1. *)
5402 (* ------------------------------------------------------------------------- *)
5404 parse_as_infix("simplex",(12,"right"));;
5406 let simplex = new_definition
5407 `n simplex s <=> ?c. ~(affine_dependent c) /\
5408 &(CARD c):int = n + &1 /\
5409 s = convex hull c`;;
5412 (`n simplex s <=> ?c. FINITE c /\
5413 ~(affine_dependent c) /\
5414 &(CARD c):int = n + &1 /\
5416 REWRITE_TAC[simplex] THEN MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);;
5418 let CONVEX_SIMPLEX = prove
5419 (`!n s. n simplex s ==> convex s`,
5420 REWRITE_TAC[simplex] THEN MESON_TAC[CONVEX_CONVEX_HULL]);;
5422 let COMPACT_SIMPLEX = prove
5423 (`!n s. n simplex s ==> compact s`,
5424 REWRITE_TAC[SIMPLEX] THEN
5425 MESON_TAC[FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);;
5427 let CLOSED_SIMPLEX = prove
5428 (`!s n. n simplex s ==> closed s`,
5429 MESON_TAC[COMPACT_SIMPLEX; COMPACT_IMP_CLOSED]);;
5431 let SIMPLEX_IMP_POLYTOPE = prove
5432 (`!n s. n simplex s ==> polytope s`,
5433 REWRITE_TAC[simplex; polytope] THEN
5434 MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);;
5436 let SIMPLEX_DIM_GE = prove
5437 (`!n s. n simplex s ==> -- &1 <= n`,
5438 REWRITE_TAC[simplex] THEN INT_ARITH_TAC);;
5440 let SIMPLEX_EMPTY = prove
5441 (`!n. n simplex {} <=> n = -- &1`,
5442 GEN_TAC THEN REWRITE_TAC[SIMPLEX] THEN
5443 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
5444 REWRITE_TAC[CONVEX_HULL_EQ_EMPTY; CONJ_ASSOC] THEN
5445 ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN
5446 REWRITE_TAC[FINITE_EMPTY; CARD_CLAUSES; AFFINE_INDEPENDENT_EMPTY] THEN
5449 let SIMPLEX_MINUS_1 = prove
5450 (`!s. (-- &1) simplex s <=> s = {}`,
5451 GEN_TAC THEN REWRITE_TAC[SIMPLEX; INT_ADD_LINV; INT_OF_NUM_EQ] THEN
5452 ONCE_REWRITE_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN
5453 SIMP_TAC[CARD_EQ_0] THEN REWRITE_TAC[NOT_IMP] THEN
5454 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN
5455 REWRITE_TAC[UNWIND_THM2; FINITE_EMPTY; AFFINE_INDEPENDENT_EMPTY] THEN
5456 REWRITE_TAC[CONVEX_HULL_EMPTY]);;
5458 let AFF_DIM_SIMPLEX = prove
5459 (`!s n. n simplex s ==> aff_dim s = n`,
5460 REWRITE_TAC[simplex; INT_ARITH `x:int = n + &1 <=> n = x - &1`] THEN
5461 REPEAT STRIP_TAC THEN
5462 ASM_SIMP_TAC[AFF_DIM_CONVEX_HULL; AFF_DIM_AFFINE_INDEPENDENT]);;
5464 let SIMPLEX_EXTREME_POINTS = prove
5465 (`!n s:real^N->bool.
5467 ==> FINITE {v | v extreme_point_of s} /\
5468 ~(affine_dependent {v | v extreme_point_of s}) /\
5469 &(CARD {v | v extreme_point_of s}) = n + &1 /\
5470 s = convex hull {v | v extreme_point_of s}`,
5471 REPEAT GEN_TAC THEN REWRITE_TAC[SIMPLEX; LEFT_IMP_EXISTS_THM] THEN
5472 X_GEN_TAC `c:real^N->bool` THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN
5473 SUBGOAL_THEN `{v:real^N | v extreme_point_of s} = c`
5474 (fun th -> ASM_REWRITE_TAC[th]) THEN
5475 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
5476 MATCH_MP_TAC(SET_RULE `s SUBSET t /\ ~(s PSUBSET t) ==> s = t`) THEN
5477 REWRITE_TAC[SUBSET; IN_ELIM_THM; EXTREME_POINT_OF_CONVEX_HULL] THEN
5478 ABBREV_TAC `c' = {v:real^N | v extreme_point_of (convex hull c)}` THEN
5480 SUBGOAL_THEN `convex hull c:real^N->bool = convex hull c'` ASSUME_TAC THENL
5481 [EXPAND_TAC "c'" THEN MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
5482 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN MATCH_MP_TAC COMPACT_CONVEX_HULL THEN
5483 ASM_MESON_TAC[HAS_SIZE; FINITE_IMP_COMPACT];
5484 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_MEMBER]) THEN
5485 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5486 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
5487 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN
5488 REWRITE_TAC[] THEN EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN
5489 SUBGOAL_THEN `(a:real^N) IN convex hull c'` MP_TAC THENL
5490 [ASM_MESON_TAC[HULL_INC]; ALL_TAC] THEN
5491 DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
5492 CONVEX_HULL_SUBSET_AFFINE_HULL)) THEN
5493 SUBGOAL_THEN `c' SUBSET (c DELETE (a:real^N))` MP_TAC THENL
5494 [ASM SET_TAC[]; ASM_MESON_TAC[HULL_MONO; SUBSET]]]);;
5496 let SIMPLEX_FACE_OF_SIMPLEX = prove
5497 (`!n s f:real^N->bool.
5498 n simplex s /\ f face_of s ==> ?m. m <= n /\ m simplex f`,
5499 REPEAT STRIP_TAC THEN
5500 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SIMPLEX]) THEN
5501 REWRITE_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM] THEN
5502 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
5503 FIRST_X_ASSUM SUBST_ALL_TAC THEN
5504 SUBGOAL_THEN `?c':real^N->bool. c' SUBSET c /\ f = convex hull c'`
5505 STRIP_ASSUME_TAC THENL
5506 [ASM_SIMP_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]; ALL_TAC] THEN
5507 EXISTS_TAC `&(CARD(c':real^N->bool)) - &1:int` THEN ASM_REWRITE_TAC[] THEN
5509 [FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] CARD_SUBSET)) THEN
5510 ASM_REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN INT_ARITH_TAC;
5511 REWRITE_TAC[simplex] THEN EXISTS_TAC `c':real^N->bool` THEN
5512 ASM_REWRITE_TAC[INT_ARITH `a - &1 + &1:int = a`] THEN
5513 ASM_MESON_TAC[AFFINE_DEPENDENT_MONO]]);;
5515 let FACE_OF_SIMPLEX_SUBSET = prove
5516 (`!n s f:real^N->bool.
5517 n simplex s /\ f face_of s
5518 ==> ?c. c SUBSET {x | x extreme_point_of s} /\ f = convex hull c`,
5519 REPEAT STRIP_TAC THEN
5520 FIRST_ASSUM(MP_TAC o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN
5521 ABBREV_TAC `c = {x:real^N | x extreme_point_of s}` THEN
5522 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5523 DISCH_THEN SUBST_ALL_TAC THEN
5524 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
5525 ASM_MESON_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);;
5527 let SUBSET_FACE_OF_SIMPLEX = prove
5528 (`!s n c:real^N->bool.
5529 n simplex s /\ c SUBSET {x | x extreme_point_of s}
5530 ==> (convex hull c) face_of s`,
5531 REPEAT STRIP_TAC THEN
5532 FIRST_ASSUM(MP_TAC o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN
5533 REWRITE_TAC[HAS_SIZE] THEN
5534 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN
5535 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN
5536 ASM_REWRITE_TAC[] THEN
5537 MATCH_MP_TAC(SET_RULE `!t. u SUBSET t /\ DISJOINT s t ==> DISJOINT s u`) THEN
5538 EXISTS_TAC `affine hull ({v:real^N | v extreme_point_of s} DIFF c)` THEN
5539 REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN
5540 MATCH_MP_TAC DISJOINT_AFFINE_HULL THEN
5541 EXISTS_TAC `{v:real^N | v extreme_point_of s}` THEN
5542 ASM_REWRITE_TAC[] THEN SET_TAC[]);;
5544 let FACES_OF_SIMPLEX = prove
5546 ==> {f | f face_of s} =
5547 {convex hull c | c SUBSET {v | v extreme_point_of s}}`,
5548 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
5549 REWRITE_TAC[IN_ELIM_THM] THEN
5550 ASM_MESON_TAC[FACE_OF_SIMPLEX_SUBSET; SUBSET_FACE_OF_SIMPLEX]);;
5552 let HAS_SIZE_FACES_OF_SIMPLEX = prove
5553 (`!n s:real^N->bool.
5555 ==> {f | f face_of s} HAS_SIZE 2 EXP (num_of_int(n + &1))`,
5556 REPEAT GEN_TAC THEN DISCH_TAC THEN
5557 FIRST_ASSUM(SUBST1_TAC o MATCH_MP FACES_OF_SIMPLEX) THEN
5558 FIRST_X_ASSUM(STRIP_ASSUME_TAC o GSYM o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN
5559 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN
5560 REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL
5561 [REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ];
5562 MATCH_MP_TAC HAS_SIZE_POWERSET THEN
5563 ASM_REWRITE_TAC[HAS_SIZE; NUM_OF_INT_OF_NUM]] THEN
5565 `!a b. a SUBSET {v:real^N | v extreme_point_of s} /\
5566 b SUBSET {v | v extreme_point_of s} /\
5567 convex hull a SUBSET convex hull b
5569 (fun th -> MESON_TAC[th]) THEN
5570 REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN
5572 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN
5573 REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
5574 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN REWRITE_TAC[] THEN
5575 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5576 MATCH_MP_TAC(SET_RULE
5577 `!s t u. x IN s /\ s SUBSET t /\ t SUBSET u /\ u SUBSET v ==> x IN v`) THEN
5578 MAP_EVERY EXISTS_TAC
5579 [`convex hull a:real^N->bool`; `convex hull b:real^N->bool`;
5580 `affine hull b:real^N->bool`] THEN
5581 ASM_SIMP_TAC[HULL_INC; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN
5582 MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]);;
5584 let FINITE_FACES_OF_SIMPLEX = prove
5585 (`!n s. n simplex s ==> FINITE {f | f face_of s}`,
5587 DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_FACES_OF_SIMPLEX) THEN
5588 SIMP_TAC[HAS_SIZE]);;
5590 let CARD_FACES_OF_SIMPLEX = prove
5591 (`!n s. n simplex s ==> CARD {f | f face_of s} = 2 EXP (num_of_int(n + &1))`,
5593 DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_FACES_OF_SIMPLEX) THEN
5594 SIMP_TAC[HAS_SIZE]);;
5596 let CHOOSE_SIMPLEX = prove
5597 (`!n. --(&1) <= n /\ n <= &(dimindex(:N)) ==> ?s:real^N->bool. n simplex s`,
5598 X_GEN_TAC `d:int` THEN
5599 REWRITE_TAC[INT_ARITH `--(&1):int <= n <=> n = --(&1) \/ &0 <= n`] THEN
5600 DISCH_THEN(CONJUNCTS_THEN2 DISJ_CASES_TAC MP_TAC) THENL
5601 [ASM_MESON_TAC[SIMPLEX_EMPTY]; ALL_TAC] THEN
5602 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM INT_OF_NUM_EXISTS]) THEN
5603 DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST1_TAC) THEN
5604 REWRITE_TAC[INT_OF_NUM_LE; GSYM DIM_UNIV] THEN DISCH_TAC THEN
5605 FIRST_ASSUM(MP_TAC o MATCH_MP CHOOSE_SUBSPACE_OF_SUBSPACE) THEN
5606 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
5607 MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
5608 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
5609 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
5610 EXISTS_TAC `convex hull ((vec 0:real^N) INSERT c)` THEN
5611 REWRITE_TAC[simplex] THEN EXISTS_TAC `(vec 0:real^N) INSERT c` THEN
5612 FIRST_ASSUM(ASSUME_TAC o MATCH_MP INDEPENDENT_NONZERO) THEN
5613 FIRST_ASSUM(ASSUME_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN
5614 ASM_SIMP_TAC[CARD_CLAUSES; GSYM INT_OF_NUM_SUC] THEN
5615 ASM_SIMP_TAC[INDEPENDENT_IMP_AFFINE_DEPENDENT_0] THEN
5616 ASM_MESON_TAC[HAS_SIZE]);;
5618 let CHOOSE_POLYTOPE = prove
5619 (`!n. --(&1) <= n /\ n <= &(dimindex(:N))
5620 ==> ?s:real^N->bool. polytope s /\ aff_dim s = n`,
5621 MESON_TAC[CHOOSE_SIMPLEX; SIMPLEX_IMP_POLYTOPE; AFF_DIM_SIMPLEX]);;
5623 (* ------------------------------------------------------------------------- *)
5624 (* Simplicial complexes and triangulations. *)
5625 (* ------------------------------------------------------------------------- *)
5627 let simplicial_complex = new_definition
5628 `simplicial_complex c <=>
5630 (!s. s IN c ==> ?n. n simplex s) /\
5631 (!f s. s IN c /\ f face_of s ==> f IN c) /\
5632 (!s s'. s IN c /\ s' IN c
5633 ==> (s INTER s') face_of s /\ (s INTER s') face_of s')`;;
5635 let triangulation = new_definition
5636 `triangulation(tr:(real^N->bool)->bool) <=>
5638 (!t. t IN tr ==> ?n. n simplex t) /\
5639 (!t t'. t IN tr /\ t' IN tr
5640 ==> (t INTER t') face_of t /\ (t INTER t') face_of t')`;;
5642 let SIMPLICIAL_COMPLEX_IMP_TRIANGULATION = prove
5643 (`!tr. simplicial_complex tr ==> triangulation tr`,
5644 REWRITE_TAC[triangulation; simplicial_complex] THEN MESON_TAC[]);;
5646 let TRIANGULATION_SUBSET = prove
5647 (`!tr:(real^N->bool)->bool tr'.
5648 triangulation tr /\ tr' SUBSET tr ==> triangulation tr'`,
5649 REWRITE_TAC[triangulation] THEN
5650 MESON_TAC[SUBSET; FINITE_SUBSET]);;
5652 let TRIANGULATION_UNION = prove
5654 triangulation(tr1 UNION tr2) <=>
5655 triangulation tr1 /\ triangulation tr2 /\
5656 (!s t. s IN tr1 /\ t IN tr2
5657 ==> s INTER t face_of s /\ s INTER t face_of t)`,
5658 REWRITE_TAC[triangulation; FINITE_UNION; IN_UNION] THEN
5659 MESON_TAC[INTER_COMM]);;
5661 let TRIANGULATION_INTER_SIMPLEX = prove
5662 (`!tr t t':real^N->bool.
5663 triangulation tr /\ t IN tr /\ t' IN tr
5664 ==> t INTER t' = convex hull ({x | x extreme_point_of t} INTER
5665 {x | x extreme_point_of t'})`,
5666 REWRITE_TAC[triangulation] THEN REPEAT STRIP_TAC THEN
5667 FIRST_X_ASSUM(MP_TAC o SPECL [`t:real^N->bool`; `t':real^N->bool`]) THEN
5668 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
5669 FIRST_X_ASSUM(fun th -> MAP_EVERY (MP_TAC o C SPEC th)
5670 [`t:real^N->bool`; `t':real^N->bool`]) THEN
5671 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
5672 X_GEN_TAC `m:int` THEN DISCH_TAC THEN X_GEN_TAC `n:int` THEN DISCH_TAC THEN
5673 MP_TAC(ISPECL [`m:int`; `t':real^N->bool`;
5674 `t INTER t':real^N->bool`] FACE_OF_SIMPLEX_SUBSET) THEN
5675 MP_TAC(ISPECL [`n:int`; `t:real^N->bool`;
5676 `t INTER t':real^N->bool`] FACE_OF_SIMPLEX_SUBSET) THEN
5678 DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
5679 DISCH_THEN(X_CHOOSE_THEN `d':real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
5680 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
5682 MATCH_MP_TAC HULL_MINIMAL THEN
5683 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[CONVEX_INTER; CONVEX_SIMPLEX]] THEN
5684 SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM; extreme_point_of]] THEN
5685 MATCH_MP_TAC SUBSET_TRANS THEN
5686 EXISTS_TAC `convex hull {x:real^N | x extreme_point_of (t INTER t')}` THEN
5688 [MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN
5689 MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
5690 ASM_MESON_TAC[COMPACT_INTER; CONVEX_INTER; COMPACT_SIMPLEX; CONVEX_SIMPLEX];
5691 MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THENL
5692 [SUBST1_TAC(SYM(ASSUME `convex hull d:real^N->bool = t INTER t'`));
5693 SUBST1_TAC(SYM(ASSUME `convex hull d':real^N->bool = t INTER t'`))] THEN
5694 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN
5695 DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINT_OF_CONVEX_HULL) THEN
5698 let TRIANGULATION_SIMPLICIAL_COMPLEX = prove
5699 (`!tr. triangulation tr
5700 ==> simplicial_complex {f:real^N->bool | ?t. t IN tr /\ f face_of t}`,
5702 (`{f | ?t. t IN tr /\ P f t} = UNIONS (IMAGE (\t. {f | P f t}) tr)`,
5703 GEN_REWRITE_TAC I [EXTENSION] THEN
5704 REWRITE_TAC[IN_ELIM_THM; IN_UNIONS; IN_IMAGE; LEFT_AND_EXISTS_THM] THEN
5705 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
5706 REWRITE_TAC[GSYM CONJ_ASSOC; UNWIND_THM2; IN_ELIM_THM]) in
5707 REWRITE_TAC[triangulation; simplicial_complex] THEN
5708 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
5709 REWRITE_TAC[IN_ELIM_THM] THEN GEN_TAC THEN
5710 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
5711 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN STRIP_TAC THEN
5712 REPEAT CONJ_TAC THENL
5713 [REWRITE_TAC[lemma] THEN ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE] THEN
5714 ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN
5715 ASM_MESON_TAC[FINITE_FACES_OF_SIMPLEX];
5716 ASM_MESON_TAC[SIMPLEX_FACE_OF_SIMPLEX];
5717 ASM_MESON_TAC[FACE_OF_TRANS];
5718 ASM_MESON_TAC[FACE_OF_INTER_SUBFACE]]);;
5720 (* ------------------------------------------------------------------------- *)
5721 (* Subdividing a cell complex (not necessarily simplicial). *)
5722 (* ------------------------------------------------------------------------- *)
5724 let CELL_COMPLEX_SUBDIVISION_EXISTS = prove
5725 (`!m:(real^N->bool)->bool d e.
5728 (!c. c IN m ==> polytope c) /\
5729 (!c. c IN m ==> aff_dim c <= d) /\
5730 (!c1 c2. c1 IN m /\ c2 IN m
5731 ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)
5732 ==> ?m'. (!c. c IN m' ==> diameter c < e) /\
5733 UNIONS m' = UNIONS m /\
5735 (!c. c IN m' ==> polytope c) /\
5736 (!c. c IN m' ==> aff_dim c <= d) /\
5737 (!c1 c2. c1 IN m' /\ c2 IN m'
5738 ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)`,
5742 ==> ?n. integer n /\ (x < n * a /\ n * a < y \/
5743 y < n * a /\ n * a < x)`,
5744 REPEAT STRIP_TAC THEN
5745 ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; GSYM REAL_LT_RDIV_EQ] THEN
5746 MATCH_MP_TAC INTEGER_EXISTS_BETWEEN_ABS_LT THEN
5747 REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB; REAL_ABS_MUL] THEN
5748 ASM_SIMP_TAC[REAL_ABS_INV; REAL_ARITH `&0 < x ==> abs x = x`] THEN
5749 ASM_SIMP_TAC[GSYM real_div; REAL_LT_RDIV_EQ;
5750 REAL_MUL_LID; REAL_LT_IMP_LE])
5752 (`!m:(real^N->bool)->bool d.
5754 (!c. c IN m ==> polytope c) /\
5755 (!c. c IN m ==> aff_dim c <= d) /\
5756 (!c1 c2. c1 IN m /\ c2 IN m
5757 ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)
5759 ==> ?m'. UNIONS m' = UNIONS m /\
5761 (!c. c IN m' ==> polytope c) /\
5762 (!c. c IN m' ==> aff_dim c <= d) /\
5763 (!c1 c2. c1 IN m' /\ c2 IN m'
5764 ==> c1 INTER c2 face_of c1 /\
5765 c1 INTER c2 face_of c2) /\
5766 (!c x y. c IN m' /\ x IN c /\ y IN c
5767 ==> !a b. (a,b) IN i
5768 ==> a dot x <= b /\ a dot y <= b \/
5769 a dot x >= b /\ a dot y >= b)`,
5770 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5771 REWRITE_TAC[NOT_IN_EMPTY; FORALL_PAIR_THM] THEN CONJ_TAC THENL
5772 [EXISTS_TAC `m:(real^N->bool)->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
5773 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`; `i:(real^N#real)->bool`] THEN
5774 GEN_REWRITE_TAC I [IMP_CONJ] THEN
5775 DISCH_THEN(X_CHOOSE_THEN `n:(real^N->bool)->bool` MP_TAC) THEN
5776 DISCH_THEN(CONJUNCTS_THEN2 (SUBST1_TAC o SYM) MP_TAC) THEN
5777 POP_ASSUM_LIST(K ALL_TAC) THEN REPEAT STRIP_TAC THEN
5778 EXISTS_TAC `{c INTER {x:real^N | a dot x <= b} | c IN n} UNION
5779 {c INTER {x:real^N | a dot x >= b} | c IN n}` THEN
5780 REPEAT CONJ_TAC THENL
5781 [REWRITE_TAC[UNIONS_UNION; GSYM INTER_UNIONS; GSYM UNION_OVER_INTER] THEN
5782 MATCH_MP_TAC(SET_RULE `(!x. x IN s) ==> t INTER s = t`) THEN
5783 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC;
5784 ASM_SIMP_TAC[FINITE_UNION; SIMPLE_IMAGE; FINITE_IMAGE];
5785 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
5786 ASM_SIMP_TAC[POLYTOPE_INTER_POLYHEDRON; POLYHEDRON_HALFSPACE_LE;
5787 POLYHEDRON_HALFSPACE_GE];
5788 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
5789 ASM_MESON_TAC[INT_LE_TRANS; AFF_DIM_SUBSET; INTER_SUBSET];
5790 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
5791 ASM_REWRITE_TAC[] THEN
5792 ONCE_REWRITE_TAC[SET_RULE
5793 `(s INTER t) INTER (s' INTER t') = (s INTER s') INTER (t INTER t')`] THEN
5794 MATCH_MP_TAC FACE_OF_INTER_INTER THEN ASM_SIMP_TAC[] THEN
5795 SIMP_TAC[SET_RULE `s INTER s = s`; FACE_OF_REFL; CONVEX_HALFSPACE_LE;
5796 CONVEX_HALFSPACE_GE] THEN
5797 REWRITE_TAC[INTER; IN_ELIM_THM; HYPERPLANE_FACE_OF_HALFSPACE_LE;
5798 HYPERPLANE_FACE_OF_HALFSPACE_GE;
5799 REAL_ARITH `a <= b /\ a >= b <=> a = b`;
5800 REAL_ARITH `a >= b /\ a <= b <=> a = b`];
5801 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_UNION; FORALL_AND_THM;
5803 TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
5804 REWRITE_TAC[FORALL_IN_GSPEC; IN_INTER; IN_ELIM_THM; PAIR_EQ] THEN
5805 SIMP_TAC[] THEN ASM_MESON_TAC[]]) in
5806 REPEAT STRIP_TAC THEN
5807 SUBGOAL_THEN `bounded(UNIONS m:real^N->bool)` MP_TAC THENL
5808 [ASM_SIMP_TAC[BOUNDED_UNIONS; POLYTOPE_IMP_BOUNDED]; ALL_TAC] THEN
5809 REWRITE_TAC[BOUNDED_POS_LT; LEFT_IMP_EXISTS_THM] THEN
5810 X_GEN_TAC `B:real` THEN REWRITE_TAC[] THEN STRIP_TAC THEN
5811 MP_TAC(ISPECL [`--B / (e / &2 / &(dimindex(:N)))`;
5812 `B / (e / &2 / &(dimindex(:N)))`] FINITE_INTSEG) THEN
5813 ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_HALF;
5814 REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
5815 REWRITE_TAC[REAL_BOUNDS_LE] THEN ABBREV_TAC
5816 `k = {i | integer i /\ abs(i * e / &2 / &(dimindex(:N))) <= B}` THEN
5818 MP_TAC(ISPECL [`m:(real^N->bool)->bool`; `d:int`] lemma2) THEN
5819 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC
5820 `{ (basis i:real^N,j * e / &2 / &(dimindex(:N))) |
5821 i IN 1..dimindex(:N) /\ j IN k}`) THEN
5822 ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FINITE_NUMSEG] THEN
5823 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:(real^N->bool)->bool` THEN
5824 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5825 X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN
5826 MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
5827 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC DIAMETER_LE THEN
5828 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
5829 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
5830 W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
5831 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
5832 MATCH_MP_TAC SUM_BOUND_GEN THEN
5833 REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG_1; NUMSEG_EMPTY] THEN
5834 REWRITE_TAC[NOT_LT; DIMINDEX_GE_1; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN
5835 X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
5836 DISCH_THEN(MP_TAC o MATCH_MP lemma1) THEN
5837 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV;
5838 REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
5839 DISCH_THEN(X_CHOOSE_THEN `j:real` (CONJUNCTS_THEN ASSUME_TAC)) THEN
5840 FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^N->bool`; `x:real^N`; `y:real^N`]) THEN
5841 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o
5842 SPECL [`basis i:real^N`; `j * e / &2 / &(dimindex(:N))`]) THEN
5843 ASM_SIMP_TAC[DOT_BASIS; IN_ELIM_THM; NOT_IMP] THEN
5844 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
5845 MAP_EVERY EXISTS_TAC [`i:num`; `j:real`] THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN
5846 EXPAND_TAC "k" THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
5847 FIRST_X_ASSUM DISJ_CASES_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
5848 (REAL_ARITH `a < x /\ x < b
5849 ==> abs a <= c /\ abs b <= c ==> abs x <= c`)) THEN
5851 W(MP_TAC o PART_MATCH lhand COMPONENT_LE_NORM o lhand o snd) THEN
5852 ASM_REWRITE_TAC[] THEN
5853 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
5854 MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN