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 (* ------------------------------------------------------------------------- *)
2390 (* ------------------------------------------------------------------------- *)
2392 let polyhedron = new_definition
2396 (!h. h IN f ==> ?a b. ~(a = vec 0) /\ h = {x | a dot x <= b})`;;
2398 let POLYHEDRON_INTER = prove
2399 (`!s t:real^N->bool.
2400 polyhedron s /\ polyhedron t ==> polyhedron (s INTER t)`,
2401 REPEAT GEN_TAC THEN REWRITE_TAC[polyhedron] THEN
2402 DISCH_THEN(CONJUNCTS_THEN2
2403 (X_CHOOSE_TAC `f:(real^N->bool)->bool`)
2404 (X_CHOOSE_TAC `g:(real^N->bool)->bool`)) THEN
2405 EXISTS_TAC `f UNION g:(real^N->bool)->bool` THEN
2406 ASM_REWRITE_TAC[SET_RULE `INTERS(f UNION g) = INTERS f INTER INTERS g`] THEN
2407 REWRITE_TAC[FINITE_UNION; IN_UNION] THEN
2408 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);;
2410 let POLYHEDRON_UNIV = prove
2411 (`polyhedron(:real^N)`,
2412 REWRITE_TAC[polyhedron] THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN
2413 REWRITE_TAC[INTERS_0; NOT_IN_EMPTY; FINITE_RULES]);;
2415 let POLYHEDRON_POSITIVE_ORTHANT = prove
2416 (`polyhedron {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`,
2417 REWRITE_TAC[polyhedron] THEN
2418 EXISTS_TAC `IMAGE (\i. {x:real^N | &0 <= x$i}) (1..dimindex(:N))` THEN
2419 SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN CONJ_TAC THENL
2420 [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[INTERS_IMAGE] THEN
2421 REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG];
2422 X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
2423 MAP_EVERY EXISTS_TAC [`--basis k:real^N`; `&0`] THEN
2424 ASM_SIMP_TAC[VECTOR_NEG_EQ_0; DOT_LNEG; DOT_BASIS; BASIS_NONZERO] THEN
2425 REWRITE_TAC[REAL_ARITH `--x <= &0 <=> &0 <= x`]]);;
2427 let POLYHEDRON_INTERS = prove
2428 (`!f:(real^N->bool)->bool.
2429 FINITE f /\ (!s. s IN f ==> polyhedron s) ==> polyhedron(INTERS f)`,
2430 REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2431 REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; POLYHEDRON_UNIV] THEN
2432 ASM_SIMP_TAC[INTERS_INSERT; FORALL_IN_INSERT; POLYHEDRON_INTER]);;
2434 let POLYHEDRON_EMPTY = prove
2435 (`polyhedron({}:real^N->bool)`,
2436 REWRITE_TAC[polyhedron] THEN
2437 EXISTS_TAC `{{x:real^N | basis 1 dot x <= -- &1},
2438 {x | --(basis 1) dot x <= -- &1}}` THEN
2439 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY; INTERS_2; FORALL_IN_INSERT] THEN
2440 REWRITE_TAC[NOT_IN_EMPTY; INTER; IN_ELIM_THM; DOT_LNEG] THEN
2441 REWRITE_TAC[REAL_ARITH `~(a <= -- &1 /\ --a <= -- &1)`; EMPTY_GSPEC] THEN
2443 [MAP_EVERY EXISTS_TAC [`basis 1:real^N`; `-- &1`];
2444 MAP_EVERY EXISTS_TAC [`--(basis 1):real^N`; `-- &1`]] THEN
2445 SIMP_TAC[VECTOR_NEG_EQ_0; BASIS_NONZERO; DOT_LNEG;
2446 DIMINDEX_GE_1; LE_REFL]);;
2448 let POLYHEDRON_HALFSPACE_LE = prove
2449 (`!a b. polyhedron {x:real^N | a dot x <= b}`,
2450 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
2451 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
2452 COND_CASES_TAC THEN ASM_REWRITE_TAC[POLYHEDRON_EMPTY; POLYHEDRON_UNIV];
2453 REWRITE_TAC[polyhedron] THEN EXISTS_TAC `{{x:real^N | a dot x <= b}}` THEN
2454 REWRITE_TAC[FINITE_SING; INTERS_1; FORALL_IN_INSERT; NOT_IN_EMPTY] THEN
2455 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real`] THEN ASM_REWRITE_TAC[]]);;
2457 let POLYHEDRON_HALFSPACE_GE = prove
2458 (`!a b. polyhedron {x:real^N | a dot x >= b}`,
2459 REWRITE_TAC[REAL_ARITH `a:real >= b <=> --a <= --b`] THEN
2460 REWRITE_TAC[GSYM DOT_LNEG; POLYHEDRON_HALFSPACE_LE]);;
2462 let POLYHEDRON_HYPERPLANE = prove
2463 (`!a b. polyhedron {x:real^N | a dot x = b}`,
2464 REWRITE_TAC[REAL_ARITH `x:real = b <=> x <= b /\ x >= b`] THEN
2465 REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
2466 SIMP_TAC[POLYHEDRON_INTER; POLYHEDRON_HALFSPACE_LE;
2467 POLYHEDRON_HALFSPACE_GE]);;
2469 let AFFINE_IMP_POLYHEDRON = prove
2470 (`!s:real^N->bool. affine s ==> polyhedron s`,
2471 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool`
2472 AFFINE_HULL_FINITE_INTERSECTION_HYPERPLANES) THEN
2473 ASM_SIMP_TAC[HULL_P; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2474 STRIP_TAC THEN ASM_SIMP_TAC[] THEN
2475 MATCH_MP_TAC POLYHEDRON_INTERS THEN ASM_REWRITE_TAC[] THEN
2476 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2477 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2478 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
2479 REWRITE_TAC[POLYHEDRON_HYPERPLANE]);;
2481 let POLYHEDRON_IMP_CLOSED = prove
2482 (`!s:real^N->bool. polyhedron s ==> closed s`,
2483 REWRITE_TAC[polyhedron; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2484 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2485 MATCH_MP_TAC CLOSED_INTERS THEN
2486 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2487 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2488 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
2489 REWRITE_TAC[CLOSED_HALFSPACE_LE]);;
2491 let POLYHEDRON_IMP_CONVEX = prove
2492 (`!s:real^N->bool. polyhedron s ==> convex s`,
2493 REWRITE_TAC[polyhedron; RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2494 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2495 MATCH_MP_TAC CONVEX_INTERS THEN
2496 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2497 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2498 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
2499 REWRITE_TAC[CONVEX_HALFSPACE_LE]);;
2501 let POLYHEDRON_AFFINE_HULL = prove
2502 (`!s. polyhedron(affine hull s)`,
2503 SIMP_TAC[AFFINE_IMP_POLYHEDRON; AFFINE_AFFINE_HULL]);;
2505 (* ------------------------------------------------------------------------- *)
2506 (* Canonical polyedron representation making facial structure explicit. *)
2507 (* ------------------------------------------------------------------------- *)
2509 let POLYHEDRON_INTER_AFFINE = prove
2510 (`!s. polyhedron s <=>
2512 s = (affine hull s) INTER (INTERS f) /\
2514 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b})`,
2515 GEN_TAC THEN EQ_TAC THENL
2516 [REWRITE_TAC[polyhedron] THEN MATCH_MP_TAC MONO_EXISTS THEN
2517 GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THEN
2518 TRY(FIRST_ASSUM ACCEPT_TAC) THEN
2519 MATCH_MP_TAC(SET_RULE `s = t /\ s SUBSET u ==> s = u INTER t`) THEN
2520 REWRITE_TAC[HULL_SUBSET] THEN ASM_REWRITE_TAC[];
2521 STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
2522 MATCH_MP_TAC POLYHEDRON_INTER THEN REWRITE_TAC[POLYHEDRON_AFFINE_HULL] THEN
2523 MATCH_MP_TAC POLYHEDRON_INTERS THEN ASM_REWRITE_TAC[] THEN
2524 ASM_MESON_TAC[POLYHEDRON_HALFSPACE_LE]]);;
2526 let POLYHEDRON_INTER_AFFINE_PARALLEL = prove
2530 s = (affine hull s) INTER (INTERS f) /\
2532 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b} /\
2533 (!x. x IN affine hull s
2534 ==> (x + a) IN affine hull s))`,
2535 GEN_TAC THEN REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN EQ_TAC THENL
2536 [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]] THEN
2537 DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` MP_TAC) THEN
2538 ASM_CASES_TAC `s:real^N->bool = {}` THENL
2539 [DISCH_THEN(K ALL_TAC) THEN EXISTS_TAC `{}:(real^N->bool)->bool` THEN
2540 ASM_SIMP_TAC[AFFINE_HULL_EMPTY; INTER_EMPTY; NOT_IN_EMPTY; FINITE_EMPTY];
2542 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL
2543 [ASM_REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; INTER_UNIV] THEN
2544 DISCH_THEN(ASSUME_TAC o SYM o CONJUNCT2) THEN
2545 EXISTS_TAC `{}:(real^N->bool)->bool` THEN
2546 ASM_REWRITE_TAC[NOT_IN_EMPTY; INTERS_0; INTER_UNIV; FINITE_EMPTY];
2548 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o GSYM) MP_TAC)) THEN
2549 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
2550 [RIGHT_IMP_EXISTS_THM] THEN
2551 REWRITE_TAC[LEFT_IMP_EXISTS_THM; SKOLEM_THM] THEN
2553 [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN
2554 DISCH_THEN(ASSUME_TAC o GSYM) THEN
2556 `!h. h IN f /\ ~(affine hull s SUBSET h)
2557 ==> ?a' b'. ~(a' = vec 0) /\
2558 affine hull s INTER {x:real^N | a' dot x <= b'} =
2559 affine hull s INTER h /\
2560 !w. w IN affine hull s ==> (w + a') IN affine hull s`
2562 [GEN_TAC THEN STRIP_TAC THEN
2563 FIRST_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2564 REWRITE_TAC[ASSUME `(h:real^N->bool) IN f`] THEN
2565 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC o GSYM) THEN
2566 MP_TAC(ISPECL [`affine hull s:real^N->bool`;
2567 `(a:(real^N->bool)->real^N) h`;
2568 `(b:(real^N->bool)->real) h`]
2569 AFFINE_PARALLEL_SLICE) THEN
2570 REWRITE_TAC[AFFINE_AFFINE_HULL] THEN MATCH_MP_TAC(TAUT
2571 `~p /\ ~q /\ (r ==> r') ==> (p \/ q \/ r ==> r')`) THEN
2572 ASM_SIMP_TAC[] THEN CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
2574 UNDISCH_TAC `~(s:real^N->bool = {})` THEN
2575 EXPAND_TAC "s" THEN REWRITE_TAC[GSYM INTERS_INSERT] THEN
2576 MATCH_MP_TAC(SET_RULE
2577 `!t. t SUBSET s /\ INTERS t = {} ==> INTERS s = {}`) THEN
2578 EXISTS_TAC `{affine hull s,h:real^N->bool}` THEN
2579 ASM_REWRITE_TAC[INTERS_2] THEN ASM SET_TAC[];
2581 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
2582 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
2583 FIRST_X_ASSUM(K ALL_TAC o SPEC `{}:real^N->bool`) THEN
2585 [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN
2587 EXISTS_TAC `IMAGE (\h:real^N->bool. {x:real^N | a h dot x <= b h})
2588 {h | h IN f /\ ~(affine hull s SUBSET h)}` THEN
2589 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; FORALL_IN_IMAGE] THEN
2590 REWRITE_TAC[FORALL_IN_GSPEC] THEN CONJ_TAC THENL
2592 X_GEN_TAC `h:real^N->bool` THEN STRIP_TAC THEN
2593 MAP_EVERY EXISTS_TAC
2594 [`(a:(real^N->bool)->real^N) h`; `(b:(real^N->bool)->real) h`] THEN
2595 ASM_MESON_TAC[]] THEN
2596 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN
2597 GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real^N` THEN
2598 REWRITE_TAC[INTERS_IMAGE; IN_INTER; IN_ELIM_THM] THEN
2599 ASM_CASES_TAC `(x:real^N) IN affine hull s` THEN
2600 ASM_REWRITE_TAC[IN_INTERS] THEN AP_TERM_TAC THEN ABS_TAC THEN
2603 let POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL = prove
2604 (`!s. polyhedron s <=>
2606 s = (affine hull s) INTER (INTERS f) /\
2608 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b} /\
2609 (!x. x IN affine hull s
2610 ==> (x + a) IN affine hull s)) /\
2611 !f'. f' PSUBSET f ==> s PSUBSET (affine hull s) INTER (INTERS f')`,
2612 GEN_TAC THEN REWRITE_TAC[POLYHEDRON_INTER_AFFINE_PARALLEL] THEN
2613 EQ_TAC THENL [ALL_TAC; MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]] THEN
2614 GEN_REWRITE_TAC LAND_CONV
2616 `(?f. FINITE f /\ P f) <=> (?n f. f HAS_SIZE n /\ P f)`] THEN
2617 GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN
2618 DISCH_THEN(X_CHOOSE_THEN `n:num` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
2619 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[HAS_SIZE] THEN
2620 X_GEN_TAC `f:(real^N->bool)->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2621 CONJ_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
2622 X_GEN_TAC `f':(real^N->bool)->bool` THEN DISCH_TAC THEN
2623 FIRST_X_ASSUM(MP_TAC o SPEC `CARD(f':(real^N->bool)->bool)`) THEN
2624 ANTS_TAC THENL [ASM_MESON_TAC[CARD_PSUBSET]; ALL_TAC] THEN
2625 REWRITE_TAC[NOT_EXISTS_THM; HAS_SIZE] THEN
2626 DISCH_THEN(MP_TAC o SPEC `f':(real^N->bool)->bool`) THEN
2627 MATCH_MP_TAC(TAUT `a /\ c /\ (~b ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN
2628 CONJ_TAC THENL [ASM_MESON_TAC[PSUBSET; FINITE_SUBSET]; ALL_TAC] THEN
2630 [REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[];
2631 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(s = t) ==> s PSUBSET t`) THEN
2632 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
2635 let POLYHEDRON_INTER_AFFINE_MINIMAL = prove
2636 (`!s. polyhedron s <=>
2638 s = (affine hull s) INTER (INTERS f) /\
2640 ==> ?a b. ~(a = vec 0) /\ h = {x:real^N | a dot x <= b}) /\
2641 !f'. f' PSUBSET f ==> s PSUBSET (affine hull s) INTER (INTERS f')`,
2642 GEN_TAC THEN EQ_TAC THENL
2643 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL];
2644 REWRITE_TAC[POLYHEDRON_INTER_AFFINE]] THEN
2645 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN MESON_TAC[]);;
2647 let RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT = prove
2648 (`!s:real^N->bool f a b.
2650 s = affine hull s INTER INTERS f /\
2651 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
2652 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
2653 ==> relative_interior s =
2654 {x | x IN s /\ !h. h IN f ==> a h dot x < b h}`,
2655 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2656 DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) STRIP_ASSUME_TAC) THEN
2657 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN
2658 X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
2660 STRIP_TAC THEN ASM_REWRITE_TAC[RELATIVE_INTERIOR; IN_ELIM_THM] THEN
2661 EXISTS_TAC `INTERS {interior h | (h:real^N->bool) IN f}` THEN
2662 ASM_SIMP_TAC[SIMPLE_IMAGE; OPEN_INTERS; FINITE_IMAGE; OPEN_INTERIOR;
2663 FORALL_IN_IMAGE; IN_INTERS] THEN
2665 [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
2666 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`)) THEN
2667 ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN
2668 FIRST_ASSUM(SUBST1_TAC o CONJUNCT2) THEN
2669 ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; IN_ELIM_THM];
2670 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN
2671 MATCH_MP_TAC(SET_RULE
2672 `(!s. s IN f ==> i s SUBSET s)
2673 ==> INTERS (IMAGE i f) INTER t SUBSET t INTER INTERS f`) THEN
2674 REWRITE_TAC[INTERIOR_SUBSET]]] THEN
2676 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN
2677 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:real^N->bool` THEN
2679 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (i:real^N->bool)`) THEN ANTS_TAC THENL
2681 REWRITE_TAC[PSUBSET_ALT; IN_INTER; IN_INTERS; IN_DELETE]] THEN
2682 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2683 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2684 SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot z > b i` ASSUME_TAC THENL
2685 [UNDISCH_TAC `~((z:real^N) IN s)` THEN
2686 FIRST_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[IN_INTER; IN_INTERS] THEN
2687 ASM_REWRITE_TAC[REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN ASM SET_TAC[];
2689 SUBGOAL_THEN `~(z:real^N = x)` ASSUME_TAC THENL
2690 [ASM_MESON_TAC[]; ALL_TAC] THEN
2692 `?l. &0 < l /\ l < &1 /\ (l % z + (&1 - l) % x:real^N) IN s`
2693 STRIP_ASSUME_TAC THENL
2694 [FIRST_ASSUM(X_CHOOSE_THEN `e:real` MP_TAC o CONJUNCT2) THEN
2695 REWRITE_TAC[SUBSET; IN_INTER; IN_BALL; dist] THEN STRIP_TAC THEN
2696 EXISTS_TAC `min (&1 / &2) (e / &2 / norm(z - x:real^N))` THEN
2697 REWRITE_TAC[REAL_MIN_LT; REAL_LT_MIN] THEN
2698 CONV_TAC REAL_RAT_REDUCE_CONV THEN
2699 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2700 FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL
2701 [REWRITE_TAC[VECTOR_ARITH
2702 `x - (l % z + (&1 - l) % x):real^N = --l % (z - x)`] THEN
2703 REWRITE_TAC[NORM_MUL; REAL_ABS_NEG] THEN
2704 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2705 MATCH_MP_TAC(REAL_ARITH
2706 `&0 < a /\ &0 < b /\ b < c ==> abs(min a b) < c`) THEN
2707 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2708 REWRITE_TAC[REAL_LT_01; real_div; REAL_MUL_ASSOC] THEN
2709 MATCH_MP_TAC REAL_LT_RMUL THEN
2710 ASM_REWRITE_TAC[REAL_LT_INV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
2711 UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC;
2712 ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN
2713 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
2716 MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN EXISTS_TAC `&1 - l` THEN
2717 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
2718 REWRITE_TAC[REAL_ARITH `a < b * (&1 - l) <=> l * b + a < b`] THEN
2719 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC
2720 `l * (a:(real^N->bool)->real^N) i dot z + (a i dot x) * (&1 - l)` THEN
2721 ASM_SIMP_TAC[REAL_LT_RADD; REAL_LT_LMUL_EQ; GSYM real_gt] THEN
2722 ONCE_REWRITE_TAC[REAL_ARITH `a * (&1 - b) = (&1 - b) * a`] THEN
2723 REWRITE_TAC[GSYM DOT_RMUL; GSYM DOT_RADD] THEN ASM SET_TAC[]);;
2725 let FACET_OF_POLYHEDRON_EXPLICIT = prove
2726 (`!s:real^N->bool f a b.
2728 s = affine hull s INTER INTERS f /\
2729 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
2730 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
2731 ==> !c. c facet_of s <=>
2732 ?h. h IN f /\ c = s INTER {x | a h dot x = b h}`,
2733 REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
2734 [ASM_REWRITE_TAC[INTER_EMPTY; AFFINE_HULL_EMPTY; SET_RULE `~(s PSUBSET s)`;
2735 FACET_OF_EMPTY] THEN
2736 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
2737 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
2738 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
2739 DISCH_THEN(X_CHOOSE_TAC `h:real^N->bool`) THEN DISCH_THEN
2740 (MP_TAC o SPEC `f DELETE (h:real^N->bool)` o last o CONJUNCTS) THEN
2743 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
2744 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
2745 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
2747 FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN
2750 h IN f ==> (s INTER {x:real^N | a h dot x = b h}) facet_of s`
2751 (LABEL_TAC "face") THENL
2752 [REPEAT STRIP_TAC THEN REWRITE_TAC[facet_of] THEN CONJ_TAC THENL
2753 [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
2755 [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN
2756 REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
2757 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
2758 X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN
2759 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
2760 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN
2761 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
2762 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
2763 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
2765 MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_EQ_EMPTY) THEN
2766 ASM_SIMP_TAC[] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
2767 DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN
2768 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_RELATIVE_INTERIOR]) THEN
2770 FIRST_ASSUM(MP_TAC o SPEC `f DELETE (h:real^N->bool)`) THEN
2773 REWRITE_TAC[PSUBSET_ALT; IN_INTER; IN_INTERS; IN_DELETE]] THEN
2774 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2775 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2776 SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot z > b h` ASSUME_TAC THENL
2777 [UNDISCH_TAC `~((z:real^N) IN s)` THEN
2778 FIRST_ASSUM(SUBST1_TAC o SYM) THEN
2779 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
2780 ASM_REWRITE_TAC[REAL_ARITH `a:real > b <=> ~(a <= b)`] THEN
2783 SUBGOAL_THEN `~(z:real^N = x)` ASSUME_TAC THENL
2784 [ASM_MESON_TAC[]; ALL_TAC] THEN
2785 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
2786 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
2787 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
2788 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
2789 [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
2790 GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN
2791 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
2792 ASM_REWRITE_TAC[IN_ELIM_THM] THEN
2793 DISCH_THEN(fun th ->
2794 MP_TAC(SPEC `h:real^N->bool` th) THEN ASM_REWRITE_TAC[] THEN
2795 DISCH_TAC THEN ASSUME_TAC th) THEN
2796 SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot x < a h dot z`
2797 ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2798 ABBREV_TAC `l = (b h - (a:(real^N->bool)->real^N) h dot x) /
2799 (a h dot z - a h dot x)` THEN
2800 SUBGOAL_THEN `&0 < l /\ l < &1` STRIP_ASSUME_TAC THENL
2801 [EXPAND_TAC "l" THEN
2802 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT] THEN
2805 ABBREV_TAC `w:real^N = (&1 - l) % x + l % z:real^N` THEN
2807 `!i. i IN f /\ ~(i = h) ==> (a:(real^N->bool)->real^N) i dot w < b i`
2809 [X_GEN_TAC `i:real^N->bool` THEN STRIP_TAC THEN EXPAND_TAC "w" THEN
2810 REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
2811 MATCH_MP_TAC(REAL_ARITH
2812 `(&1 - l) * x < (&1 - l) * z /\ l * y <= l * z
2813 ==> (&1 - l) * x + l * y < z`) THEN
2814 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_IMP_LE;
2815 REAL_LT_LMUL_EQ; REAL_SUB_LT] THEN
2816 UNDISCH_TAC `!t:real^N->bool. t IN f /\ ~(t = h) ==> z IN t` THEN
2817 DISCH_THEN(MP_TAC o SPEC `i:real^N->bool`) THEN ASM SET_TAC[];
2819 SUBGOAL_THEN `(a:(real^N->bool)->real^N) h dot w = b h` ASSUME_TAC THENL
2820 [EXPAND_TAC "w" THEN REWRITE_TAC[VECTOR_ARITH
2821 `(&1 - l) % x + l % z:real^N = x + l % (z - x)`] THEN
2822 EXPAND_TAC "l" THEN REWRITE_TAC[DOT_RADD; DOT_RSUB; DOT_RMUL] THEN
2823 ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NE; REAL_SUB_0] THEN
2826 SUBGOAL_THEN `(w:real^N) IN s` ASSUME_TAC THENL
2827 [FIRST_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [th]) THEN
2828 REWRITE_TAC[IN_INTER; IN_INTERS] THEN CONJ_TAC THENL
2829 [EXPAND_TAC "w" THEN
2830 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
2831 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HULL_INC THEN
2832 ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; SUBSET];
2834 X_GEN_TAC `i:real^N->bool` THEN DISCH_TAC THEN
2835 ASM_CASES_TAC `i:real^N->bool = h` THENL
2836 [ASM SET_TAC[REAL_LE_REFL]; ALL_TAC] THEN
2837 SUBGOAL_THEN `convex(i:real^N->bool)` MP_TAC THENL
2838 [REPEAT(FIRST_X_ASSUM(MP_TAC o C MATCH_MP
2839 (ASSUME `(i:real^N->bool) IN f`))) THEN
2840 REPEAT(DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th])) THEN
2841 REWRITE_TAC[CONVEX_HALFSPACE_LE];
2843 REWRITE_TAC[CONVEX_ALT] THEN EXPAND_TAC "w" THEN
2844 DISCH_THEN MATCH_MP_TAC THEN
2845 ASM_SIMP_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT1) THEN
2846 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN
2847 REWRITE_TAC[IN_INTER; IN_INTERS] THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
2849 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
2850 ONCE_REWRITE_TAC[GSYM AFF_DIM_AFFINE_HULL] THEN
2852 `affine hull (s INTER {x | (a:(real^N->bool)->real^N) h dot x = b h}) =
2853 (affine hull s) INTER {x | a h dot x = b h}`
2856 SIMP_TAC[AFF_DIM_AFFINE_INTER_HYPERPLANE; AFFINE_AFFINE_HULL] THEN
2857 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
2858 COND_CASES_TAC THENL [ASM SET_TAC[REAL_LT_REFL]; REFL_TAC]] THEN
2859 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[SUBSET_INTER] THEN
2860 REPEAT CONJ_TAC THENL
2861 [MATCH_MP_TAC HULL_MONO THEN SET_TAC[];
2862 MATCH_MP_TAC(SET_RULE
2863 `s SUBSET affine hull t /\ affine hull t = t ==> s SUBSET t`) THEN
2864 REWRITE_TAC[AFFINE_HULL_EQ; AFFINE_HYPERPLANE] THEN
2865 MATCH_MP_TAC HULL_MONO THEN SET_TAC[];
2867 REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
2868 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
2871 !j. j IN f /\ ~(j:real^N->bool = h)
2872 ==> t * (a j dot y - a j dot w) <= b j - a j dot (w:real^N)`
2873 STRIP_ASSUME_TAC THENL
2874 [ASM_CASES_TAC `f DELETE (h:real^N->bool) = {}` THENL
2875 [ASM_REWRITE_TAC[GSYM IN_DELETE; NOT_IN_EMPTY] THEN
2876 EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01];
2878 EXISTS_TAC `inf (IMAGE
2879 (\j. if &0 < a j dot y - a j dot (w:real^N)
2880 then (b j - a j dot w) / (a j dot y - a j dot w)
2881 else &1) (f DELETE (h:real^N->bool)))` THEN
2882 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
2883 [ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_DELETE;
2884 IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_DELETE] THEN
2885 ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN
2886 ASM_SIMP_TAC[REAL_LT_DIV; REAL_SUB_LT; REAL_LT_01; COND_ID];
2887 REWRITE_TAC[REAL_SUB_LT] THEN DISCH_TAC] THEN
2888 X_GEN_TAC `j:real^N->bool` THEN STRIP_TAC THEN
2889 ASM_CASES_TAC `a j dot (w:real^N) < a(j:real^N->bool) dot y` THENL
2890 [ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_INF_LE_FINITE; REAL_SUB_LT;
2891 FINITE_IMAGE; FINITE_DELETE; IMAGE_EQ_EMPTY] THEN
2892 REWRITE_TAC[EXISTS_IN_IMAGE] THEN EXISTS_TAC `j:real^N->bool` THEN
2893 ASM_REWRITE_TAC[IN_DELETE; REAL_LE_REFL];
2894 MATCH_MP_TAC(REAL_ARITH `&0 <= --x /\ &0 < y ==> x <= y`) THEN
2895 ASM_SIMP_TAC[REAL_SUB_LT; GSYM REAL_MUL_RNEG; REAL_LE_MUL_EQ] THEN
2896 ASM_REAL_ARITH_TAC];
2898 ABBREV_TAC `c:real^N = (&1 - t) % w + t % y` THEN
2899 SUBGOAL_THEN `y:real^N = (&1 - inv t) % w + inv(t) % c` SUBST1_TAC THENL
2900 [EXPAND_TAC "c" THEN
2901 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
2902 ASM_SIMP_TAC[REAL_MUL_LINV; REAL_LT_IMP_NZ;
2903 REAL_FIELD `&0 < x ==> inv x * (&1 - x) = inv x - &1`] THEN
2906 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
2907 CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN
2908 ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
2909 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
2910 [EXPAND_TAC "c" THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
2911 ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RING;
2913 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC RAND_CONV [t]) THEN
2914 REWRITE_TAC[IN_INTER; IN_INTERS] THEN CONJ_TAC THENL
2915 [EXPAND_TAC "c" THEN
2916 MATCH_MP_TAC(REWRITE_RULE[AFFINE_ALT] AFFINE_AFFINE_HULL) THEN
2917 ASM_SIMP_TAC[HULL_INC];
2919 X_GEN_TAC `j:real^N->bool` THEN DISCH_TAC THEN
2920 FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC o C MATCH_MP
2921 (ASSUME `(j:real^N->bool) IN f`)) THEN
2922 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
2923 ASM_CASES_TAC `j:real^N->bool = h` THEN ASM_SIMP_TAC[REAL_EQ_IMP_LE] THEN
2924 EXPAND_TAC "c" THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
2925 REWRITE_TAC[REAL_ARITH
2926 `(&1 - t) * x + t * y <= z <=> t * (y - x) <= z - x`] THEN
2929 X_GEN_TAC `c:real^N->bool` THEN EQ_TAC THENL
2930 [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[]] THEN
2931 REWRITE_TAC[facet_of] THEN STRIP_TAC THEN
2932 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
2933 SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL
2934 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN
2935 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
2936 DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN
2937 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
2938 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
2939 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
2940 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
2941 GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN
2942 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
2943 SUBGOAL_THEN `~(c:real^N->bool = s)` ASSUME_TAC THENL
2944 [ASM_MESON_TAC[INT_ARITH`~(i:int = i - &1)`]; ALL_TAC] THEN
2945 SUBGOAL_THEN `~((x:real^N) IN relative_interior s)` ASSUME_TAC THENL
2946 [UNDISCH_TAC `~(c:real^N->bool = s)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN
2947 DISCH_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN
2948 EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN
2951 SUBGOAL_THEN `(x:real^N) IN s` MP_TAC THENL
2952 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o MATCH_MP
2953 FACE_OF_IMP_SUBSET) THEN
2954 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET];
2956 ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
2957 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN
2958 REWRITE_TAC[IN_INTER; IN_INTERS] THEN STRIP_TAC THEN
2959 REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
2960 X_GEN_TAC `i:real^N->bool` THEN REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN
2961 ASM_REWRITE_TAC[] THEN
2962 SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot x = b i` ASSUME_TAC THENL
2963 [MATCH_MP_TAC(REAL_ARITH `x <= y /\ ~(x < y) ==> x = y`) THEN
2964 ASM_REWRITE_TAC[] THEN UNDISCH_THEN
2965 `!t:real^N->bool. t IN f ==> x IN t` (MP_TAC o SPEC `i:real^N->bool`) THEN
2966 ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o C MATCH_MP
2967 (ASSUME `(i:real^N->bool) IN f`)) THEN SET_TAC[];
2969 SUBGOAL_THEN `c SUBSET (s INTER {x:real^N | a(i:real^N->bool) dot x = b i})`
2971 [MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN
2972 ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THEN
2973 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[] THEN
2974 REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN
2975 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM];
2977 SUBGOAL_THEN `c face_of (s INTER {x:real^N | a(i:real^N->bool) dot x = b i})`
2979 [MP_TAC(ISPECL [`c:real^N->bool`; `s:real^N->bool`;
2980 `s INTER {x:real^N | a(i:real^N->bool) dot x = b i}`]
2982 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[];
2984 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
2986 `aff_dim(c:real^N->bool) <
2987 aff_dim(s INTER {x:real^N | a(i:real^N->bool) dot x = b i})`
2989 [MATCH_MP_TAC FACE_OF_AFF_DIM_LT THEN
2990 ASM_SIMP_TAC[CONVEX_INTER; CONVEX_HYPERPLANE];
2991 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[INT_LT_REFL]]);;
2993 let FACE_OF_POLYHEDRON_SUBSET_EXPLICIT = prove
2994 (`!s:real^N->bool f a b.
2996 s = affine hull s INTER INTERS f /\
2997 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
2998 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
2999 ==> !c. c face_of s /\ ~(c = {}) /\ ~(c = s)
3000 ==> ?h. h IN f /\ c SUBSET (s INTER {x | a h dot x = b h})`,
3001 REPEAT GEN_TAC THEN ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL
3002 [DISCH_THEN(MP_TAC o SYM o CONJUNCT1 o CONJUNCT2) THEN
3003 ASM_REWRITE_TAC[INTERS_0; INTER_UNIV; AFFINE_HULL_EQ] THEN
3004 MESON_TAC[FACE_OF_AFFINE_TRIVIAL];
3006 DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN
3007 DISCH_THEN(ASSUME_TAC o MATCH_MP FACET_OF_POLYHEDRON_EXPLICIT) THEN
3008 REPEAT STRIP_TAC THEN
3009 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
3010 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
3011 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
3012 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3013 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3015 FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN
3018 h IN f ==> (s INTER {x:real^N | a h dot x = b h}) face_of s`
3020 [REPEAT STRIP_TAC THEN
3021 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN CONJ_TAC THENL
3022 [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN
3023 REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3024 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3025 X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN
3026 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
3027 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN
3028 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
3029 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
3030 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
3032 SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL
3033 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN
3034 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
3035 DISCH_THEN(X_CHOOSE_TAC `x:real^N`) THEN
3036 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3037 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3038 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3039 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
3040 GEN_REWRITE_TAC LAND_CONV [EXTENSION] THEN
3041 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
3042 SUBGOAL_THEN `~((x:real^N) IN relative_interior s)` ASSUME_TAC THENL
3043 [UNDISCH_TAC `~(c:real^N->bool = s)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN
3044 DISCH_TAC THEN MATCH_MP_TAC FACE_OF_EQ THEN
3045 EXISTS_TAC `s:real^N->bool` THEN ASM_SIMP_TAC[FACE_OF_REFL] THEN
3048 SUBGOAL_THEN `(x:real^N) IN s` MP_TAC THENL
3049 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET] o MATCH_MP
3050 FACE_OF_IMP_SUBSET) THEN
3051 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET];
3053 ASM_SIMP_TAC[] THEN DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3054 FIRST_ASSUM(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [t]) THEN
3055 REWRITE_TAC[IN_INTER; IN_INTERS] THEN STRIP_TAC THEN
3056 REWRITE_TAC[NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
3057 X_GEN_TAC `i:real^N->bool` THEN REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN
3058 ASM_REWRITE_TAC[] THEN
3059 SUBGOAL_THEN `(a:(real^N->bool)->real^N) i dot x = b i` ASSUME_TAC THENL
3060 [MATCH_MP_TAC(REAL_ARITH `x <= y /\ ~(x < y) ==> x = y`) THEN
3061 ASM_REWRITE_TAC[] THEN UNDISCH_THEN
3062 `!t:real^N->bool. t IN f ==> x IN t` (MP_TAC o SPEC `i:real^N->bool`) THEN
3063 ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o C MATCH_MP
3064 (ASSUME `(i:real^N->bool) IN f`)) THEN SET_TAC[];
3066 MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN
3067 ASM_SIMP_TAC[FACE_OF_IMP_SUBSET] THEN
3068 RULE_ASSUM_TAC(REWRITE_RULE[facet_of]) THEN ASM_SIMP_TAC[] THEN
3069 REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY] THEN
3070 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]);;
3072 let FACE_OF_POLYHEDRON_EXPLICIT = prove
3073 (`!s:real^N->bool f a b.
3075 s = affine hull s INTER INTERS f /\
3076 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
3077 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
3078 ==> !c. c face_of s /\ ~(c = {}) /\ ~(c = s)
3079 ==> c = INTERS {s INTER {x | a h dot x = b h} |h|
3081 c SUBSET (s INTER {x | a h dot x = b h})}`,
3083 (`!t s. (!a. P a ==> t SUBSET s INTER INTERS {f x | P x})
3084 ==> t SUBSET INTERS {s INTER f x | P x}`,
3085 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
3086 REWRITE_TAC[INTERS_IMAGE] THEN SET_TAC[]) in
3088 DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN
3089 DISCH_THEN(ASSUME_TAC o MATCH_MP FACET_OF_POLYHEDRON_EXPLICIT) THEN
3090 REPEAT STRIP_TAC THEN
3091 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_CONVEX) THEN
3092 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
3093 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
3094 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3095 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3097 FIRST_ASSUM(ASSUME_TAC o MATCH_MP POLYHEDRON_IMP_CONVEX) THEN
3100 h IN f ==> (s INTER {x:real^N | a h dot x = b h}) face_of s`
3102 [REPEAT STRIP_TAC THEN
3103 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN CONJ_TAC THENL
3104 [MATCH_MP_TAC POLYHEDRON_IMP_CONVEX THEN
3105 REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3106 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3107 X_GEN_TAC `x:real^N` THEN FIRST_X_ASSUM SUBST1_TAC THEN
3108 REWRITE_TAC[IN_INTER; IN_INTERS] THEN
3109 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool` o CONJUNCT2) THEN
3110 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
3111 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
3112 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
3114 SUBGOAL_THEN `~(relative_interior(c:real^N->bool) = {})` MP_TAC THENL
3115 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY]; ALL_TAC] THEN
3116 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_IMP_EXISTS_THM] THEN
3117 X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN
3118 SUBGOAL_THEN `(z:real^N) IN s` ASSUME_TAC THENL
3119 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN
3120 MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN
3123 MATCH_MP_TAC FACE_OF_EQ THEN EXISTS_TAC `s:real^N->bool` THEN
3124 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
3125 [MATCH_MP_TAC FACE_OF_INTERS THEN ASM_SIMP_TAC[FORALL_IN_GSPEC] THEN
3126 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[IMAGE_EQ_EMPTY] THEN
3127 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
3128 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3129 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3130 FACE_OF_POLYHEDRON_SUBSET_EXPLICIT) THEN
3131 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL[FIRST_ASSUM ACCEPT_TAC; ALL_TAC] THEN
3132 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
3135 `{s INTER {x | a(h:real^N->bool) dot x = b h} |h|
3136 h IN f /\ c SUBSET (s INTER {x:real^N | a h dot x = b h})} =
3137 {s INTER {x | a(h:real^N->bool) dot x = b h} |h|
3138 h IN f /\ z IN s INTER {x:real^N | a h dot x = b h}}`
3140 [MATCH_MP_TAC(SET_RULE
3141 `(!x. P x <=> Q x) ==> {f x | P x} = {f x | Q x}`) THEN
3142 X_GEN_TAC `h:real^N->bool` THEN EQ_TAC THEN STRIP_TAC THEN
3143 ASM_REWRITE_TAC[] THENL
3144 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN
3145 MATCH_MP_TAC(REWRITE_RULE[SUBSET] RELATIVE_INTERIOR_SUBSET) THEN
3147 MATCH_MP_TAC SUBSET_OF_FACE_OF THEN EXISTS_TAC `s:real^N->bool` THEN
3148 ASM_SIMP_TAC[] THEN ASM SET_TAC[]];
3150 REWRITE_TAC[DISJOINT; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
3151 EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
3153 `?e. &0 < e /\ !h. h IN f /\ a(h:real^N->bool) dot z < b h
3154 ==> ball(z,e) SUBSET {w:real^N | a h dot w < b h}`
3155 (CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THENL
3156 [REWRITE_TAC[SET_RULE
3157 `(!h. P h ==> s SUBSET t h) <=> s SUBSET INTERS (IMAGE t {h | P h})`] THEN
3158 MATCH_MP_TAC(MESON[OPEN_CONTAINS_BALL]
3159 `open s /\ x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s`) THEN
3160 SIMP_TAC[IN_INTERS; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
3161 MATCH_MP_TAC OPEN_INTERS THEN
3162 ASM_SIMP_TAC[FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_RESTRICT] THEN
3163 REWRITE_TAC[OPEN_HALFSPACE_LT];
3165 ASM_REWRITE_TAC[IN_RELATIVE_INTERIOR] THEN
3166 ASM_SIMP_TAC[IN_INTERS; FORALL_IN_GSPEC; IN_ELIM_THM; IN_INTER] THEN
3167 EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN
3168 MATCH_MP_TAC lemma THEN X_GEN_TAC `i:real^N->bool` THEN STRIP_TAC THEN
3169 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [th]) THEN
3170 MATCH_MP_TAC(SET_RULE
3171 `ae SUBSET as /\ ae SUBSET hs /\
3172 b INTER hs SUBSET fs
3173 ==> (b INTER ae) SUBSET (as INTER fs) INTER hs`) THEN
3174 REPEAT CONJ_TAC THENL
3175 [MATCH_MP_TAC HULL_MONO THEN
3176 REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_GSPEC] THEN ASM SET_TAC[];
3177 SIMP_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN
3178 REWRITE_TAC[FORALL_IN_GSPEC] THEN X_GEN_TAC `j:real^N->bool` THEN
3179 STRIP_TAC THEN MATCH_MP_TAC HULL_MINIMAL THEN
3180 REWRITE_TAC[AFFINE_HYPERPLANE] THEN
3181 REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_GSPEC] THEN ASM SET_TAC[];
3183 REWRITE_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN
3184 X_GEN_TAC `j:real^N->bool` THEN DISCH_TAC THEN
3185 SUBGOAL_THEN `(a:(real^N->bool)->real^N) j dot z <= b j` MP_TAC THENL
3186 [ASM SET_TAC[]; REWRITE_TAC[REAL_LE_LT]] THEN
3187 STRIP_TAC THENL [ASM SET_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN
3188 MATCH_MP_TAC(SET_RULE
3189 `(?s. s IN f /\ s SUBSET t) ==> u INTER INTERS f SUBSET t`) THEN
3190 REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `j:real^N->bool` THEN
3191 ASM SET_TAC[REAL_LE_REFL]);;
3193 (* ------------------------------------------------------------------------- *)
3194 (* More general corollaries from the explicit representation. *)
3195 (* ------------------------------------------------------------------------- *)
3197 let FACET_OF_POLYHEDRON = prove
3198 (`!s:real^N->bool c.
3199 polyhedron s /\ c facet_of s
3200 ==> ?a b. ~(a = vec 0) /\
3201 s SUBSET {x | a dot x <= b} /\
3202 c = s INTER {x | a dot x = b}`,
3203 REPEAT STRIP_TAC THEN FIRST_ASSUM
3204 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3205 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
3206 [RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3207 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3209 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3210 `b:(real^N->bool)->real`] THEN
3212 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3213 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3214 FACET_OF_POLYHEDRON_EXPLICIT) THEN
3215 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3216 DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3217 DISCH_THEN(X_CHOOSE_THEN `i:real^N->bool` STRIP_ASSUME_TAC) THEN
3218 EXISTS_TAC `(a:(real^N->bool)->real^N) i` THEN
3219 EXISTS_TAC `(b:(real^N->bool)->real) i` THEN ASM_SIMP_TAC[] THEN
3220 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
3221 MATCH_MP_TAC(SET_RULE `t SUBSET u ==> (s INTER t) SUBSET u`) THEN
3222 MATCH_MP_TAC(SET_RULE `t IN f ==> INTERS f SUBSET t`) THEN ASM_MESON_TAC[]);;
3224 let FACE_OF_POLYHEDRON = prove
3225 (`!s:real^N->bool c.
3226 polyhedron s /\ c face_of s /\ ~(c = {}) /\ ~(c = s)
3227 ==> c = INTERS {f | f facet_of s /\ c SUBSET f}`,
3228 REPEAT STRIP_TAC THEN FIRST_ASSUM
3229 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3230 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3231 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3233 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3234 `b:(real^N->bool)->real`] THEN
3236 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3237 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3238 FACET_OF_POLYHEDRON_EXPLICIT) THEN
3239 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3240 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
3241 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3242 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3243 FACE_OF_POLYHEDRON_EXPLICIT) THEN
3244 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3245 DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3246 DISCH_THEN(fun th -> GEN_REWRITE_TAC LAND_CONV [th]) THEN
3247 AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
3248 X_GEN_TAC `h:real^N->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[]);;
3250 let FACE_OF_POLYHEDRON_SUBSET_FACET = prove
3251 (`!s:real^N->bool c.
3252 polyhedron s /\ c face_of s /\ ~(c = {}) /\ ~(c = s)
3253 ==> ?f. f facet_of s /\ c SUBSET f`,
3254 REPEAT STRIP_TAC THEN
3255 FIRST_ASSUM(ASSUME_TAC o MATCH_MP FACE_OF_IMP_SUBSET) THEN
3256 MP_TAC(ISPECL [`s:real^N->bool`; `c:real^N->bool`] FACE_OF_POLYHEDRON) THEN
3257 ASM_CASES_TAC `{f:real^N->bool | f facet_of s /\ c SUBSET f} = {}` THEN
3260 let EXPOSED_FACE_OF_POLYHEDRON = prove
3261 (`!s f:real^N->bool. polyhedron s ==> (f exposed_face_of s <=> f face_of s)`,
3262 REPEAT STRIP_TAC THEN EQ_TAC THENL [SIMP_TAC[exposed_face_of]; ALL_TAC] THEN
3263 DISCH_TAC THEN ASM_CASES_TAC `f:real^N->bool = {}` THEN
3264 ASM_REWRITE_TAC[EMPTY_EXPOSED_FACE_OF] THEN
3265 ASM_CASES_TAC `f:real^N->bool = s` THEN
3266 ASM_SIMP_TAC[EXPOSED_FACE_OF_REFL; POLYHEDRON_IMP_CONVEX] THEN
3267 MP_TAC(ISPECL [`s:real^N->bool`; `f:real^N->bool`] FACE_OF_POLYHEDRON) THEN
3268 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
3269 MATCH_MP_TAC EXPOSED_FACE_OF_INTERS THEN
3270 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; FORALL_IN_GSPEC] THEN
3271 ASM_SIMP_TAC[FACE_OF_POLYHEDRON_SUBSET_FACET; IN_ELIM_THM] THEN
3272 ASM_SIMP_TAC[exposed_face_of; FACET_OF_IMP_FACE_OF] THEN
3273 ASM_MESON_TAC[FACET_OF_POLYHEDRON]);;
3275 let FACE_OF_POLYHEDRON_POLYHEDRON = prove
3276 (`!s:real^N->bool c. polyhedron s /\ c face_of s ==> polyhedron c`,
3277 REPEAT STRIP_TAC THEN FIRST_ASSUM
3278 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3279 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3280 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3282 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3283 `b:(real^N->bool)->real`] THEN
3285 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3286 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3287 FACE_OF_POLYHEDRON_EXPLICIT) THEN
3288 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3289 DISCH_THEN(MP_TAC o SPEC `c:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3290 ASM_CASES_TAC `c:real^N->bool = {}` THEN
3291 ASM_REWRITE_TAC[POLYHEDRON_EMPTY] THEN
3292 ASM_CASES_TAC `c:real^N->bool = s` THEN ASM_REWRITE_TAC[] THEN
3293 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC POLYHEDRON_INTERS THEN
3294 REWRITE_TAC[FORALL_IN_GSPEC] THEN
3295 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
3296 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT] THEN
3297 REPEAT STRIP_TAC THEN REWRITE_TAC[IMAGE_ID] THEN
3298 MATCH_MP_TAC POLYHEDRON_INTER THEN
3299 ASM_REWRITE_TAC[POLYHEDRON_HYPERPLANE]);;
3301 let FINITE_POLYHEDRON_FACES = prove
3302 (`!s:real^N->bool. polyhedron s ==> FINITE {f | f face_of s}`,
3303 REPEAT STRIP_TAC THEN FIRST_ASSUM
3304 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3305 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3306 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3308 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3309 `b:(real^N->bool)->real`] THEN
3311 MATCH_MP_TAC(MESON[FINITE_DELETE]
3312 `!a b. FINITE (s DELETE a DELETE b) ==> FINITE s`) THEN
3313 MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `s:real^N->bool`] THEN
3314 MATCH_MP_TAC FINITE_SUBSET THEN
3316 `{INTERS {s INTER {x:real^N | a(h:real^N->bool) dot x = b h} | h | h IN f'}
3317 |f'| f' SUBSET f}` THEN
3318 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SIMPLE_IMAGE_GEN] THEN
3319 ASM_SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE] THEN
3320 GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[IN_DELETE; IN_ELIM_THM] THEN
3321 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3322 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3323 FACE_OF_POLYHEDRON_EXPLICIT) THEN
3324 ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
3325 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `c:real^N->bool` THEN
3326 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
3327 DISCH_TAC THEN EXISTS_TAC
3329 h IN f /\ c SUBSET s INTER {x:real^N | a h dot x = b h}}` THEN
3330 CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
3331 ASM_REWRITE_TAC[IN_ELIM_THM] THEN FIRST_ASSUM ACCEPT_TAC);;
3333 let FINITE_POLYHEDRON_EXPOSED_FACES = prove
3334 (`!s:real^N->bool. polyhedron s ==> FINITE {f | f exposed_face_of s}`,
3335 SIMP_TAC[EXPOSED_FACE_OF_POLYHEDRON; FINITE_POLYHEDRON_FACES]);;
3337 let FINITE_POLYHEDRON_EXTREME_POINTS = prove
3338 (`!s:real^N->bool. polyhedron s ==> FINITE {v | v extreme_point_of s}`,
3339 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
3340 ONCE_REWRITE_TAC[SET_RULE `{v} face_of s <=> {v} IN {f | f face_of s}`] THEN
3341 MATCH_MP_TAC FINITE_FINITE_PREIMAGE THEN
3342 ASM_SIMP_TAC[FINITE_POLYHEDRON_FACES] THEN X_GEN_TAC `f:real^N->bool` THEN
3343 DISCH_TAC THEN ASM_CASES_TAC `!a:real^N. ~({a} = f)` THEN
3344 ASM_REWRITE_TAC[EMPTY_GSPEC; FINITE_EMPTY] THEN
3345 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
3346 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
3347 GEN_TAC THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
3348 REWRITE_TAC[SET_RULE `{v | {v} = {a}} = {a}`; FINITE_SING]);;
3350 let FINITE_POLYHEDRON_FACETS = prove
3351 (`!s:real^N->bool. polyhedron s ==> FINITE {f | f facet_of s}`,
3352 REWRITE_TAC[facet_of] THEN ONCE_REWRITE_TAC[SET_RULE
3353 `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN
3354 SIMP_TAC[FINITE_RESTRICT; FINITE_POLYHEDRON_FACES]);;
3356 let RELATIVE_INTERIOR_OF_POLYHEDRON = prove
3359 ==> relative_interior s = s DIFF UNIONS {f | f facet_of s}`,
3360 REPEAT STRIP_TAC THEN FIRST_ASSUM
3361 (MP_TAC o GEN_REWRITE_RULE I [POLYHEDRON_INTER_AFFINE_MINIMAL]) THEN
3362 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
3363 [RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
3364 SIMP_TAC[LEFT_IMP_EXISTS_THM; RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
3366 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3367 `b:(real^N->bool)->real`] THEN
3369 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3370 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3371 FACET_OF_POLYHEDRON_EXPLICIT) THEN
3372 MP_TAC(ISPECL [`s:real^N->bool`; `f:(real^N->bool)->bool`;
3373 `a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`]
3374 RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3375 ASM_REWRITE_TAC[] THEN
3376 ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN
3377 ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_TAC] THEN
3378 ASM_REWRITE_TAC[] THEN
3379 MATCH_MP_TAC(SET_RULE
3380 `(!x. x IN s ==> P x \/ x IN t) /\ (!x. x IN t ==> ~P x)
3381 ==> {x | x IN s /\ P x} = s DIFF t`) THEN
3382 REWRITE_TAC[FORALL_IN_UNIONS] THEN
3383 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
3385 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
3386 REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN
3387 REWRITE_TAC[LEFT_AND_EXISTS_THM; TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
3388 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3389 ASM_REWRITE_TAC[UNWIND_THM2; IN_ELIM_THM; IN_INTER] THEN
3390 MATCH_MP_TAC(SET_RULE
3391 `(!x. P x ==> Q x \/ R x) ==> (!x. P x ==> Q x) \/ (?x. P x /\ R x)`) THEN
3392 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
3393 REWRITE_TAC[GSYM REAL_LE_LT] THEN
3394 SUBGOAL_THEN `(x:real^N) IN INTERS f` MP_TAC THENL
3395 [ASM SET_TAC[]; ALL_TAC] THEN
3396 REWRITE_TAC[IN_INTERS] THEN
3397 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN
3398 SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` MP_TAC THENL
3399 [ASM_MESON_TAC[]; ASM_REWRITE_TAC[] THEN SET_TAC[]];
3400 X_GEN_TAC `h:real^N->bool` THEN
3401 DISCH_THEN(X_CHOOSE_THEN `g:real^N->bool` STRIP_ASSUME_TAC) THEN
3402 X_GEN_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
3403 ASM_MESON_TAC[REAL_LT_REFL]]);;
3405 let RELATIVE_BOUNDARY_OF_POLYHEDRON = prove
3408 ==> s DIFF relative_interior s = UNIONS {f | f facet_of s}`,
3409 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[RELATIVE_INTERIOR_OF_POLYHEDRON] THEN
3410 MATCH_MP_TAC(SET_RULE `f SUBSET s ==> s DIFF (s DIFF f) = f`) THEN
3411 REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN
3412 MESON_TAC[FACET_OF_IMP_SUBSET; SUBSET]);;
3414 let RELATIVE_FRONTIER_OF_POLYHEDRON = prove
3416 polyhedron s ==> relative_frontier s = UNIONS {f | f facet_of s}`,
3417 SIMP_TAC[relative_frontier; POLYHEDRON_IMP_CLOSED; CLOSURE_CLOSED] THEN
3418 REWRITE_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON]);;
3420 let RELATIVE_FRONTIER_OF_POLYHEDRON_ALT = prove
3423 ==> relative_frontier s = UNIONS {f | f face_of s /\ ~(f = s)}`,
3424 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
3425 [ASM_SIMP_TAC[RELATIVE_FRONTIER_OF_POLYHEDRON; facet_of] THEN
3426 MATCH_MP_TAC SUBSET_UNIONS THEN SIMP_TAC[SUBSET; IN_ELIM_THM] THEN
3427 MESON_TAC[INT_ARITH `~(f - &1:int = f)`];
3428 REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN
3429 MESON_TAC[REWRITE_RULE[SUBSET] FACE_OF_SUBSET_RELATIVE_FRONTIER]]);;
3431 let FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT = prove
3432 (`!s:real^N->bool f a b.
3434 s = affine hull s INTER INTERS f /\
3435 (!h. h IN f ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}) /\
3436 (!f'. f' PSUBSET f ==> s PSUBSET affine hull s INTER INTERS f')
3437 ==> !h1 h2. h1 IN f /\ h2 IN f /\
3438 s INTER {x | a h1 dot x = b h1} =
3439 s INTER {x | a h2 dot x = b h2}
3441 REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
3442 [ASM_REWRITE_TAC[AFFINE_HULL_EMPTY; INTER_EMPTY; PSUBSET_IRREFL] THEN
3443 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
3444 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
3445 ASM_MESON_TAC[SET_RULE `~(s = {}) ==> {} PSUBSET s`];
3447 SUBGOAL_THEN `polyhedron(s:real^N->bool)` ASSUME_TAC THENL
3448 [REWRITE_TAC[POLYHEDRON_INTER_AFFINE] THEN
3449 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN ASM_MESON_TAC[];
3451 SUBGOAL_THEN `~(relative_interior s:real^N->bool = {})` MP_TAC THENL
3452 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYHEDRON_IMP_CONVEX];
3453 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
3454 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC)] THEN
3455 DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3457 [`s:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3458 `b:(real^N->bool)->real`] RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
3460 [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC] THEN
3461 REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
3462 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3463 FIRST_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`) THEN
3464 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[PSUBSET_ALT]] THEN
3465 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `x:real^N` MP_TAC)) THEN
3466 REWRITE_TAC[IN_INTER; IN_INTERS; IN_DELETE] THEN STRIP_TAC THEN
3467 MP_TAC(ISPECL [`segment[x:real^N,z]`; `s:real^N->bool`]
3468 CONNECTED_INTER_RELATIVE_FRONTIER) THEN
3469 PURE_REWRITE_TAC[relative_frontier] THEN ANTS_TAC THENL
3470 [REWRITE_TAC[CONNECTED_SEGMENT; GSYM MEMBER_NOT_EMPTY] THEN
3471 REPEAT CONJ_TAC THENL
3472 [ASM_MESON_TAC[CONVEX_CONTAINS_SEGMENT; AFFINE_AFFINE_HULL;
3473 HULL_INC; AFFINE_IMP_CONVEX];
3474 EXISTS_TAC `z:real^N` THEN ASM_REWRITE_TAC[IN_INTER; ENDS_IN_SEGMENT];
3475 EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[IN_DIFF; ENDS_IN_SEGMENT]];
3477 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
3478 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; CLOSURE_CLOSED;
3479 LEFT_IMP_EXISTS_THM; IN_INTER] THEN
3480 X_GEN_TAC `y:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3481 DISCH_THEN(fun th -> STRIP_ASSUME_TAC(REWRITE_RULE[IN_DIFF] th) THEN
3483 ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON] THEN
3485 [`s:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
3486 `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN
3488 [ASM_SIMP_TAC[] THEN ASM_MESON_TAC[];
3489 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th])] THEN
3490 REWRITE_TAC[SET_RULE `{y | ?x. x IN s /\ y = f x} = IMAGE f s`] THEN
3491 REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_INTER] THEN
3492 DISCH_THEN(X_CHOOSE_THEN `h:real^N->bool` STRIP_ASSUME_TAC) THEN
3494 `?k:real^N->bool. k IN f /\ ~(k = h2) /\ a k dot (y:real^N) = b k`
3495 STRIP_ASSUME_TAC THENL
3496 [ASM_CASES_TAC `h:real^N->bool = h2` THENL
3497 [EXISTS_TAC `h1:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
3498 UNDISCH_TAC `s INTER {x:real^N | a(h1:real^N->bool) dot x = b h1} =
3499 s INTER {x | a h2 dot x = b h2}` THEN
3500 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[];
3504 `(a:(real^N->bool)->real^N) k dot z < b k /\ a k dot x <= b k`
3505 STRIP_ASSUME_TAC THENL [ASM_SIMP_TAC[] THEN ASM SET_TAC[]; ALL_TAC] THEN
3506 SUBGOAL_THEN `y IN segment(x:real^N,z)` MP_TAC THENL
3507 [ASM_REWRITE_TAC[IN_OPEN_SEGMENT_ALT] THEN ASM_MESON_TAC[];
3508 REWRITE_TAC[IN_SEGMENT] THEN STRIP_TAC] THEN
3509 UNDISCH_TAC `(a:(real^N->bool)->real^N) k dot y = b k` THEN
3510 ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
3511 MATCH_MP_TAC(REAL_ARITH
3512 `(&1 - u) * x <= (&1 - u) * b /\ u * y < u * b
3513 ==> ~((&1 - u) * x + u * y = b)`) THEN
3514 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LE_LMUL_EQ; REAL_SUB_LT]);;
3516 (* ------------------------------------------------------------------------- *)
3517 (* A characterization of polyhedra as having finitely many faces. *)
3518 (* ------------------------------------------------------------------------- *)
3520 let POLYHEDRON_EQ_FINITE_EXPOSED_FACES = prove
3522 polyhedron s <=> closed s /\ convex s /\ FINITE {f | f exposed_face_of s}`,
3523 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
3524 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_IMP_CONVEX;
3525 FINITE_POLYHEDRON_EXPOSED_FACES] THEN
3526 ASM_CASES_TAC `s:real^N->bool = {}` THEN
3527 ASM_REWRITE_TAC[POLYHEDRON_EMPTY] THEN
3529 `f = {h:real^N->bool | h exposed_face_of s /\ ~(h = {}) /\ ~(h = s)}` THEN
3530 SUBGOAL_THEN `FINITE(f:(real^N->bool)->bool)` ASSUME_TAC THENL
3531 [EXPAND_TAC "f" THEN
3532 ONCE_REWRITE_TAC[SET_RULE
3533 `{x | P x /\ Q x} = {x | x IN {x | P x} /\ Q x}`] THEN
3534 ASM_SIMP_TAC[FINITE_RESTRICT];
3540 ?a b. ~(a = vec 0) /\
3541 s SUBSET {x | a dot x <= b} /\
3542 h = s INTER {x | a dot x = b}`
3544 [EXPAND_TAC "f" THEN REWRITE_TAC[EXPOSED_FACE_OF; IN_ELIM_THM] THEN
3547 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; FORALL_AND_THM;
3548 TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
3549 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3550 DISCH_THEN(X_CHOOSE_THEN `a:(real^N->bool)->real^N` MP_TAC) THEN
3551 DISCH_THEN(X_CHOOSE_THEN `b:(real^N->bool)->real` STRIP_ASSUME_TAC) THEN
3553 `s = affine hull s INTER
3554 INTERS {{x:real^N | a(h:real^N->bool) dot x <= b h} | h IN f}`
3557 MATCH_MP_TAC POLYHEDRON_INTER THEN REWRITE_TAC[POLYHEDRON_AFFINE_HULL] THEN
3558 MATCH_MP_TAC POLYHEDRON_INTERS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
3559 ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; POLYHEDRON_HALFSPACE_LE]] THEN
3560 MATCH_MP_TAC SUBSET_ANTISYM THEN
3561 REWRITE_TAC[SUBSET_INTER; HULL_SUBSET;
3562 SET_RULE `s SUBSET INTERS f <=> !h. h IN f ==> s SUBSET h`] THEN
3563 ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN
3564 REWRITE_TAC[SUBSET; IN_INTER; IN_INTERS; FORALL_IN_GSPEC] THEN
3565 X_GEN_TAC `p:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
3566 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3567 SUBGOAL_THEN `~(relative_interior(s:real^N->bool) = {})` MP_TAC THENL
3568 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY];
3569 GEN_REWRITE_TAC LAND_CONV [GSYM MEMBER_NOT_EMPTY] THEN
3570 DISCH_THEN(X_CHOOSE_TAC `c:real^N`)] THEN
3572 `?x:real^N. x IN segment[c,p] /\ x IN (s DIFF relative_interior s)`
3574 [MP_TAC(ISPEC `segment[c:real^N,p]` CONNECTED_OPEN_IN) THEN
3575 REWRITE_TAC[CONNECTED_SEGMENT; NOT_EXISTS_THM] THEN
3576 DISCH_THEN(MP_TAC o SPECL
3577 [`segment[c:real^N,p] INTER relative_interior s`;
3578 `segment[c:real^N,p] INTER (UNIV DIFF s)`]) THEN
3579 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
3580 REWRITE_TAC[IN_DIFF; NOT_EXISTS_THM] THEN DISCH_TAC THEN
3581 REPEAT CONJ_TAC THENL
3582 [MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN
3583 EXISTS_TAC `affine hull s:real^N->bool` THEN
3584 SIMP_TAC[OPEN_IN_RELATIVE_INTERIOR; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY;
3585 OPEN_IN_SUBTOPOLOGY_REFL; SUBSET_UNIV; OPEN_IN_INTER;
3586 TOPSPACE_EUCLIDEAN] THEN
3587 REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC HULL_MINIMAL THEN
3588 SIMP_TAC[AFFINE_IMP_CONVEX; AFFINE_AFFINE_HULL] THEN
3589 ASM_REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN
3590 ASM_MESON_TAC[RELATIVE_INTERIOR_SUBSET; HULL_INC; SUBSET];
3591 REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC `(:real^N) DIFF s` THEN
3592 ASM_REWRITE_TAC[GSYM closed];
3593 MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN ASM SET_TAC[];
3594 MP_TAC(ISPEC `s:real^N->bool` RELATIVE_INTERIOR_SUBSET) THEN SET_TAC[];
3595 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
3596 ASM_MESON_TAC[ENDS_IN_SEGMENT];
3597 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_DIFF; IN_INTER; IN_UNIV] THEN
3598 ASM_MESON_TAC[ENDS_IN_SEGMENT]];
3599 REWRITE_TAC[IN_SEGMENT; LEFT_AND_EXISTS_THM] THEN
3600 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3601 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
3602 DISCH_THEN(X_CHOOSE_THEN `l:real` MP_TAC) THEN
3603 ASM_CASES_TAC `l = &0` THEN
3604 ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_MUL_LZERO; REAL_SUB_RZERO;
3605 VECTOR_MUL_LID; IN_DIFF] THEN
3606 ASM_CASES_TAC `l = &1` THEN
3607 ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO; REAL_SUB_REFL;
3608 VECTOR_MUL_LID; IN_DIFF] THEN
3609 ASM_REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC] THEN
3610 ABBREV_TAC `x:real^N = (&1 - l) % c + l % p` THEN
3611 SUBGOAL_THEN `?h:real^N->bool. h IN f /\ x IN h` STRIP_ASSUME_TAC THENL
3612 [MP_TAC(ISPECL [`s:real^N->bool`; `(&1 - l) % c + l % p:real^N`]
3613 SUPPORTING_HYPERPLANE_RELATIVE_FRONTIER) THEN
3614 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN
3615 DISCH_THEN(X_CHOOSE_THEN `d:real^N` STRIP_ASSUME_TAC) THEN
3617 EXISTS_TAC `s INTER {y:real^N | d dot y = d dot x}` THEN
3618 ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT CONJ_TAC THENL
3619 [MATCH_MP_TAC EXPOSED_FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN
3620 ASM_SIMP_TAC[real_ge; REWRITE_RULE[SUBSET] CLOSURE_SUBSET];
3622 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM] THEN
3623 DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN
3624 ASM_MESON_TAC[SUBSET; REAL_LT_REFL; RELATIVE_INTERIOR_SUBSET]];
3626 SUBGOAL_THEN `{y:real^N | a(h:real^N->bool) dot y = b h} face_of
3627 {y | a h dot y <= b h}`
3629 [MATCH_MP_TAC(MESON[]
3630 `(t INTER s) face_of t /\ t INTER s = s ==> s face_of t`) THEN
3632 [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
3633 REWRITE_TAC[IN_ELIM_THM; CONVEX_HALFSPACE_LE];
3634 SET_TAC[REAL_LE_REFL]];
3636 REWRITE_TAC[face_of] THEN
3637 DISCH_THEN(MP_TAC o SPECL [`c:real^N`; `p:real^N`; `x:real^N`] o
3638 CONJUNCT2 o CONJUNCT2) THEN
3639 ASM_SIMP_TAC[IN_ELIM_THM; NOT_IMP; GSYM CONJ_ASSOC] THEN
3640 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
3641 RELATIVE_INTERIOR_SUBSET)) THEN
3642 REPEAT CONJ_TAC THENL
3645 REWRITE_TAC[IN_SEGMENT] THEN ASM SET_TAC[];
3647 MP_TAC(ISPECL [`s:real^N->bool`; `h:real^N->bool`; `s:real^N->bool`]
3648 SUBSET_OF_FACE_OF) THEN
3651 let POLYHEDRON_EQ_FINITE_FACES = prove
3654 closed s /\ convex s /\ FINITE {f | f face_of s}`,
3655 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
3656 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_IMP_CONVEX;
3657 FINITE_POLYHEDRON_FACES] THEN
3658 REWRITE_TAC[POLYHEDRON_EQ_FINITE_EXPOSED_FACES] THEN
3659 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FINITE_SUBSET THEN
3660 EXISTS_TAC `{f:real^N->bool | f face_of s}` THEN
3661 ASM_REWRITE_TAC[] THEN
3662 SIMP_TAC[SUBSET; IN_ELIM_THM; exposed_face_of]);;
3664 let POLYHEDRON_TRANSLATION_EQ = prove
3665 (`!a s. polyhedron (IMAGE (\x:real^N. a + x) s) <=> polyhedron s`,
3666 REPEAT STRIP_TAC THEN REWRITE_TAC[POLYHEDRON_EQ_FINITE_FACES] THEN
3667 REWRITE_TAC[CLOSED_TRANSLATION_EQ] THEN AP_TERM_TAC THEN
3668 REWRITE_TAC[CONVEX_TRANSLATION_EQ] THEN AP_TERM_TAC THEN
3669 MP_TAC(ISPEC `IMAGE (\x:real^N. a + x)` QUANTIFY_SURJECTION_THM) THEN
3670 REWRITE_TAC[SURJECTIVE_IMAGE; EXISTS_REFL;
3671 VECTOR_ARITH `a + x:real^N = y <=> x = y - a`] THEN
3672 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
3673 REWRITE_TAC[FACE_OF_TRANSLATION_EQ] THEN
3674 MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN
3675 MATCH_MP_TAC(MESON[]
3676 `(!x y. Q x y ==> R x y) ==> (!x y. P x /\ P y /\ Q x y ==> R x y)`) THEN
3677 REWRITE_TAC[INJECTIVE_IMAGE] THEN VECTOR_ARITH_TAC);;
3679 add_translation_invariants [POLYHEDRON_TRANSLATION_EQ];;
3681 let POLYHEDRON_LINEAR_IMAGE_EQ = prove
3682 (`!f:real^M->real^N s.
3683 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
3684 ==> (polyhedron (IMAGE f s) <=> polyhedron s)`,
3685 REPEAT STRIP_TAC THEN REWRITE_TAC[POLYHEDRON_EQ_FINITE_FACES] THEN
3687 [ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]; ALL_TAC] THEN
3688 BINOP_TAC THENL [ASM_MESON_TAC[CONVEX_LINEAR_IMAGE_EQ]; ALL_TAC] THEN
3689 MP_TAC(ISPEC `IMAGE (f:real^M->real^N)` QUANTIFY_SURJECTION_THM) THEN
3690 ASM_REWRITE_TAC[SURJECTIVE_IMAGE] THEN
3691 DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
3692 MP_TAC(ISPEC `f:real^M->real^N` FACE_OF_LINEAR_IMAGE) THEN
3693 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
3694 MATCH_MP_TAC FINITE_IMAGE_INJ_EQ THEN
3695 FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [GSYM INJECTIVE_IMAGE]) THEN
3696 ASM_REWRITE_TAC[IMP_CONJ]);;
3698 add_linear_invariants [POLYHEDRON_LINEAR_IMAGE_EQ];;
3700 let POLYHEDRON_NEGATIONS = prove
3701 (`!s:real^N->bool. polyhedron s ==> polyhedron(IMAGE (--) s)`,
3702 GEN_TAC THEN MATCH_MP_TAC EQ_IMP THEN CONV_TAC SYM_CONV THEN
3703 MATCH_MP_TAC POLYHEDRON_LINEAR_IMAGE_EQ THEN
3704 REWRITE_TAC[VECTOR_ARITH `--x:real^N = y <=> x = --y`; EXISTS_REFL] THEN
3705 REWRITE_TAC[LINEAR_NEGATION] THEN VECTOR_ARITH_TAC);;
3707 (* ------------------------------------------------------------------------- *)
3708 (* Relation between polytopes and polyhedra. *)
3709 (* ------------------------------------------------------------------------- *)
3711 let POLYTOPE_EQ_BOUNDED_POLYHEDRON = prove
3712 (`!s:real^N->bool. polytope s <=> polyhedron s /\ bounded s`,
3713 GEN_TAC THEN EQ_TAC THENL
3714 [SIMP_TAC[FINITE_POLYTOPE_FACES; POLYHEDRON_EQ_FINITE_FACES;
3715 POLYTOPE_IMP_CLOSED; POLYTOPE_IMP_CONVEX; POLYTOPE_IMP_BOUNDED];
3716 STRIP_TAC THEN REWRITE_TAC[polytope] THEN
3717 EXISTS_TAC `{v:real^N | v extreme_point_of s}` THEN
3718 ASM_SIMP_TAC[FINITE_POLYHEDRON_EXTREME_POINTS] THEN
3719 MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
3720 ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; POLYHEDRON_IMP_CLOSED;
3721 POLYHEDRON_IMP_CONVEX]]);;
3723 let POLYTOPE_INTER = prove
3724 (`!s t. polytope s /\ polytope t ==> polytope(s INTER t)`,
3725 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER; BOUNDED_INTER]);;
3727 let POLYTOPE_INTER_POLYHEDRON = prove
3728 (`!s t:real^N->bool. polytope s /\ polyhedron t ==> polytope(s INTER t)`,
3729 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER] THEN
3730 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
3732 let POLYHEDRON_INTER_POLYTOPE = prove
3733 (`!s t:real^N->bool. polyhedron s /\ polytope t ==> polytope(s INTER t)`,
3734 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON; POLYHEDRON_INTER] THEN
3735 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
3737 let POLYTOPE_IMP_POLYHEDRON = prove
3738 (`!p. polytope p ==> polyhedron p`,
3739 SIMP_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON]);;
3741 let POLYTOPE_FACET_EXISTS = prove
3742 (`!p:real^N->bool. polytope p /\ &0 < aff_dim p ==> ?f. f facet_of p`,
3743 GEN_TAC THEN ASM_CASES_TAC `p:real^N->bool = {}` THEN
3744 ASM_REWRITE_TAC[AFF_DIM_EMPTY] THEN CONV_TAC INT_REDUCE_CONV THEN
3746 MP_TAC(ISPEC `p:real^N->bool` EXTREME_POINT_EXISTS_CONVEX) THEN
3747 ASM_SIMP_TAC[POLYTOPE_IMP_COMPACT; POLYTOPE_IMP_CONVEX] THEN
3748 DISCH_THEN(X_CHOOSE_TAC `v:real^N`) THEN
3749 MP_TAC(ISPECL [`p:real^N->bool`; `{v:real^N}`]
3750 FACE_OF_POLYHEDRON_SUBSET_FACET) THEN
3751 ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
3752 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON; FACE_OF_SING; NOT_INSERT_EMPTY] THEN
3753 ASM_MESON_TAC[AFF_DIM_SING; INT_LT_REFL]);;
3755 let POLYHEDRON_INTERVAL = prove
3756 (`!a b. polyhedron(interval[a,b])`,
3757 MESON_TAC[POLYTOPE_IMP_POLYHEDRON; POLYTOPE_INTERVAL]);;
3759 let POLYHEDRON_CONVEX_HULL = prove
3760 (`!s. FINITE s ==> polyhedron(convex hull s)`,
3761 SIMP_TAC[POLYTOPE_CONVEX_HULL; POLYTOPE_IMP_POLYHEDRON]);;
3763 (* ------------------------------------------------------------------------- *)
3764 (* Polytope is union of convex hulls of facets plus any point inside. *)
3765 (* ------------------------------------------------------------------------- *)
3767 let POLYTOPE_UNION_CONVEX_HULL_FACETS = prove
3768 (`!s p:real^N->bool.
3769 polytope p /\ &0 < aff_dim p /\ ~(s = {}) /\ s SUBSET p
3770 ==> p = UNIONS { convex hull (s UNION f) | f facet_of p}`,
3771 let lemma = SET_RULE `{f x | p x} = {y | ?x. p x /\ y = f x}` in
3772 MATCH_MP_TAC SET_PROVE_CASES THEN REWRITE_TAC[] THEN
3773 X_GEN_TAC `a:real^N` THEN ONCE_REWRITE_TAC[lemma] THEN
3774 GEOM_ORIGIN_TAC `a:real^N` THEN ONCE_REWRITE_TAC[GSYM lemma] THEN
3775 X_GEN_TAC `s:real^N->bool` THEN DISCH_THEN(K ALL_TAC) THEN
3776 MP_TAC(SET_RULE `(vec 0:real^N) IN (vec 0 INSERT s)`) THEN
3777 SPEC_TAC(`(vec 0:real^N) INSERT s`,`s:real^N->bool`) THEN
3778 X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN
3779 X_GEN_TAC `p:real^N->bool` THEN STRIP_TAC THEN
3780 FIRST_ASSUM(STRIP_ASSUME_TAC o
3781 GEN_REWRITE_RULE I [POLYTOPE_EQ_BOUNDED_POLYHEDRON]) THEN
3782 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
3784 REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IMP_CONJ] THEN
3785 REWRITE_TAC[FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM] THEN
3786 X_GEN_TAC `f:real^N->bool` THEN DISCH_TAC THEN
3787 REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN
3788 EXISTS_TAC `convex hull p:real^N->bool` THEN CONJ_TAC THENL
3789 [MATCH_MP_TAC HULL_MONO THEN
3790 FIRST_ASSUM(MP_TAC o MATCH_MP FACET_OF_IMP_SUBSET) THEN ASM SET_TAC[];
3791 ASM_MESON_TAC[CONVEX_HULL_EQ; POLYHEDRON_IMP_CONVEX; SUBSET_REFL]]] THEN
3792 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN
3793 ASM_CASES_TAC `v:real^N = vec 0` THENL
3794 [MP_TAC(ISPEC `p:real^N->bool` POLYTOPE_FACET_EXISTS) THEN
3795 ASM_REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
3796 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN
3797 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[HULL_INC; IN_UNION];
3799 SUBGOAL_THEN `?t. &1 < t /\ ~((t % v:real^N) IN p)` STRIP_ASSUME_TAC THENL
3800 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
3801 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
3802 EXISTS_TAC `max (&2) ((B + &1) / norm (v:real^N))` THEN
3803 CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
3804 FIRST_X_ASSUM(MATCH_MP_TAC o
3805 GEN_REWRITE_RULE BINDER_CONV [GSYM CONTRAPOS_THM]) THEN
3806 ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LE_RDIV_EQ; NORM_POS_LT] THEN
3807 MATCH_MP_TAC(REAL_ARITH `a < b ==> ~(abs(max (&2) b) <= a)`) THEN
3808 ASM_SIMP_TAC[REAL_LT_DIV2_EQ; NORM_POS_LT] THEN REAL_ARITH_TAC;
3810 SUBGOAL_THEN `(vec 0:real^N) IN p` ASSUME_TAC THENL
3811 [ASM SET_TAC[]; ALL_TAC] THEN
3812 MP_TAC(ISPECL [`segment[vec 0,t % v:real^N] INTER p`; `vec 0:real^N`]
3813 DISTANCE_ATTAINS_SUP) THEN
3815 [ASM_SIMP_TAC[COMPACT_INTER_CLOSED; POLYHEDRON_IMP_CLOSED; COMPACT_SEGMENT;
3816 GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
3817 ASM_MESON_TAC[ENDS_IN_SEGMENT];
3818 REWRITE_TAC[IN_INTER; GSYM CONJ_ASSOC; IMP_CONJ] THEN
3819 REWRITE_TAC[segment; FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN
3820 REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; DIST_0] THEN
3821 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; NORM_MUL; REAL_MUL_ASSOC] THEN
3822 ASM_SIMP_TAC[REAL_LE_RMUL_EQ; NORM_POS_LT; LEFT_IMP_EXISTS_THM;
3823 REAL_ARITH `&1 < t ==> &0 < abs t`] THEN
3824 X_GEN_TAC `u:real` THEN
3825 ASM_CASES_TAC `u = &1` THEN ASM_REWRITE_TAC[VECTOR_MUL_LID] THEN
3826 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3827 ASM_SIMP_TAC[real_abs] THEN DISCH_TAC] THEN
3828 SUBGOAL_THEN `inv(t) <= u` ASSUME_TAC THENL
3829 [FIRST_X_ASSUM MATCH_MP_TAC THEN
3830 ASM_SIMP_TAC[REAL_INV_LE_1; REAL_LT_IMP_LE; REAL_LE_INV_EQ;
3831 REAL_ARITH `&1 < t ==> &0 <= t`] THEN
3832 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID;
3833 REAL_ARITH `&1 < t ==> ~(t = &0)`];
3835 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH `&1 < t ==> &0 < t`)) THEN
3836 SUBGOAL_THEN `&0 < u /\ u < &1` STRIP_ASSUME_TAC THENL
3837 [ASM_REWRITE_TAC[REAL_LT_LE] THEN
3838 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
3839 UNDISCH_TAC `inv t <= &0` THEN REWRITE_TAC[REAL_NOT_LE] THEN
3840 ASM_REWRITE_TAC[REAL_LT_INV_EQ];
3842 MATCH_MP_TAC(SET_RULE `!t. t SUBSET s /\ x IN t ==> x IN s`) THEN
3843 EXISTS_TAC `convex hull {vec 0:real^N,u % t % v}` THEN CONJ_TAC THENL
3845 REWRITE_TAC[CONVEX_HULL_2; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN
3846 REWRITE_TAC[IN_ELIM_THM] THEN
3847 MAP_EVERY EXISTS_TAC [`&1 - inv(u * t)`; `inv(u * t):real`] THEN
3848 REWRITE_TAC[REAL_ARITH `&1 - x + x = &1`; REAL_SUB_LE; REAL_LE_INV_EQ] THEN
3849 ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; VECTOR_MUL_ASSOC] THEN
3850 ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_ENTIRE; REAL_MUL_LINV;
3851 REAL_LT_IMP_NZ; VECTOR_MUL_LID] THEN
3852 MATCH_MP_TAC REAL_INV_LE_1 THEN ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN
3853 ASM_REWRITE_TAC[real_div; REAL_MUL_LID]] THEN
3855 `(u % t % v:real^N) IN (p DIFF relative_interior p)`
3858 ASM_SIMP_TAC[RELATIVE_INTERIOR_OF_POLYHEDRON] THEN
3859 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
3860 `x IN s DIFF (s DIFF t) ==> x IN t`)) THEN
3861 REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
3862 DISCH_THEN(X_CHOOSE_THEN `f:real^N->bool` STRIP_ASSUME_TAC) THEN
3863 MATCH_MP_TAC(SET_RULE
3864 `(?s. s IN f /\ t SUBSET s) ==> t SUBSET UNIONS f`) THEN
3865 REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `f:real^N->bool` THEN
3866 ASM_SIMP_TAC[SUBSET_HULL; CONVEX_CONVEX_HULL] THEN
3867 ASM_SIMP_TAC[HULL_INC; IN_UNION; INSERT_SUBSET; EMPTY_SUBSET]] THEN
3868 ASM_REWRITE_TAC[IN_DIFF; IN_RELATIVE_INTERIOR] THEN
3869 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3870 REWRITE_TAC[SUBSET; IN_BALL; IN_INTER; dist] THEN
3871 ABBREV_TAC `k = min (e / &2 / norm(t % v:real^N)) (&1 - u)` THEN
3872 SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL
3873 [EXPAND_TAC "k" THEN REWRITE_TAC[REAL_LT_MIN] THEN
3874 ASM_REWRITE_TAC[REAL_SUB_LT] THEN MATCH_MP_TAC REAL_LT_DIV THEN
3875 ASM_SIMP_TAC[REAL_HALF; NORM_POS_LT; VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ];
3877 DISCH_THEN(MP_TAC o SPEC `(u + k) % t % v:real^N`) THEN
3878 REWRITE_TAC[VECTOR_ARITH `u % x - (u + k) % x:real^N = --k % x`] THEN
3879 ONCE_REWRITE_TAC[NORM_MUL] THEN REWRITE_TAC[REAL_ABS_NEG; NOT_IMP] THEN
3880 REPEAT CONJ_TAC THENL
3881 [MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
3882 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_MUL_EQ_0;
3883 REAL_LT_IMP_NZ] THEN
3884 ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN
3885 EXPAND_TAC "k" THEN REAL_ARITH_TAC;
3886 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN
3887 REPEAT(MATCH_MP_TAC SPAN_MUL) THEN ASM_SIMP_TAC[SPAN_SUPERSET];
3889 FIRST_X_ASSUM(MP_TAC o SPEC `u + k:real`) THEN
3890 ASM_REWRITE_TAC[NOT_IMP] THEN
3891 MATCH_MP_TAC(REAL_ARITH
3892 `&0 <= u /\ &0 < x /\ x <= &1 - u
3893 ==> (&0 <= u + x /\ u + x <= &1) /\ ~(u + x <= u)`) THEN
3894 ASM_REWRITE_TAC[] THEN EXPAND_TAC "k" THEN REAL_ARITH_TAC]);;
3896 (* ------------------------------------------------------------------------- *)
3897 (* Finitely generated cone is polyhedral, and hence closed. *)
3898 (* ------------------------------------------------------------------------- *)
3900 let POLYHEDRON_CONVEX_CONE_HULL = prove
3901 (`!s:real^N->bool. FINITE s ==> polyhedron(convex_cone hull s)`,
3902 GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN DISCH_TAC THENL
3903 [ASM_REWRITE_TAC[CONVEX_CONE_HULL_EMPTY] THEN
3904 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON; POLYTOPE_SING];
3907 `polyhedron(convex hull ((vec 0:real^N) INSERT s))`
3909 [MATCH_MP_TAC POLYTOPE_IMP_POLYHEDRON THEN
3910 REWRITE_TAC[polytope] THEN ASM_MESON_TAC[FINITE_INSERT];
3911 REWRITE_TAC[polyhedron] THEN
3912 DISCH_THEN(X_CHOOSE_THEN `f:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
3913 RULE_ASSUM_TAC(REWRITE_RULE[SKOLEM_THM; RIGHT_IMP_EXISTS_THM]) THEN
3914 FIRST_X_ASSUM(X_CHOOSE_THEN `a:(real^N->bool)->real^N` MP_TAC) THEN
3915 DISCH_THEN(X_CHOOSE_TAC `b:(real^N->bool)->real`)] THEN
3916 SUBGOAL_THEN `~(f:(real^N->bool)->bool = {})` ASSUME_TAC THENL
3917 [DISCH_THEN SUBST_ALL_TAC THEN FIRST_X_ASSUM(MP_TAC o
3918 GEN_REWRITE_RULE RAND_CONV [INTERS_0]) THEN
3919 DISCH_THEN(MP_TAC o AP_TERM `bounded:(real^N->bool)->bool`) THEN
3920 ASM_SIMP_TAC[NOT_BOUNDED_UNIV; BOUNDED_CONVEX_HULL; FINITE_IMP_BOUNDED;
3921 FINITE_INSERT; FINITE_EMPTY];
3923 EXISTS_TAC `{h:real^N->bool | h IN f /\ b h = &0}` THEN
3924 ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM] THEN CONJ_TAC THENL
3926 X_GEN_TAC `h:real^N->bool` THEN STRIP_TAC THEN
3927 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
3928 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
3929 MAP_EVERY EXISTS_TAC
3930 [`(a:(real^N->bool)->real^N) h`; `(b:(real^N->bool)->real) h`] THEN
3931 ASM_REWRITE_TAC[]] THEN
3932 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
3933 [MATCH_MP_TAC HULL_MINIMAL THEN CONJ_TAC THENL
3934 [MATCH_MP_TAC SUBSET_TRANS THEN
3935 EXISTS_TAC `convex hull ((vec 0:real^N) INSERT s)` THEN CONJ_TAC THENL
3936 [SIMP_TAC[SUBSET; HULL_INC; IN_INSERT]; ASM_REWRITE_TAC[]] THEN
3937 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> INTERS t SUBSET INTERS s`) THEN
3939 MATCH_MP_TAC CONVEX_CONE_INTERS THEN
3940 X_GEN_TAC `h:real^N->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN
3941 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN
3942 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
3943 REWRITE_TAC[CONVEX_CONE_HALFSPACE_LE]];
3945 REWRITE_TAC[SUBSET; IN_INTERS; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
3947 SUBGOAL_THEN `!h:real^N->bool. h IN f ==> ?t. &0 < t /\ (t % x) IN h`
3949 [X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN
3950 ASM_CASES_TAC `(b:(real^N->bool)->real) h = &0` THENL
3951 [EXISTS_TAC `&1` THEN ASM_SIMP_TAC[REAL_LT_01; VECTOR_MUL_LID];
3953 SUBGOAL_THEN `&0 < (b:(real^N->bool)->real) h` ASSUME_TAC THENL
3954 [ASM_REWRITE_TAC[REAL_LT_LE] THEN
3955 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
3956 DISCH_THEN(MP_TAC o SPEC `vec 0:real^N`) THEN
3957 SIMP_TAC[HULL_INC; IN_INSERT; IN_INTERS] THEN
3958 DISCH_THEN(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
3959 SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}`
3960 (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th])
3961 THENL [ASM_MESON_TAC[]; REWRITE_TAC[IN_ELIM_THM; DOT_RZERO]];
3963 SUBGOAL_THEN `(vec 0:real^N) IN interior h` MP_TAC THENL
3964 [SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` SUBST1_TAC THENL
3966 ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; IN_ELIM_THM; DOT_RZERO]];
3967 REWRITE_TAC[IN_INTERIOR; SUBSET; IN_BALL_0; LEFT_IMP_EXISTS_THM] THEN
3968 X_GEN_TAC `e:real` THEN STRIP_TAC THEN
3969 ASM_CASES_TAC `x:real^N = vec 0` THENL
3970 [EXISTS_TAC `&1` THEN
3971 ASM_SIMP_TAC[VECTOR_MUL_RZERO; REAL_LT_01; NORM_0];
3972 EXISTS_TAC `e / &2 / norm(x:real^N)` THEN
3973 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT] THEN
3974 FIRST_X_ASSUM MATCH_MP_TAC THEN
3975 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_NORM] THEN
3976 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC]];
3978 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
3979 X_GEN_TAC `t:(real^N->bool)->real` THEN DISCH_TAC THEN
3980 SUBGOAL_THEN `x:real^N = inv(inf(IMAGE t (f:(real^N->bool)->bool))) %
3983 [GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_MUL_LID] THEN
3984 REWRITE_TAC[VECTOR_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN
3985 CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MUL_LINV THEN
3986 MATCH_MP_TAC REAL_LT_IMP_NZ THEN
3987 ASM_SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
3988 ASM_SIMP_TAC[FORALL_IN_IMAGE];
3990 MATCH_MP_TAC(REWRITE_RULE[conic] CONIC_CONVEX_CONE_HULL) THEN
3991 ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LE_INF_FINITE; FINITE_IMAGE;
3992 IMAGE_EQ_EMPTY; REAL_LT_IMP_LE; FORALL_IN_IMAGE] THEN
3993 MATCH_MP_TAC(SET_RULE `!s t. s SUBSET t /\ x IN s ==> x IN t`) THEN
3994 EXISTS_TAC `convex hull ((vec 0:real^N) INSERT s)` THEN CONJ_TAC THENL
3995 [MATCH_MP_TAC HULL_MINIMAL THEN
3996 REWRITE_TAC[CONVEX_CONVEX_CONE_HULL] THEN
3997 ASM_SIMP_TAC[INSERT_SUBSET; HULL_SUBSET; CONVEX_CONE_HULL_CONTAINS_0];
3998 ASM_REWRITE_TAC[IN_INTERS] THEN X_GEN_TAC `h:real^N->bool` THEN
4000 SUBGOAL_THEN `inf(IMAGE (t:(real^N->bool)->real) f) % x:real^N =
4001 (&1 - inf(IMAGE t f) / t h) % vec 0 +
4002 (inf(IMAGE t f) / t h) % t h % x`
4004 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_MUL_RZERO; VECTOR_ADD_LID;
4005 REAL_DIV_RMUL; REAL_LT_IMP_NZ];
4007 MATCH_MP_TAC IN_CONVEX_SET THEN
4008 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN
4009 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID] THEN
4010 ASM_SIMP_TAC[REAL_INF_LE_FINITE; REAL_LE_INF_FINITE;
4011 FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
4012 ASM_REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
4013 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN REPEAT CONJ_TAC THENL
4014 [SUBGOAL_THEN `h = {x:real^N | a h dot x <= b h}` SUBST1_TAC THENL
4015 [ASM_MESON_TAC[]; ASM_SIMP_TAC[CONVEX_HALFSPACE_LE]];
4016 SUBGOAL_THEN `(vec 0:real^N) IN convex hull (vec 0 INSERT s)` MP_TAC
4017 THENL [SIMP_TAC[HULL_INC; IN_INSERT]; ALL_TAC] THEN
4018 ASM_REWRITE_TAC[IN_INTERS] THEN ASM_MESON_TAC[];
4019 ASM SET_TAC[REAL_LE_REFL]]]);;
4021 let CLOSED_CONVEX_CONE_HULL = prove
4022 (`!s:real^N->bool. FINITE s ==> closed(convex_cone hull s)`,
4023 MESON_TAC[POLYHEDRON_IMP_CLOSED; POLYHEDRON_CONVEX_CONE_HULL]);;
4025 (* ------------------------------------------------------------------------- *)
4026 (* And conversely, a polyhedral cone is finitely generated. *)
4027 (* ------------------------------------------------------------------------- *)
4029 let FINITELY_GENERATED_CONIC_POLYHEDRON = prove
4031 polyhedron s /\ conic s /\ ~(s = {})
4032 ==> ?c. FINITE c /\ s = convex_cone hull c`,
4033 REPEAT STRIP_TAC THEN
4034 SUBGOAL_THEN `?p:real^N->bool. polytope p /\ vec 0 IN interior p`
4035 STRIP_ASSUME_TAC THENL
4036 [EXISTS_TAC `interval[--vec 1:real^N,vec 1:real^N]` THEN
4037 REWRITE_TAC[POLYTOPE_INTERVAL; INTERIOR_CLOSED_INTERVAL] THEN
4038 SIMP_TAC[IN_INTERVAL; VECTOR_NEG_COMPONENT; VEC_COMPONENT] THEN
4039 CONV_TAC REAL_RAT_REDUCE_CONV;
4041 SUBGOAL_THEN `polytope(s INTER p:real^N->bool)` MP_TAC THENL
4042 [REWRITE_TAC[POLYTOPE_EQ_BOUNDED_POLYHEDRON] THEN
4043 ASM_SIMP_TAC[BOUNDED_INTER; POLYTOPE_IMP_BOUNDED]THEN
4044 ASM_SIMP_TAC[POLYHEDRON_INTER; POLYTOPE_IMP_POLYHEDRON];
4045 REWRITE_TAC[polytope] THEN MATCH_MP_TAC MONO_EXISTS] THEN
4046 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4047 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4049 ASM_SIMP_TAC[SUBSET_HULL; POLYHEDRON_IMP_CONVEX; convex_cone] THEN
4050 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `s INTER p:real^N->bool` THEN
4051 REWRITE_TAC[INTER_SUBSET] THEN ASM_REWRITE_TAC[HULL_SUBSET]] THEN
4052 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4053 SUBGOAL_THEN `?t. &0 < t /\ (t % x:real^N) IN p` STRIP_ASSUME_TAC THENL
4054 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR]) THEN
4055 REWRITE_TAC[SUBSET; IN_BALL_0; LEFT_IMP_EXISTS_THM] THEN
4056 X_GEN_TAC `e:real` THEN STRIP_TAC THEN
4057 ASM_CASES_TAC `x:real^N = vec 0` THENL
4058 [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO; REAL_LT_01] THEN
4059 ASM_SIMP_TAC[NORM_0];
4060 EXISTS_TAC `e / &2 / norm(x:real^N)` THEN
4061 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; NORM_POS_LT] THEN
4062 FIRST_X_ASSUM MATCH_MP_TAC THEN
4063 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NUM] THEN
4064 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_REAL_ARITH_TAC];
4066 SUBGOAL_THEN `x:real^N = inv t % t % x` SUBST1_TAC THENL
4067 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID;
4070 MATCH_MP_TAC(REWRITE_RULE[conic] CONIC_CONVEX_CONE_HULL) THEN
4071 ASM_SIMP_TAC[REAL_LE_INV_EQ; REAL_LT_IMP_LE] THEN
4072 MATCH_MP_TAC(SET_RULE `!s. x IN s /\ s SUBSET t ==> x IN t`) THEN
4073 EXISTS_TAC `convex hull c:real^N->bool` THEN
4074 REWRITE_TAC[CONVEX_HULL_SUBSET_CONVEX_CONE_HULL] THEN
4075 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[IN_INTER] THEN
4076 FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [conic]) THEN
4077 ASM_SIMP_TAC[REAL_LT_IMP_LE]);;
4079 (* ------------------------------------------------------------------------- *)
4080 (* Decomposition of polyhedron into cone plus polytope and more corollaries. *)
4081 (* ------------------------------------------------------------------------- *)
4083 let POLYHEDRON_POLYTOPE_SUMS = prove
4084 (`!s t:real^N->bool.
4085 polyhedron s /\ polytope t ==> polyhedron {x + y | x IN s /\ y IN t}`,
4086 REPEAT STRIP_TAC THEN
4087 REWRITE_TAC[POLYHEDRON_EQ_FINITE_EXPOSED_FACES] THEN REPEAT CONJ_TAC THENL
4088 [MATCH_MP_TAC CLOSED_COMPACT_SUMS THEN
4089 ASM_SIMP_TAC[POLYHEDRON_IMP_CLOSED; POLYTOPE_IMP_COMPACT];
4090 MATCH_MP_TAC CONVEX_SUMS THEN
4091 ASM_SIMP_TAC[POLYHEDRON_IMP_CONVEX; POLYTOPE_IMP_CONVEX];
4092 MATCH_MP_TAC FINITE_SUBSET THEN
4093 EXISTS_TAC `{ {x + y:real^N | x IN k /\ y IN l} |
4094 k exposed_face_of s /\ l exposed_face_of t}` THEN
4096 [ONCE_REWRITE_TAC[SET_RULE `k exposed_face_of s <=>
4097 k IN {f | f exposed_face_of s}`] THEN
4098 MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN
4099 ASM_SIMP_TAC[FINITE_POLYHEDRON_EXPOSED_FACES;
4100 POLYTOPE_IMP_POLYHEDRON];
4101 REWRITE_TAC[SUBSET; IN_ELIM_THM; GSYM CONJ_ASSOC] THEN
4102 REPEAT STRIP_TAC THEN MATCH_MP_TAC EXPOSED_FACE_OF_SUMS THEN
4103 ASM_SIMP_TAC[POLYHEDRON_IMP_CONVEX; POLYTOPE_IMP_CONVEX]]]);;
4105 let POLYHEDRON_AS_CONE_PLUS_CONV = prove
4107 polyhedron s <=> ?t u. FINITE t /\ FINITE u /\
4108 s = {x + y | x IN convex_cone hull t /\
4109 y IN convex hull u}`,
4110 REPEAT GEN_TAC THEN EQ_TAC THENL
4111 [REWRITE_TAC[polyhedron; LEFT_IMP_EXISTS_THM];
4112 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4113 MATCH_MP_TAC POLYHEDRON_POLYTOPE_SUMS THEN
4114 ASM_SIMP_TAC[POLYTOPE_CONVEX_HULL; POLYHEDRON_CONVEX_CONE_HULL]] THEN
4115 REWRITE_TAC[polyhedron; LEFT_IMP_EXISTS_THM] THEN
4116 X_GEN_TAC `f:(real^N->bool)->bool` THEN
4117 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4118 DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) MP_TAC) THEN
4119 GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4120 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
4121 [`a:(real^N->bool)->real^N`; `b:(real^N->bool)->real`] THEN
4122 ONCE_REWRITE_TAC[MESON[] `h = {x | P x} <=> {x | P x} = h`] THEN
4125 `s':real^(N,1)finite_sum->bool =
4126 {x | &0 <= drop(sndcart x) /\
4128 h IN f ==> a h dot (fstcart x) <= b h * drop(sndcart x)}` THEN
4130 `?t u. FINITE t /\ FINITE u /\
4131 (!y:real^(N,1)finite_sum. y IN t ==> drop(sndcart y) = &0) /\
4132 (!y. y IN u ==> drop(sndcart y) = &1) /\
4133 s' = convex_cone hull (t UNION u)`
4134 STRIP_ASSUME_TAC THENL
4135 [MP_TAC(ISPEC `s':real^(N,1)finite_sum->bool`
4136 FINITELY_GENERATED_CONIC_POLYHEDRON) THEN
4138 [EXPAND_TAC "s'" THEN REPEAT CONJ_TAC THENL
4139 [REWRITE_TAC[polyhedron] THEN
4141 `{ x:real^(N,1)finite_sum |
4142 pastecart (vec 0) (--vec 1) dot x <= &0} INSERT
4143 { {x | pastecart (a h) (--lift(b h)) dot x <= &0} |
4144 (h:real^N->bool) IN f}` THEN
4145 REWRITE_TAC[FINITE_INSERT; INTERS_INSERT; SIMPLE_IMAGE] THEN
4146 ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_INSERT; FORALL_IN_IMAGE] THEN
4147 REPEAT CONJ_TAC THENL
4148 [EXPAND_TAC "s'" THEN
4149 REWRITE_TAC[EXTENSION; IN_ELIM_THM; FORALL_PASTECART; IN_INTER;
4150 DOT_PASTECART; INTERS_IMAGE; FSTCART_PASTECART;
4151 SNDCART_PASTECART; DOT_1; GSYM drop; DROP_NEG; LIFT_DROP] THEN
4152 REWRITE_TAC[DROP_VEC; DOT_LZERO; REAL_MUL_LNEG; GSYM real_sub] THEN
4153 REWRITE_TAC[REAL_MUL_LID; REAL_ARITH `x - y <= &0 <=> x <= y`];
4154 EXISTS_TAC `pastecart (vec 0) (--vec 1):real^(N,1)finite_sum` THEN
4155 EXISTS_TAC `&0` THEN
4156 REWRITE_TAC[PASTECART_EQ_VEC; VECTOR_NEG_EQ_0; VEC_EQ] THEN
4158 X_GEN_TAC `h:real^N->bool` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC
4159 [`pastecart (a(h:real^N->bool)) (--lift(b h)):real^(N,1)finite_sum`;
4161 ASM_SIMP_TAC[PASTECART_EQ_VEC]];
4162 REWRITE_TAC[conic; IN_ELIM_THM; FSTCART_CMUL; SNDCART_CMUL] THEN
4163 SIMP_TAC[DROP_CMUL; DOT_RMUL; REAL_LE_MUL] THEN
4164 MESON_TAC[REAL_LE_LMUL; REAL_MUL_AC];
4165 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
4166 EXISTS_TAC `vec 0:real^(N,1)finite_sum` THEN
4167 REWRITE_TAC[IN_ELIM_THM; FSTCART_VEC; SNDCART_VEC] THEN
4168 REWRITE_TAC[DROP_VEC; DOT_RZERO; REAL_LE_REFL; REAL_MUL_RZERO]];
4169 DISCH_THEN(X_CHOOSE_THEN `c:real^(N,1)finite_sum->bool`
4170 STRIP_ASSUME_TAC) THEN
4171 MAP_EVERY EXISTS_TAC
4172 [`{x:real^(N,1)finite_sum | x IN c /\ drop(sndcart x) = &0}`;
4173 `IMAGE (\x. inv(drop(sndcart x)) % x)
4174 {x:real^(N,1)finite_sum | x IN c /\ ~(drop(sndcart x) = &0)}`] THEN
4175 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT; FORALL_IN_IMAGE] THEN
4176 SIMP_TAC[IN_ELIM_THM; SNDCART_CMUL; DROP_CMUL; REAL_MUL_LINV] THEN
4178 `!x:real^(N,1)finite_sum. x IN c ==> &0 <= drop(sndcart x)`
4180 [GEN_TAC THEN DISCH_TAC THEN
4181 SUBGOAL_THEN `(x:real^(N,1)finite_sum) IN s'` MP_TAC THENL
4182 [ASM_MESON_TAC[HULL_INC]; EXPAND_TAC "s'"] THEN
4183 SIMP_TAC[IN_ELIM_THM];
4185 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN
4186 MATCH_MP_TAC HULL_MINIMAL THEN
4187 REWRITE_TAC[CONVEX_CONE_CONVEX_CONE_HULL; UNION_SUBSET] THEN
4188 SIMP_TAC[SUBSET; IN_ELIM_THM; HULL_INC; FORALL_IN_IMAGE] THEN
4189 X_GEN_TAC `x:real^(N,1)finite_sum` THEN DISCH_TAC THEN
4190 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^(N,1)finite_sum`) THEN
4191 ASM_SIMP_TAC[CONVEX_CONE_HULL_MUL; HULL_INC; REAL_LE_INV_EQ] THEN
4192 ASM_REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN
4194 [MATCH_MP_TAC HULL_INC THEN ASM_REWRITE_TAC[IN_UNION; IN_ELIM_THM];
4196 `x:real^(N,1)finite_sum =
4197 drop(sndcart x) % inv(drop(sndcart x)) % x`
4199 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
4200 REWRITE_TAC[VECTOR_MUL_LID];
4201 MATCH_MP_TAC CONVEX_CONE_HULL_MUL THEN
4202 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC HULL_INC THEN
4203 REWRITE_TAC[IN_UNION] THEN DISJ2_TAC THEN
4204 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `x:real^(N,1)finite_sum` THEN
4205 ASM_SIMP_TAC[IN_ELIM_THM; REAL_LT_IMP_NZ]]]];
4206 EXISTS_TAC `IMAGE fstcart (t:real^(N,1)finite_sum->bool)` THEN
4207 EXISTS_TAC `IMAGE fstcart (u:real^(N,1)finite_sum->bool)` THEN
4208 ASM_SIMP_TAC[FINITE_IMAGE] THEN
4209 SUBGOAL_THEN `s = {x:real^N | pastecart x (vec 1:real^1) IN s'}`
4211 [MAP_EVERY EXPAND_TAC ["s"; "s'"] THEN
4212 REWRITE_TAC[IN_ELIM_THM; SNDCART_PASTECART; DROP_VEC; REAL_POS] THEN
4213 GEN_REWRITE_TAC I [EXTENSION] THEN
4214 REWRITE_TAC[FSTCART_PASTECART; IN_ELIM_THM; IN_INTERS; REAL_MUL_RID] THEN
4216 ASM_REWRITE_TAC[CONVEX_CONE_HULL_UNION]] THEN
4217 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN X_GEN_TAC `z:real^N` THEN
4218 SIMP_TAC[CONVEX_CONE_HULL_LINEAR_IMAGE; CONVEX_HULL_LINEAR_IMAGE;
4219 LINEAR_FSTCART] THEN
4220 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM] THEN
4221 REWRITE_TAC[EXISTS_IN_IMAGE] THEN
4222 AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
4223 X_GEN_TAC `a:real^(N,1)finite_sum` THEN REWRITE_TAC[] THEN
4224 MATCH_MP_TAC(TAUT `(p ==> (q <=> r)) ==> (p /\ q <=> p /\ r)`) THEN
4225 DISCH_TAC THEN AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
4226 X_GEN_TAC `b:real^(N,1)finite_sum` THEN REWRITE_TAC[PASTECART_EQ] THEN
4227 REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; FSTCART_ADD;
4229 ASM_CASES_TAC `fstcart(a:real^(N,1)finite_sum) +
4230 fstcart(b:real^(N,1)finite_sum) = z` THEN
4231 ASM_REWRITE_TAC[] THEN
4232 SUBGOAL_THEN `sndcart(a:real^(N,1)finite_sum) = vec 0` SUBST1_TAC THENL
4233 [UNDISCH_TAC `(a:real^(N,1)finite_sum) IN convex_cone hull t` THEN
4234 SPEC_TAC(`a:real^(N,1)finite_sum`,`a:real^(N,1)finite_sum`) THEN
4235 MATCH_MP_TAC HULL_INDUCT THEN ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC] THEN
4236 REWRITE_TAC[convex_cone; convex; conic; IN_ELIM_THM] THEN
4237 SIMP_TAC[SNDCART_ADD; SNDCART_CMUL; DROP_ADD; DROP_CMUL] THEN
4238 REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_RID; GSYM MEMBER_NOT_EMPTY] THEN
4239 EXISTS_TAC `vec 0:real^(N,1)finite_sum` THEN
4240 REWRITE_TAC[IN_ELIM_THM; SNDCART_VEC; DROP_VEC];
4241 REWRITE_TAC[VECTOR_ADD_LID]] THEN
4242 ASM_CASES_TAC `u:real^(N,1)finite_sum->bool = {}` THENL
4243 [ASM_REWRITE_TAC[CONVEX_CONE_HULL_EMPTY; CONVEX_HULL_EMPTY] THEN
4244 REWRITE_TAC[IN_SING; NOT_IN_EMPTY] THEN
4245 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4246 ASM_REWRITE_TAC[SNDCART_VEC; VEC_EQ] THEN ARITH_TAC;
4248 ASM_SIMP_TAC[CONVEX_CONE_HULL_CONVEX_HULL_NONEMPTY; IN_ELIM_THM] THEN
4250 `!y:real^(N,1)finite_sum. y IN convex hull u ==> sndcart y = vec 1`
4253 [MATCH_MP_TAC HULL_INDUCT THEN ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC] THEN
4254 REWRITE_TAC[convex; IN_ELIM_THM] THEN
4255 SIMP_TAC[SNDCART_ADD; SNDCART_CMUL; DROP_ADD; DROP_CMUL] THEN
4256 SIMP_TAC[REAL_MUL_RID];
4258 EQ_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THENL
4259 [MAP_EVERY X_GEN_TAC [`c:real`; `d:real^(N,1)finite_sum`] THEN
4260 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
4261 ASM_SIMP_TAC[SNDCART_CMUL; VECTOR_MUL_EQ_0; VECTOR_ARITH
4262 `x:real^N = c % x <=> (c - &1) % x = vec 0`] THEN
4263 ASM_SIMP_TAC[REAL_SUB_0; VEC_EQ; ARITH_EQ; VECTOR_MUL_LID];
4264 DISCH_TAC THEN ASM_SIMP_TAC[] THEN EXISTS_TAC `&1` THEN
4265 ASM_REWRITE_TAC[REAL_POS; VECTOR_MUL_LID] THEN ASM_MESON_TAC[]]]);;
4267 let POLYHEDRON_LINEAR_IMAGE = prove
4268 (`!f:real^M->real^N s.
4269 linear f /\ polyhedron s ==> polyhedron(IMAGE f s)`,
4270 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4271 REWRITE_TAC[POLYHEDRON_AS_CONE_PLUS_CONV; LEFT_IMP_EXISTS_THM] THEN
4272 MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^M->bool`] THEN STRIP_TAC THEN
4273 EXISTS_TAC `IMAGE (f:real^M->real^N) t` THEN
4274 EXISTS_TAC `IMAGE (f:real^M->real^N) u` THEN
4275 ASM_SIMP_TAC[FINITE_IMAGE] THEN
4276 ASM_SIMP_TAC[CONVEX_CONE_HULL_LINEAR_IMAGE; CONVEX_HULL_LINEAR_IMAGE] THEN
4277 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN
4278 FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_ADD) THEN MESON_TAC[]);;
4280 let POLYHEDRON_SUMS = prove
4281 (`!s t:real^N->bool.
4282 polyhedron s /\ polyhedron t ==> polyhedron {x + y | x IN s /\ y IN t}`,
4283 REPEAT GEN_TAC THEN REWRITE_TAC[POLYHEDRON_AS_CONE_PLUS_CONV] THEN
4284 REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
4285 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
4287 [`t1:real^N->bool`; `u1:real^N->bool`;
4288 `t2:real^N->bool`; `u2:real^N->bool`] THEN
4289 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4290 EXISTS_TAC `t1 UNION t2:real^N->bool` THEN
4291 EXISTS_TAC `{u + v:real^N | u IN u1 /\ v IN u2}` THEN
4292 REWRITE_TAC[CONVEX_CONE_HULL_UNION; CONVEX_HULL_SUMS] THEN
4293 ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FINITE_UNION] THEN
4294 REWRITE_TAC[SET_RULE
4295 `{h x y | x IN {f a b | P a /\ Q b} /\
4296 y IN {g a b | R a /\ S b}} =
4297 {h (f a b) (g c d) | P a /\ Q b /\ R c /\ S d}`] THEN
4298 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_AC]);;
4300 (* ------------------------------------------------------------------------- *)
4301 (* Farkas's lemma (2 variants) and stronger separation for polyhedra. *)
4302 (* ------------------------------------------------------------------------- *)
4304 let FARKAS_LEMMA = prove
4308 (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i)) <=>
4311 (!i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= (transp A ** y)$i))`,
4312 REPEAT STRIP_TAC THEN MATCH_MP_TAC(TAUT
4313 `(q ==> ~p) /\ (~p ==> q) ==> (p <=> ~q)`) THEN
4315 [REPEAT STRIP_TAC THEN
4316 SUBGOAL_THEN `y dot ((A:real^N^M) ** x - b) = &0` MP_TAC THENL
4317 [ASM_REWRITE_TAC[VECTOR_SUB_REFL; DOT_RZERO]; ALL_TAC] THEN
4318 RULE_ASSUM_TAC(ONCE_REWRITE_RULE[DOT_SYM]) THEN
4319 REWRITE_TAC[DOT_RSUB; REAL_SUB_0] THEN
4320 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
4321 `y < &0 ==> &0 <= x ==> ~(x = y)`)) THEN
4322 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4323 REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; dot] THEN
4324 MATCH_MP_TAC SUM_POS_LE THEN
4325 ASM_SIMP_TAC[REAL_LE_MUL; IN_NUMSEG; FINITE_NUMSEG];
4326 DISCH_TAC THEN MP_TAC(ISPECL
4327 [`{(A:real^N^M) ** (x:real^N) |
4328 !i. 1 <= i /\ i <= dimindex(:N) ==> &0 <= x$i}`;
4329 `b:real^M`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN
4330 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
4331 [REWRITE_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN
4332 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
4333 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
4334 SIMP_TAC[CONVEX_POSITIVE_ORTHANT; CONVEX_LINEAR_IMAGE;
4335 MATRIX_VECTOR_MUL_LINEAR] THEN
4336 MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN
4337 MATCH_MP_TAC POLYHEDRON_LINEAR_IMAGE THEN
4338 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; POLYHEDRON_POSITIVE_ORTHANT];
4339 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^M` THEN
4340 DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN
4341 ONCE_REWRITE_TAC[DOT_SYM] THEN
4342 FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N`) THEN
4343 REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO; DOT_RZERO] THEN
4344 REWRITE_TAC[real_gt; VEC_COMPONENT; REAL_LE_REFL] THEN
4345 DISCH_TAC THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
4346 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
4347 ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
4348 FIRST_X_ASSUM(MP_TAC o SPEC
4349 `c / (transp(A:real^N^M) ** (y:real^M))$k % basis k:real^N`) THEN
4350 ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
4351 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4352 ASM_SIMP_TAC[DOT_RMUL; DOT_BASIS; VECTOR_MATRIX_MUL_TRANSP] THEN
4353 ASM_SIMP_TAC[REAL_FIELD `y < &0 ==> x / y * y = x`] THEN
4354 REWRITE_TAC[REAL_LT_REFL; real_gt] THEN
4355 GEN_TAC THEN COND_CASES_TAC THEN
4356 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_LE_REFL; REAL_MUL_RID] THEN
4357 ONCE_REWRITE_TAC[REAL_ARITH `x / y:real = --x * -- inv y`] THEN
4358 MATCH_MP_TAC REAL_LE_MUL THEN
4359 REWRITE_TAC[REAL_ARITH `&0 <= --x <=> ~(&0 < x)`; REAL_LT_INV_EQ] THEN
4360 ASM_REAL_ARITH_TAC]]);;
4362 let FARKAS_LEMMA_ALT = prove
4365 (!i. 1 <= i /\ i <= dimindex(:M) ==> (A ** x)$i <= b$i)) <=>
4367 (!i. 1 <= i /\ i <= dimindex(:M) ==> &0 <= y$i) /\
4368 y ** A = vec 0 /\ b dot y < &0)`,
4370 MATCH_MP_TAC(TAUT `~(p /\ q) /\ (~p ==> q) ==> (p <=> ~q)`) THEN
4371 REPEAT STRIP_TAC THENL
4372 [SUBGOAL_THEN `&0 <= (b - (A:real^N^M) ** x) dot y` MP_TAC THENL
4373 [REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_POS_LE THEN
4374 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
4375 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
4376 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_SUB_LE];
4377 REWRITE_TAC[DOT_LSUB; REAL_SUB_LE] THEN REWRITE_TAC[REAL_NOT_LE] THEN
4378 GEN_REWRITE_TAC RAND_CONV [DOT_SYM] THEN
4379 REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4380 ASM_REWRITE_TAC[DOT_LZERO]];
4382 [`{(A:real^N^M) ** (x:real^N) + s |x,s|
4383 !i. 1 <= i /\ i <= dimindex(:M) ==> &0 <= s$i}`;
4384 `b:real^M`] SEPARATING_HYPERPLANE_CLOSED_POINT) THEN
4385 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
4386 [REWRITE_TAC[IN_ELIM_THM; CONJ_ASSOC] THEN CONJ_TAC THENL
4387 [ONCE_REWRITE_TAC[SET_RULE
4388 `{f x + y | x,y | P y} =
4389 {z + y | z,y | z IN IMAGE (f:real^M->real^N) (:real^M) /\
4390 y IN {w | P w}}`] THEN
4391 SIMP_TAC[CONVEX_SUMS; CONVEX_POSITIVE_ORTHANT; CONVEX_LINEAR_IMAGE;
4392 MATRIX_VECTOR_MUL_LINEAR; CONVEX_UNIV] THEN
4393 MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN
4394 MATCH_MP_TAC POLYHEDRON_SUMS THEN
4395 ASM_SIMP_TAC[POLYHEDRON_LINEAR_IMAGE; POLYHEDRON_UNIV;
4396 MATRIX_VECTOR_MUL_LINEAR; POLYHEDRON_POSITIVE_ORTHANT];
4397 POP_ASSUM MP_TAC THEN REWRITE_TAC[CONTRAPOS_THM] THEN
4398 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
4399 ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; REAL_LE_ADDR]];
4400 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^M` THEN
4401 DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN
4402 ONCE_REWRITE_TAC[DOT_SYM] THEN
4403 FIRST_ASSUM(MP_TAC o SPECL [`vec 0:real^N`; `vec 0:real^M`]) THEN
4404 REWRITE_TAC[MATRIX_VECTOR_MUL_RZERO; VECTOR_ADD_RID; DOT_RZERO] THEN
4405 REWRITE_TAC[real_gt; VEC_COMPONENT; REAL_LE_REFL] THEN
4406 DISCH_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN
4407 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN CONJ_TAC THENL
4408 [X_GEN_TAC `k:num` THEN STRIP_TAC THEN
4409 ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
4410 FIRST_X_ASSUM(MP_TAC o SPECL
4411 [`vec 0:real^N`; `--c / --((y:real^M)$k) % basis k:real^M`]) THEN
4412 ASM_SIMP_TAC[MATRIX_VECTOR_MUL_RZERO; VECTOR_ADD_LID;
4413 DOT_RMUL; DOT_BASIS; REAL_FIELD
4414 `y < &0 ==> c / --y * y = --c`] THEN
4415 SIMP_TAC[REAL_NEG_NEG; REAL_LT_REFL; VECTOR_MUL_COMPONENT; real_gt] THEN
4416 ASM_SIMP_TAC[BASIS_COMPONENT] THEN REPEAT STRIP_TAC THEN
4418 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID; REAL_LE_REFL] THEN
4419 MATCH_MP_TAC REAL_LE_DIV THEN ASM_REAL_ARITH_TAC;
4420 FIRST_X_ASSUM(MP_TAC o SPECL
4421 [`c / norm((y:real^M) ** (A:real^N^M)) pow 2 %
4422 (transp A ** y)`; `vec 0:real^M`]) THEN
4423 SIMP_TAC[VEC_COMPONENT; REAL_LE_REFL; VECTOR_ADD_RID] THEN
4424 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
4425 REWRITE_TAC[GSYM VECTOR_MATRIX_MUL_TRANSP; DOT_RMUL] THEN
4426 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
4427 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_POW_2; DOT_EQ_0] THEN
4428 REAL_ARITH_TAC]]]);;
4430 let SEPARATING_HYPERPLANE_POLYHEDRA = prove
4431 (`!s t:real^N->bool.
4432 polyhedron s /\ polyhedron t /\ ~(s = {}) /\ ~(t = {}) /\ DISJOINT s t
4433 ==> ?a b. ~(a = vec 0) /\
4434 (!x. x IN s ==> a dot x < b) /\
4435 (!x. x IN t ==> a dot x > b)`,
4436 REPEAT STRIP_TAC THEN
4437 MP_TAC(ISPEC `{x + y:real^N | x IN s /\ y IN IMAGE (--) t}`
4438 SEPARATING_HYPERPLANE_CLOSED_0) THEN
4440 [ASM_SIMP_TAC[CONVEX_SUMS; CONVEX_NEGATIONS; POLYHEDRON_IMP_CONVEX] THEN
4442 [MATCH_MP_TAC POLYHEDRON_IMP_CLOSED THEN
4443 MATCH_MP_TAC POLYHEDRON_SUMS THEN ASM_SIMP_TAC[POLYHEDRON_NEGATIONS];
4444 REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN
4445 REWRITE_TAC[VECTOR_ARITH `y = --x:real^N <=> --y = x`] THEN
4446 REWRITE_TAC[UNWIND_THM1] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
4447 REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = x + y <=> y = --x`] THEN
4448 REWRITE_TAC[UNWIND_THM2; VECTOR_NEG_NEG] THEN ASM SET_TAC[]];
4449 REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4450 REWRITE_TAC[FORALL_IN_IMAGE; GSYM VECTOR_SUB; LEFT_IMP_EXISTS_THM] THEN
4451 MAP_EVERY X_GEN_TAC [`a:real^N`; `k:real`] THEN
4452 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; DOT_RSUB] THEN STRIP_TAC THEN
4453 EXISTS_TAC `--a:real^N` THEN ASM_REWRITE_TAC[VECTOR_NEG_EQ_0] THEN
4454 MP_TAC(ISPEC `IMAGE (\x:real^N. a dot x) s` INF) THEN
4455 MP_TAC(ISPEC `IMAGE (\x:real^N. a dot x) t` SUP) THEN
4456 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
4457 MAP_EVERY ABBREV_TAC
4458 [`u = inf(IMAGE (\x:real^N. a dot x) s)`;
4459 `v = sup(IMAGE (\x:real^N. a dot x) t)`] THEN
4461 [MP_TAC(GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]
4462 (ASSUME `~(s:real^N->bool = {})`)) THEN
4463 DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN
4464 EXISTS_TAC `a dot (z:real^N) - k` THEN
4465 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4466 FIRST_X_ASSUM(MP_TAC o SPECL [`z:real^N`; `x:real^N`]) THEN
4467 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
4470 [MP_TAC(GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]
4471 (ASSUME `~(t:real^N->bool = {})`)) THEN
4472 DISCH_THEN(X_CHOOSE_TAC `z:real^N`) THEN
4473 EXISTS_TAC `a dot (z:real^N) + k` THEN
4474 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4475 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `z:real^N`]) THEN
4476 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
4478 SUBGOAL_THEN `k <= u - v` ASSUME_TAC THENL
4479 [REWRITE_TAC[REAL_LE_SUB_LADD] THEN EXPAND_TAC "u" THEN
4480 MATCH_MP_TAC REAL_LE_INF THEN
4481 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
4482 GEN_TAC THEN DISCH_TAC THEN
4483 ONCE_REWRITE_TAC[REAL_ARITH `k + v <= u <=> v <= u - k`] THEN
4484 EXPAND_TAC "v" THEN MATCH_MP_TAC REAL_SUP_LE THEN
4485 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
4486 ASM_MESON_TAC[REAL_ARITH `x - y > k ==> y <= x - k`];
4487 EXISTS_TAC `--((u + v) / &2)` THEN REWRITE_TAC[real_gt] THEN
4488 REWRITE_TAC[DOT_LNEG; REAL_LT_NEG2] THEN REPEAT STRIP_TAC THENL
4489 [MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `u:real`;
4490 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `v:real`] THEN
4491 ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC]]);;
4493 (* ------------------------------------------------------------------------- *)
4494 (* Relative and absolute frontier of a polytope. *)
4495 (* ------------------------------------------------------------------------- *)
4497 let RELATIVE_BOUNDARY_OF_CONVEX_HULL = prove
4500 ==> (convex hull s) DIFF relative_interior(convex hull s) =
4501 UNIONS { convex hull (s DELETE a) | a | a IN s}`,
4502 REPEAT STRIP_TAC THEN
4503 FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN
4504 REPEAT_TCL DISJ_CASES_THEN MP_TAC (ARITH_RULE
4505 `CARD(s:real^N->bool) = 0 \/ CARD s = 1 \/ 2 <= CARD s`)
4507 [ASM_SIMP_TAC[CARD_EQ_0; CONVEX_HULL_EMPTY] THEN SET_TAC[];
4508 DISCH_TAC THEN MP_TAC(HAS_SIZE_CONV `(s:real^N->bool) HAS_SIZE 1`) THEN
4509 ASM_SIMP_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM; CONVEX_HULL_SING] THEN
4510 REWRITE_TAC[RELATIVE_INTERIOR_SING; DIFF_EQ_EMPTY] THEN
4511 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[EMPTY_UNIONS] THEN
4512 REWRITE_TAC[FORALL_IN_GSPEC; IN_SING; FORALL_UNWIND_THM2] THEN
4513 REWRITE_TAC[CONVEX_HULL_EQ_EMPTY] THEN SET_TAC[];
4515 ASM_SIMP_TAC[POLYHEDRON_CONVEX_HULL; RELATIVE_BOUNDARY_OF_POLYHEDRON] THEN
4516 ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT] THEN
4519 let RELATIVE_FRONTIER_OF_CONVEX_HULL = prove
4522 ==> relative_frontier(convex hull s) =
4523 UNIONS { convex hull (s DELETE a) | a | a IN s}`,
4524 REPEAT STRIP_TAC THEN
4525 FIRST_ASSUM(ASSUME_TAC o MATCH_MP AFFINE_INDEPENDENT_IMP_FINITE) THEN
4526 ASM_SIMP_TAC[relative_frontier; GSYM RELATIVE_BOUNDARY_OF_CONVEX_HULL] THEN
4527 AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC CLOSURE_CLOSED THEN
4528 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);;
4530 let FRONTIER_OF_CONVEX_HULL = prove
4532 s HAS_SIZE (dimindex(:N) + 1)
4533 ==> frontier(convex hull s) =
4534 UNIONS { convex hull (s DELETE a) | a | a IN s}`,
4535 REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN
4536 ASM_CASES_TAC `affine_dependent(s:real^N->bool)` THENL
4537 [REWRITE_TAC[frontier] THEN MATCH_MP_TAC EQ_TRANS THEN
4538 EXISTS_TAC `(convex hull s:real^N->bool) DIFF {}` THEN CONJ_TAC THENL
4540 ASM_SIMP_TAC[INTERIOR_CONVEX_HULL_EQ_EMPTY; frontier; HAS_SIZE] THEN
4541 MATCH_MP_TAC CLOSURE_CLOSED THEN
4542 ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL;
4543 FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY];
4544 REWRITE_TAC[DIFF_EMPTY] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4546 [GEN_REWRITE_TAC LAND_CONV [CARATHEODORY_AFF_DIM] THEN
4547 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
4548 GEN_REWRITE_TAC I [SUBSET] THEN
4549 REWRITE_TAC[IN_ELIM_THM; UNIONS_IMAGE] THEN
4550 X_GEN_TAC `x:real^N` THEN
4551 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
4552 MP_TAC(ISPEC `s:real^N->bool` AFFINE_INDEPENDENT_IFF_CARD) THEN
4553 ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN
4554 REWRITE_TAC[INT_ARITH `(x + &1) - &1:int = x`] THEN DISCH_TAC THEN
4555 SUBGOAL_THEN `(t:real^N->bool) PSUBSET s` ASSUME_TAC THENL
4556 [ASM_REWRITE_TAC[PSUBSET] THEN
4557 DISCH_THEN(MP_TAC o AP_TERM `CARD:(real^N->bool)->num`) THEN
4558 MATCH_MP_TAC(ARITH_RULE `t:num < s ==> t = s ==> F`) THEN
4559 ASM_REWRITE_TAC[ARITH_RULE `x < n + 1 <=> x <= n`] THEN
4560 REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN MATCH_MP_TAC INT_LE_TRANS THEN
4561 EXISTS_TAC `aff_dim(s:real^N->bool) + &1` THEN
4562 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(INT_ARITH
4563 `s:int <= n /\ ~(s = n) ==> s + &1 <= n`) THEN
4564 ASM_REWRITE_TAC[AFF_DIM_LE_UNIV];
4565 SUBGOAL_THEN `?a:real^N. a IN s /\ ~(a IN t)` MP_TAC THENL
4566 [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
4567 X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4569 `(convex hull t) SUBSET convex hull (s DELETE (a:real^N))`
4571 [MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]; ASM SET_TAC[]]];
4572 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[UNIONS_IMAGE] THEN
4573 REWRITE_TAC[SUBSET; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4574 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
4575 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; GSYM SUBSET] THEN
4576 REPEAT STRIP_TAC THEN MATCH_MP_TAC HULL_MONO THEN SET_TAC[]]];
4577 MATCH_MP_TAC EQ_TRANS THEN
4579 `(convex hull s) DIFF relative_interior(convex hull s):real^N->bool` THEN
4581 [ASM_SIMP_TAC[GSYM RELATIVE_BOUNDARY_OF_CONVEX_HULL; frontier] THEN
4583 [MATCH_MP_TAC CLOSURE_CLOSED THEN
4584 ASM_SIMP_TAC[CLOSURE_CLOSED; COMPACT_IMP_CLOSED; COMPACT_CONVEX_HULL;
4585 FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY];
4586 CONV_TAC SYM_CONV THEN MATCH_MP_TAC RELATIVE_INTERIOR_INTERIOR THEN
4587 REWRITE_TAC[AFFINE_HULL_CONVEX_HULL] THEN
4588 REWRITE_TAC[GSYM AFF_DIM_EQ_FULL] THEN
4589 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
4590 [AFFINE_INDEPENDENT_IFF_CARD]) THEN
4591 ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC];
4592 ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_POLYHEDRON;
4593 POLYHEDRON_CONVEX_HULL; FINITE_INSERT; FINITE_EMPTY] THEN
4594 ASM_SIMP_TAC[FACET_OF_CONVEX_HULL_AFFINE_INDEPENDENT_ALT] THEN
4595 REWRITE_TAC[ARITH_RULE `2 <= n + 1 <=> 1 <= n`; DIMINDEX_GE_1] THEN
4598 (* ------------------------------------------------------------------------- *)
4599 (* Special case of a triangle. *)
4600 (* ------------------------------------------------------------------------- *)
4602 let RELATIVE_BOUNDARY_OF_TRIANGLE = prove
4605 ==> convex hull {a,b,c} DIFF relative_interior(convex hull {a,b,c}) =
4606 segment[a,b] UNION segment[b,c] UNION segment[c,a]`,
4607 REPEAT STRIP_TAC THEN
4608 ONCE_REWRITE_TAC[SET_RULE `s UNION t UNION u = t UNION u UNION s`] THEN
4609 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV
4610 [COLLINEAR_3_EQ_AFFINE_DEPENDENT]) THEN
4611 REWRITE_TAC[DE_MORGAN_THM; SEGMENT_CONVEX_HULL] THEN STRIP_TAC THEN
4612 ASM_SIMP_TAC[RELATIVE_BOUNDARY_OF_CONVEX_HULL] THEN
4613 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
4614 REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; UNIONS_0; UNION_EMPTY] THEN
4615 REPEAT BINOP_TAC THEN REWRITE_TAC[] THEN ASM SET_TAC[]);;
4617 let RELATIVE_FRONTIER_OF_TRIANGLE = prove
4620 ==> relative_frontier(convex hull {a,b,c}) =
4621 segment[a,b] UNION segment[b,c] UNION segment[c,a]`,
4622 REPEAT STRIP_TAC THEN
4623 ASM_SIMP_TAC[GSYM RELATIVE_BOUNDARY_OF_TRIANGLE; relative_frontier] THEN
4624 AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC CLOSURE_CLOSED THEN
4625 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL;
4626 FINITE_INSERT; FINITE_EMPTY]);;
4628 let FRONTIER_OF_TRIANGLE = prove
4630 frontier(convex hull {a,b,c}) =
4631 segment[a,b] UNION segment[b,c] UNION segment[c,a]`,
4632 REPEAT STRIP_TAC THEN REWRITE_TAC[SEGMENT_CONVEX_HULL] THEN
4633 ONCE_REWRITE_TAC[SET_RULE `s UNION t UNION u = t UNION u UNION s`] THEN
4634 MAP_EVERY (fun t -> ASM_CASES_TAC t THENL
4635 [ASM_REWRITE_TAC[INSERT_AC; UNION_ACI] THEN
4636 SIMP_TAC[GSYM SEGMENT_CONVEX_HULL; frontier; CLOSURE_SEGMENT;
4637 INTERIOR_SEGMENT; DIMINDEX_2; LE_REFL; DIFF_EMPTY] THEN
4638 REWRITE_TAC[CONVEX_HULL_SING] THEN
4639 REWRITE_TAC[SET_RULE `s = s UNION {a} <=> a IN s`;
4640 SET_RULE `s = {a} UNION s <=> a IN s`] THEN
4641 REWRITE_TAC[ENDS_IN_SEGMENT];
4643 [`b:real^2 = a`; `c:real^2 = a`; `c:real^2 = b`] THEN
4644 SUBGOAL_THEN `{a:real^2,b,c} HAS_SIZE (dimindex(:2) + 1)` ASSUME_TAC THENL
4645 [SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
4646 ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; DIMINDEX_2] THEN
4647 CONV_TAC NUM_REDUCE_CONV;
4648 ASM_SIMP_TAC[FRONTIER_OF_CONVEX_HULL] THEN
4649 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
4650 REWRITE_TAC[IMAGE_CLAUSES; UNIONS_INSERT; UNIONS_0; UNION_EMPTY] THEN
4651 REPEAT BINOP_TAC THEN REWRITE_TAC[] THEN ASM SET_TAC[]]);;
4653 let INSIDE_OF_TRIANGLE = prove
4655 inside(segment[a,b] UNION segment[b,c] UNION segment[c,a]) =
4656 interior(convex hull {a,b,c})`,
4657 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FRONTIER_OF_TRIANGLE] THEN
4658 MATCH_MP_TAC INSIDE_FRONTIER_EQ_INTERIOR THEN
4659 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN MATCH_MP_TAC BOUNDED_CONVEX_HULL THEN
4660 MATCH_MP_TAC FINITE_IMP_BOUNDED THEN
4661 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY]);;
4663 let INTERIOR_OF_TRIANGLE = prove
4665 interior(convex hull {a,b,c}) =
4666 (convex hull {a,b,c}) DIFF
4667 (segment[a,b] UNION segment[b,c] UNION segment[c,a])`,
4668 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM FRONTIER_OF_TRIANGLE; frontier] THEN
4669 MATCH_MP_TAC(SET_RULE `i SUBSET s /\ c = s ==> i = s DIFF (c DIFF i)`) THEN
4670 REWRITE_TAC[INTERIOR_SUBSET] THEN MATCH_MP_TAC CLOSURE_CONVEX_HULL THEN
4671 SIMP_TAC[FINITE_IMP_COMPACT; FINITE_INSERT; FINITE_EMPTY]);;
4673 (* ------------------------------------------------------------------------- *)
4674 (* A ridge is the intersection of precisely two facets. *)
4675 (* ------------------------------------------------------------------------- *)
4677 let POLYHEDRON_RIDGE_TWO_FACETS = prove
4678 (`!p:real^N->bool r.
4679 polyhedron p /\ r face_of p /\ ~(r = {}) /\ aff_dim r = aff_dim p - &2
4680 ==> ?f1 f2. f1 face_of p /\ aff_dim f1 = aff_dim p - &1 /\
4681 f2 face_of p /\ aff_dim f2 = aff_dim p - &1 /\
4682 ~(f1 = f2) /\ r SUBSET f1 /\ r SUBSET f2 /\ f1 INTER f2 = r /\
4683 !f. f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f
4684 ==> f = f1 \/ f = f2`,
4685 REPEAT STRIP_TAC THEN
4686 MP_TAC(ISPECL [`p:real^N->bool`; `r:real^N->bool`] FACE_OF_POLYHEDRON) THEN
4687 ANTS_TAC THENL [ASM_MESON_TAC[INT_ARITH `~(p:int = p - &2)`]; ALL_TAC] THEN
4688 SUBGOAL_THEN `&2 <= aff_dim(p:real^N->bool)` ASSUME_TAC THENL
4689 [MP_TAC(ISPEC `r:real^N->bool` AFF_DIM_GE) THEN
4690 MP_TAC(ISPEC `r:real^N->bool` AFF_DIM_EQ_MINUS1) THEN
4691 ASM_REWRITE_TAC[] THEN INT_ARITH_TAC;
4694 `{f:real^N->bool | f facet_of p /\ r SUBSET f} =
4695 {f | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}`
4697 [GEN_REWRITE_TAC I [EXTENSION] THEN
4698 ASM_REWRITE_TAC[IN_ELIM_THM; facet_of] THEN
4699 X_GEN_TAC `f:real^N->bool` THEN
4700 ASM_CASES_TAC `f:real^N->bool = {}` THEN
4701 ASM_REWRITE_TAC[AFF_DIM_EMPTY; GSYM CONJ_ASSOC] THEN ASM_INT_ARITH_TAC;
4702 DISCH_THEN(MP_TAC o SYM)] THEN
4704 `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}
4707 [ASM_REWRITE_TAC[INTERS_0] THEN DISCH_THEN(ASSUME_TAC o SYM) THEN
4708 UNDISCH_TAC `aff_dim(r:real^N->bool) = aff_dim(p:real^N->bool) - &2` THEN
4709 ASM_REWRITE_TAC[AFF_DIM_UNIV; DIMINDEX_3] THEN
4710 MP_TAC(ISPEC `p:real^N->bool` AFF_DIM_LE_UNIV) THEN INT_ARITH_TAC;
4712 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
4713 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN
4714 X_GEN_TAC `f1:real^N->bool` THEN STRIP_TAC THEN
4716 `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}
4719 [ASM_REWRITE_TAC[INTERS_1] THEN
4720 ASM_MESON_TAC[INT_ARITH `~(x - &2:int = x - &1)`];
4722 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
4723 `~(s = {a}) ==> a IN s ==> ?b. ~(b = a) /\ b IN s`)) THEN
4724 ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4725 X_GEN_TAC `f2:real^N->bool` THEN STRIP_TAC THEN
4727 `{f:real^N->bool | f face_of p /\ aff_dim f = aff_dim p - &1 /\ r SUBSET f}
4730 [ASM_REWRITE_TAC[INTERS_2] THEN DISCH_TAC THEN
4731 MAP_EVERY EXISTS_TAC [`f1:real^N->bool`; `f2:real^N->bool`] THEN
4732 ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
4734 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
4736 ==> a IN s /\ b IN s ==> ?c. ~(c = a) /\ ~(c = b) /\ c IN s`)) THEN
4737 ASM_REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4738 X_GEN_TAC `f3:real^N->bool` THEN STRIP_TAC THEN DISCH_TAC THEN
4739 UNDISCH_TAC `aff_dim(r:real^N->bool) = aff_dim(p:real^N->bool) - &2` THEN
4740 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
4741 MATCH_MP_TAC(INT_ARITH `~(p - &2:int <= x:int) ==> ~(x = p - &2)`) THEN
4742 DISCH_TAC THEN SUBGOAL_THEN
4743 `~(f1:real^N->bool = {}) /\
4744 ~(f2:real^N->bool = {}) /\
4745 ~(f3:real^N->bool = {})`
4746 STRIP_ASSUME_TAC THENL
4747 [REPEAT CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN
4748 RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_EMPTY]) THEN ASM_INT_ARITH_TAC;
4750 MP_TAC(ISPEC `p:real^N->bool` POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL) THEN
4751 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
4752 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
4753 ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
4754 [`f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
4755 `b:(real^N->bool)->real`] THEN
4756 ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
4757 REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = v <=> v = vec 0`] THEN
4758 STRIP_TAC THEN MP_TAC(ISPECL
4759 [`p:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
4760 `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN
4761 ASM_SIMP_TAC[] THEN DISCH_THEN(fun th ->
4762 MP_TAC(SPEC `f1:real^N->bool` th) THEN
4763 MP_TAC(SPEC `f2:real^N->bool` th) THEN
4764 MP_TAC(SPEC `f3:real^N->bool` th)) THEN
4765 ASM_REWRITE_TAC[facet_of] THEN
4766 DISCH_THEN(X_CHOOSE_THEN `h3:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
4767 DISCH_THEN(X_CHOOSE_THEN `h2:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
4768 DISCH_THEN(X_CHOOSE_THEN `h1:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
4769 SUBGOAL_THEN `~((a:(real^N->bool)->real^N) h1 = a h2) /\
4770 ~(a h2 = a h3) /\ ~(a h1 = a h3)`
4771 STRIP_ASSUME_TAC THENL
4772 [REPEAT CONJ_TAC THENL
4773 [DISJ_CASES_TAC(REAL_ARITH
4774 `b(h1:real^N->bool) <= b h2 \/ b h2 <= b h1`)
4776 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`);
4777 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN
4778 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4779 MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN
4781 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
4784 [SUBGOAL_THEN `f DELETE h2 = h1 INSERT (f DIFF {h1,h2}) /\
4785 f = (h2:real^N->bool) INSERT h1 INSERT (f DIFF {h1,h2})`
4786 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
4787 SUBGOAL_THEN `f DELETE h1 = h2 INSERT (f DIFF {h1,h2}) /\
4788 f = (h1:real^N->bool) INSERT h2 INSERT (f DIFF {h1,h2})`
4789 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
4790 REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE
4791 `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN
4792 FIRST_X_ASSUM(fun th ->
4793 MP_TAC(SPEC `h1:real^N->bool` th) THEN
4794 MP_TAC(SPEC `h2:real^N->bool` th)) THEN
4795 ASM_REWRITE_TAC[IMP_IMP] THEN
4796 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
4797 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC;
4798 DISJ_CASES_TAC(REAL_ARITH
4799 `b(h2:real^N->bool) <= b h3 \/ b h3 <= b h2`)
4801 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`);
4802 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`)] THEN
4803 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4804 MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN
4806 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
4809 [SUBGOAL_THEN `f DELETE h3 = h2 INSERT (f DIFF {h2,h3}) /\
4810 f = (h3:real^N->bool) INSERT h2 INSERT (f DIFF {h2,h3})`
4811 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
4812 SUBGOAL_THEN `f DELETE h2 = h3 INSERT (f DIFF {h2,h3}) /\
4813 f = (h2:real^N->bool) INSERT h3 INSERT (f DIFF {h2,h3})`
4814 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
4815 REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE
4816 `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN
4817 FIRST_X_ASSUM(fun th ->
4818 MP_TAC(SPEC `h2:real^N->bool` th) THEN
4819 MP_TAC(SPEC `h3:real^N->bool` th)) THEN
4820 ASM_REWRITE_TAC[IMP_IMP] THEN
4821 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
4822 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC;
4823 DISJ_CASES_TAC(REAL_ARITH
4824 `b(h1:real^N->bool) <= b h3 \/ b h3 <= b h1`)
4826 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`);
4827 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN
4828 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4829 MATCH_MP_TAC(SET_RULE `(p ==> s = t) ==> s PSUBSET t ==> ~p`) THEN
4831 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
4834 [SUBGOAL_THEN `f DELETE h3 = h1 INSERT (f DIFF {h1,h3}) /\
4835 f = (h3:real^N->bool) INSERT h1 INSERT (f DIFF {h1,h3})`
4836 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
4837 SUBGOAL_THEN `f DELETE h1 = h3 INSERT (f DIFF {h1,h3}) /\
4838 f = (h1:real^N->bool) INSERT h3 INSERT (f DIFF {h1,h3})`
4839 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
4840 REWRITE_TAC[INTERS_INSERT] THEN MATCH_MP_TAC(SET_RULE
4841 `b SUBSET a ==> a INTER b INTER s = b INTER s`) THEN
4842 FIRST_X_ASSUM(fun th ->
4843 MP_TAC(SPEC `h1:real^N->bool` th) THEN
4844 MP_TAC(SPEC `h3:real^N->bool` th)) THEN
4845 ASM_REWRITE_TAC[IMP_IMP] THEN
4846 DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
4847 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC];
4850 `~({x | a h1 dot x <= b h1} INTER {x | a h2 dot x <= b h2}
4851 SUBSET {x | a h3 dot x <= b h3}) /\
4852 ~({x | a h1 dot x <= b h1} INTER {x | a h3 dot x <= b h3}
4853 SUBSET {x | a h2 dot x <= b h2}) /\
4854 ~({x | a h2 dot x <= b h2} INTER {x | a h3 dot x <= b h3}
4855 SUBSET {x:real^N | a(h1:real^N->bool) dot x <= b h1})`
4857 [ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THENL
4858 [FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h3:real^N->bool)`);
4859 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h2:real^N->bool)`);
4860 FIRST_X_ASSUM(MP_TAC o SPEC `f DELETE (h1:real^N->bool)`)] THEN
4861 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4862 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC
4863 (LAND_CONV o LAND_CONV) [SYM th]) THEN
4864 MATCH_MP_TAC(SET_RULE `s = t ==> s PSUBSET t ==> F`) THEN
4868 `f DELETE (h3:real^N->bool) = h1 INSERT h2 INSERT (f DELETE h3) /\
4869 f = h1 INSERT h2 INSERT h3 INSERT (f DELETE h3)`
4870 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
4872 `f DELETE (h2:real^N->bool) = h1 INSERT h3 INSERT (f DELETE h2) /\
4873 f = h2 INSERT h1 INSERT h3 INSERT (f DELETE h2)`
4874 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC];
4876 `f DELETE (h1:real^N->bool) = h2 INSERT h3 INSERT (f DELETE h1) /\
4877 f = h1 INSERT h2 INSERT h3 INSERT (f DELETE h1)`
4878 (fun th -> ONCE_REWRITE_TAC[th]) THENL [ASM SET_TAC[]; ALL_TAC]] THEN
4879 REWRITE_TAC[INTERS_INSERT] THEN REWRITE_TAC[GSYM INTER_ASSOC] THEN
4880 AP_THM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[];
4883 `?w. (a:(real^N->bool)->real^N) h1 dot w < b h1 /\
4884 a h2 dot w < b h2 /\ a h3 dot w < b h3`
4885 (CHOOSE_THEN MP_TAC)
4887 [SUBGOAL_THEN `~(relative_interior p :real^N->bool = {})` MP_TAC THENL
4888 [ASM_SIMP_TAC[RELATIVE_INTERIOR_EQ_EMPTY; POLYHEDRON_IMP_CONVEX] THEN
4892 [`p:real^N->bool`; `f:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
4893 `b:(real^N->bool)->real`] RELATIVE_INTERIOR_POLYHEDRON_EXPLICIT) THEN
4894 ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN
4895 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
4896 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4897 DISCH_THEN(MP_TAC o CONJUNCT2) THEN ASM_SIMP_TAC[];
4900 `!x. x IN r ==> (a h1) dot (x:real^N) = b h1 /\
4901 (a h2) dot x = b h2 /\
4902 (a (h3:real^N->bool)) dot x = b h3`
4903 MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4904 SUBGOAL_THEN `?z:real^N. z IN r` CHOOSE_TAC THENL
4905 [ASM SET_TAC[]; ALL_TAC] THEN
4906 MAP_EVERY UNDISCH_TAC
4907 [`~((a:(real^N->bool)->real^N) h1 = a h2)`;
4908 `~((a:(real^N->bool)->real^N) h1 = a h3)`;
4909 `~((a:(real^N->bool)->real^N) h2 = a h3)`;
4910 `aff_dim(p:real^N->bool) - &2 <= aff_dim(r:real^N->bool)`] THEN
4912 FIRST_X_ASSUM(fun th -> MP_TAC(SPEC t th) THEN ASM_REWRITE_TAC[] THEN
4914 DISCH_THEN(MP_TAC o SPEC `z:real^N` o CONJUNCT2 o CONJUNCT2))
4915 [`h1:real^N->bool`; `h2:real^N->bool`; `h3:real^N->bool`] THEN
4916 SUBGOAL_THEN `(z:real^N) IN (affine hull p)` ASSUME_TAC THENL
4917 [MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[];
4918 ASM_REWRITE_TAC[]] THEN
4919 UNDISCH_TAC `(z:real^N) IN (affine hull p)` THEN
4920 SUBGOAL_THEN `(a h1) dot (z:real^N) = b h1 /\
4921 (a h2) dot z = b h2 /\
4922 (a (h3:real^N->bool)) dot z = b h3`
4923 (REPEAT_TCL CONJUNCTS_THEN (SUBST1_TAC o SYM))
4924 THENL [ASM SET_TAC[]; ALL_TAC] THEN
4925 SUBGOAL_THEN `(r:real^N->bool) SUBSET affine hull p` MP_TAC THENL
4926 [ASM_MESON_TAC[FACE_OF_IMP_SUBSET; HULL_SUBSET; SUBSET_TRANS]; ALL_TAC] THEN
4928 `~((a:(real^N->bool)->real^N) h1 = vec 0) /\
4929 ~((a:(real^N->bool)->real^N) h2 = vec 0) /\
4930 ~((a:(real^N->bool)->real^N) h3 = vec 0)`
4931 MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
4932 UNDISCH_TAC `(z:real^N) IN r` THEN POP_ASSUM_LIST(K ALL_TAC) THEN
4934 [`(a:(real^N->bool)->real^N) h1`,`a1:real^N`;
4935 `(a:(real^N->bool)->real^N) h2`,`a2:real^N`;
4936 `(a:(real^N->bool)->real^N) h3`,`a3:real^N`] THEN
4938 GEN_GEOM_ORIGIN_TAC `z:real^N` ["a1"; "a2"; "a3"] THEN
4939 REWRITE_TAC[VECTOR_ADD_RID; VECTOR_ADD_LID] THEN
4940 REWRITE_TAC[DOT_RADD; IMAGE_CLAUSES;
4941 REAL_ARITH `a + b:real <= a <=> b <= &0`;
4942 REAL_ARITH `a + b:real < a <=> b < &0`;
4943 REAL_ARITH `a + b:real = a <=> b = &0`] THEN
4945 REPEAT STRIP_TAC THEN
4946 SUBGOAL_THEN `aff_dim(p:real^N->bool) = &(dim p)` SUBST_ALL_TAC THENL
4947 [ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]; ALL_TAC] THEN
4948 SUBGOAL_THEN `aff_dim(r:real^N->bool) = &(dim r)` SUBST_ALL_TAC THENL
4949 [ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC]; ALL_TAC] THEN
4950 RULE_ASSUM_TAC(REWRITE_RULE[INT_OF_NUM_ADD; INT_OF_NUM_LE;
4951 INT_ARITH `p - &2:int <= q <=> p <= q + &2`]) THEN
4953 [`{a1:real^N,a2,a3}`; `r:real^N->bool`] DIM_ORTHOGONAL_SUM) THEN
4954 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4955 ASM_SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN
4956 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE
4957 `p <= r + 2 ==> u <= p /\ 3 <= t ==> ~(u = t + r)`)) THEN
4958 SUBGOAL_THEN `affine hull p :real^N->bool = span p` SUBST_ALL_TAC THENL
4959 [ASM_MESON_TAC[AFFINE_HULL_EQ_SPAN]; ALL_TAC] THEN
4961 [GEN_REWRITE_TAC RAND_CONV [GSYM DIM_SPAN] THEN
4962 MATCH_MP_TAC DIM_SUBSET THEN ASM SET_TAC[];
4964 MP_TAC(ISPEC `{a1:real^N,a2,a3}` DEPENDENT_BIGGERSET_GENERAL) THEN
4965 SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY; ARITH] THEN
4966 ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH] THEN
4967 GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
4968 REWRITE_TAC[ARITH_RULE `~(3 > x) <=> 3 <= x`] THEN
4969 DISCH_THEN MATCH_MP_TAC THEN
4970 REWRITE_TAC[dependent; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN
4971 ASM_REWRITE_TAC[DELETE_INSERT; EMPTY_DELETE] THEN
4972 REWRITE_TAC[SPAN_2; IN_ELIM_THM; IN_UNIV] THEN
4973 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN
4974 W(fun (asl,w) -> let fv = frees w
4975 and av = [`a1:real^N`; `a2:real^N`; `a3:real^N`] in
4976 MAP_EVERY (fun t -> SPEC_TAC(t,t)) (subtract fv av @ av)) THEN
4977 REWRITE_TAC[LEFT_FORALL_IMP_THM] THEN
4978 MATCH_MP_TAC(MESON[]
4979 `(!a1 a2 a3. P a1 a2 a3 ==> P a2 a1 a3 /\ P a3 a1 a2) /\
4980 (!a1 a2 a3. Q a1 a2 a3 ==> ~(P a1 a2 a3))
4981 ==> !a3 a2 a1. P a1 a2 a3
4982 ==> ~(Q a1 a2 a3 \/ Q a2 a1 a3 \/ Q a3 a1 a2)`) THEN
4984 [REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
4985 `(p ==> q) /\ (p ==> r) ==> p ==> q /\ r`) THEN
4986 CONJ_TAC THEN REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
4987 REWRITE_TAC[CONJ_ACI] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
4990 REPEAT GEN_TAC THEN DISCH_THEN
4991 (X_CHOOSE_THEN `u:real` (X_CHOOSE_TAC `v:real`)) THEN
4992 REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT GEN_TAC THEN
4993 ASM_CASES_TAC `u = &0` THENL
4994 [ASM_REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO] THEN
4995 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH
4996 `v = &0 \/ &0 < v \/ &0 < --v`)
4998 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO];
4999 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b <= &0 <=> &0 <= a * --b`] THEN
5000 ASM_SIMP_TAC[REAL_LE_MUL_EQ] THEN
5001 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN REAL_ARITH_TAC;
5002 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b < &0 <=> &0 < --a * b`] THEN
5003 ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN REAL_ARITH_TAC];
5005 ASM_CASES_TAC `v = &0` THENL
5006 [ASM_REWRITE_TAC[VECTOR_ADD_RID; VECTOR_MUL_LZERO] THEN
5007 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH
5008 `u = &0 \/ &0 < u \/ &0 < --u`)
5010 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO];
5011 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b <= &0 <=> &0 <= a * --b`] THEN
5012 ASM_SIMP_TAC[REAL_LE_MUL_EQ] THEN
5013 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN REAL_ARITH_TAC;
5014 REWRITE_TAC[DOT_LMUL; REAL_ARITH `a * b < &0 <=> &0 < --a * b`] THEN
5015 ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN REAL_ARITH_TAC];
5019 `&0 < u /\ &0 < v \/ &0 < u /\ &0 < --v \/
5020 &0 < --u /\ &0 < v \/ &0 < --u /\ &0 < --v`
5021 STRIP_ASSUME_TAC THENL
5022 [ASM_REAL_ARITH_TAC;
5024 `~({x | a2 dot x <= &0} INTER {x | a3 dot x <= &0} SUBSET
5025 {x:real^N | a1 dot x <= &0})` THEN
5026 ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
5027 REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5028 REWRITE_TAC[REAL_ARITH `x <= &0 <=> &0 <= --x`] THEN
5029 REWRITE_TAC[REAL_NEG_ADD; GSYM REAL_MUL_RNEG] THEN
5030 ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_ADD; REAL_LT_IMP_LE];
5032 `~({x | a1 dot x <= &0} INTER {x | a3 dot x <= &0} SUBSET
5033 {x:real^N | a2 dot x <= &0})` THEN
5034 ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
5035 GEN_TAC THEN REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5036 MATCH_MP_TAC(REAL_ARITH
5037 `(&0 < u * a2 <=> &0 < a2) /\ (&0 < --v * a3 <=> &0 < a3)
5038 ==> u * a2 + v * a3 <= &0 /\ a3 <= &0 ==> a2 <= &0`) THEN
5039 ASM_SIMP_TAC[REAL_LT_MUL_EQ];
5041 `~({x | a1 dot x <= &0} INTER {x | a2 dot x <= &0} SUBSET
5042 {x:real^N | a3 dot x <= &0})` THEN
5043 ASM_REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN
5044 GEN_TAC THEN REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5045 MATCH_MP_TAC(REAL_ARITH
5046 `(&0 < --u * a2 <=> &0 < a2) /\ (&0 < v * a3 <=> &0 < a3)
5047 ==> u * a2 + v * a3 <= &0 /\ a2 <= &0 ==> a3 <= &0`) THEN
5048 ASM_SIMP_TAC[REAL_LT_MUL_EQ];
5049 UNDISCH_TAC `(a1:real^N) dot w < &0` THEN
5050 ASM_REWRITE_TAC[DOT_LADD; DOT_LMUL] THEN
5051 MATCH_MP_TAC(REAL_ARITH
5052 `&0 < --u * --a /\ &0 < --v * --b ==> ~(u * a + v * b < &0)`) THEN
5053 CONJ_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC]);;
5055 (* ------------------------------------------------------------------------- *)
5056 (* Lower bounds on then number of 0 and n-1 dimensional faces. *)
5057 (* ------------------------------------------------------------------------- *)
5059 let POLYTOPE_VERTEX_LOWER_BOUND = prove
5061 polytope p ==> aff_dim p + &1 <= &(CARD {v | v extreme_point_of p})`,
5062 REPEAT STRIP_TAC THEN
5063 MATCH_MP_TAC INT_LE_TRANS THEN
5064 EXISTS_TAC `aff_dim(convex hull {v:real^N | v extreme_point_of p}) + &1` THEN
5066 [ASM_SIMP_TAC[GSYM KREIN_MILMAN_MINKOWSKI; POLYTOPE_IMP_CONVEX;
5067 POLYTOPE_IMP_COMPACT; INT_LE_REFL];
5068 REWRITE_TAC[AFF_DIM_CONVEX_HULL; GSYM INT_LE_SUB_LADD] THEN
5069 MATCH_MP_TAC AFF_DIM_LE_CARD THEN
5070 MATCH_MP_TAC FINITE_POLYHEDRON_EXTREME_POINTS THEN
5071 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON]]);;
5073 let POLYTOPE_FACET_LOWER_BOUND = prove
5075 polytope p /\ ~(aff_dim p = &0)
5076 ==> aff_dim p + &1 <= &(CARD {f | f facet_of p})`,
5077 GEN_TAC THEN ASM_CASES_TAC `p:real^N->bool = {}` THEN
5078 ASM_SIMP_TAC[AFF_DIM_EMPTY; FACET_OF_EMPTY; EMPTY_GSPEC; CARD_CLAUSES] THEN
5079 CONV_TAC INT_REDUCE_CONV THEN STRIP_TAC THEN
5081 `?n. {f:real^N->bool | f facet_of p} HAS_SIZE n /\ aff_dim p + &1 <= &n`
5082 (fun th -> MESON_TAC[th; HAS_SIZE]) THEN
5083 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
5084 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
5085 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN
5086 GEOM_ORIGIN_TAC `z:real^N` THEN REPEAT GEN_TAC THEN REPEAT STRIP_TAC THEN
5087 EXISTS_TAC `CARD {f:real^N->bool | f facet_of p}` THEN
5088 ASM_SIMP_TAC[FINITE_POLYTOPE_FACETS; HAS_SIZE] THEN
5089 UNDISCH_TAC `~(aff_dim(p:real^N->bool) = &0)` THEN
5090 ASM_SIMP_TAC[AFF_DIM_DIM_0; HULL_INC; INT_OF_NUM_ADD; INT_OF_NUM_LE] THEN
5091 REWRITE_TAC[INT_OF_NUM_EQ] THEN DISCH_TAC THEN
5092 MP_TAC(ISPEC `p:real^N->bool` POLYHEDRON_INTER_AFFINE_PARALLEL_MINIMAL) THEN
5093 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON] THEN
5094 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
5095 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
5096 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
5097 [`H:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
5098 `b:(real^N->bool)->real`] THEN
5099 ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
5100 REWRITE_TAC[VECTOR_ARITH `vec 0:real^N = v <=> v = vec 0`] THEN
5101 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN
5102 STRIP_TAC THEN MP_TAC(ISPECL
5103 [`p:real^N->bool`; `H:(real^N->bool)->bool`; `a:(real^N->bool)->real^N`;
5104 `b:(real^N->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN
5105 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC] THEN DISCH_THEN(K ALL_TAC) THEN
5106 SUBGOAL_THEN `!h:real^N->bool. h IN H ==> &0 <= b h` ASSUME_TAC THENL
5107 [UNDISCH_TAC `(vec 0:real^N) IN p` THEN EXPAND_TAC "p" THEN
5108 REWRITE_TAC[IN_INTER; IN_INTERS] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN
5109 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `h:real^N->bool` THEN
5110 ASM_CASES_TAC `(h:real^N->bool) IN H` THEN ASM_REWRITE_TAC[] THEN
5111 FIRST_X_ASSUM(MP_TAC o SPEC `h:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
5112 DISCH_THEN(fun t -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM t]) THEN
5113 REWRITE_TAC[IN_ELIM_THM; DOT_RZERO];
5115 MATCH_MP_TAC LE_TRANS THEN
5116 EXISTS_TAC `(CARD(H:(real^N->bool)->bool))` THEN CONJ_TAC THENL
5117 [MATCH_MP_TAC(ARITH_RULE `~(h <= a) ==> a + 1 <= h`) THEN DISCH_TAC THEN
5118 ASM_CASES_TAC `H:(real^N->bool)->bool = {}` THENL
5119 [UNDISCH_THEN `H:(real^N->bool)->bool = {}` SUBST_ALL_TAC THEN
5120 RULE_ASSUM_TAC(REWRITE_RULE[INTERS_0; INTER_UNIV]) THEN
5121 UNDISCH_TAC `~(dim(p:real^N->bool) = 0)` THEN
5122 REWRITE_TAC[DIM_EQ_0] THEN EXPAND_TAC "p" THEN
5123 REWRITE_TAC[ASSUME `H:(real^N->bool)->bool = {}`; INTERS_0] THEN
5124 REWRITE_TAC[INTER_UNIV] THEN
5125 ASM_CASES_TAC `?n:real^N. n IN span p /\ ~(n = vec 0)` THENL
5126 [ALL_TAC; ASM SET_TAC[]] THEN
5127 FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN
5128 FIRST_ASSUM(MP_TAC o MATCH_MP POLYTOPE_IMP_BOUNDED) THEN
5129 REWRITE_TAC[BOUNDED_POS] THEN DISCH_THEN(X_CHOOSE_THEN `B:real`
5130 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5131 DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm n % n:real^N`) THEN
5132 ANTS_TAC THENL [ASM_MESON_TAC[SPAN_MUL]; ALL_TAC] THEN
5133 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
5134 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN REAL_ARITH_TAC;
5136 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
5137 DISCH_THEN(X_CHOOSE_TAC `h:real^N->bool`) THEN
5139 `span(IMAGE (a:(real^N->bool)->real^N) (H DELETE h))
5142 [REWRITE_TAC[PSUBSET] THEN CONJ_TAC THENL
5143 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
5144 REWRITE_TAC[SUBSPACE_SPAN; SUBSET; FORALL_IN_IMAGE; IN_DELETE] THEN
5145 ASM_MESON_TAC[SPAN_ADD; SPAN_SUPERSET; VECTOR_ADD_LID];
5146 DISCH_THEN(MP_TAC o AP_TERM `dim:(real^N->bool)->num`) THEN
5147 REWRITE_TAC[DIM_SPAN] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
5148 (ARITH_RULE `h <= p ==> h':num < h ==> ~(h' = p)`)) THEN
5149 MATCH_MP_TAC LET_TRANS THEN
5150 EXISTS_TAC `CARD(IMAGE (a:(real^N->bool)->real^N) (H DELETE h))` THEN
5151 ASM_SIMP_TAC[DIM_LE_CARD; FINITE_DELETE; FINITE_IMAGE] THEN
5152 MATCH_MP_TAC LET_TRANS THEN
5153 EXISTS_TAC `CARD(H DELETE (h:real^N->bool))` THEN
5154 ASM_SIMP_TAC[CARD_IMAGE_LE; FINITE_DELETE] THEN
5155 ASM_SIMP_TAC[CARD_DELETE; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
5156 ASM_SIMP_TAC[CARD_EQ_0] THEN ASM SET_TAC[]];
5157 DISCH_THEN(MP_TAC o MATCH_MP ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN)] THEN
5158 REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `n:real^N` THEN STRIP_TAC THEN
5159 FIRST_ASSUM(MP_TAC o MATCH_MP POLYTOPE_IMP_BOUNDED) THEN
5160 REWRITE_TAC[BOUNDED_POS] THEN
5161 DISCH_THEN(X_CHOOSE_THEN `B:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5162 DISJ_CASES_TAC(REAL_ARITH
5163 `&0 <= (a:(real^N->bool)->real^N) h dot n \/
5164 &0 <= --((a:(real^N->bool)->real^N) h dot n)`)
5166 [DISCH_THEN(MP_TAC o SPEC `--(B + &1) / norm(n) % n:real^N`);
5167 DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm(n) % n:real^N`)] THEN
5168 (ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM;
5169 REAL_DIV_RMUL; NORM_EQ_0; REAL_ABS_NEG;
5170 REAL_ARITH `~(abs(B + &1) <= B)`] THEN
5171 EXPAND_TAC "p" THEN REWRITE_TAC[IN_INTER; IN_INTERS] THEN
5172 ASM_SIMP_TAC[SPAN_MUL] THEN X_GEN_TAC `k:real^N->bool` THEN
5174 SUBGOAL_THEN `k = {x:real^N | a k dot x <= b k}` SUBST1_TAC THENL
5175 [ASM_SIMP_TAC[]; ALL_TAC] THEN
5176 ASM_CASES_TAC `k:real^N->bool = h` THEN
5177 ASM_REWRITE_TAC[IN_ELIM_THM; DOT_RMUL] THENL
5179 MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 <= y ==> x <= y`) THEN
5180 ASM_SIMP_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN
5181 FIRST_X_ASSUM(MP_TAC o SPEC `(a:(real^N->bool)->real^N) k`) THEN
5182 REWRITE_TAC[orthogonal; DOT_SYM] THEN DISCH_THEN MATCH_MP_TAC THEN
5183 MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]]) THENL
5184 [MATCH_MP_TAC(REAL_ARITH `&0 <= --x * y /\ &0 <= z ==> x * y <= z`);
5185 MATCH_MP_TAC(REAL_ARITH `&0 <= x * --y /\ &0 <= z ==> x * y <= z`)] THEN
5186 ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN
5187 REWRITE_TAC[REAL_ARITH `--a / b:real = --(a / b)`; REAL_NEG_NEG] THEN
5188 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; NORM_POS_LT] THEN ASM_REAL_ARITH_TAC;
5189 REWRITE_TAC[SET_RULE `{f | ?h. h IN s /\ f = g h} = IMAGE g s`] THEN
5190 MATCH_MP_TAC(ARITH_RULE `m:num = n ==> n <= m`) THEN
5191 MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN
5192 MATCH_MP_TAC FACETS_OF_POLYHEDRON_EXPLICIT_DISTINCT THEN
5193 ASM_SIMP_TAC[AFFINE_HULL_EQ_SPAN; HULL_INC]]);;
5195 (* ------------------------------------------------------------------------- *)
5196 (* The notion of n-simplex where n is an integer >= -1. *)
5197 (* ------------------------------------------------------------------------- *)
5199 parse_as_infix("simplex",(12,"right"));;
5201 let simplex = new_definition
5202 `n simplex s <=> ?c. ~(affine_dependent c) /\
5203 &(CARD c):int = n + &1 /\
5204 s = convex hull c`;;
5207 (`n simplex s <=> ?c. FINITE c /\
5208 ~(affine_dependent c) /\
5209 &(CARD c):int = n + &1 /\
5211 REWRITE_TAC[simplex] THEN MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);;
5213 let CONVEX_SIMPLEX = prove
5214 (`!n s. n simplex s ==> convex s`,
5215 REWRITE_TAC[simplex] THEN MESON_TAC[CONVEX_CONVEX_HULL]);;
5217 let COMPACT_SIMPLEX = prove
5218 (`!n s. n simplex s ==> compact s`,
5219 REWRITE_TAC[SIMPLEX] THEN
5220 MESON_TAC[FINITE_IMP_COMPACT; COMPACT_CONVEX_HULL]);;
5222 let SIMPLEX_IMP_POLYTOPE = prove
5223 (`!n s. n simplex s ==> polytope s`,
5224 REWRITE_TAC[simplex; polytope] THEN
5225 MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]);;
5227 let SIMPLEX_DIM_GE = prove
5228 (`!n s. n simplex s ==> -- &1 <= n`,
5229 REWRITE_TAC[simplex] THEN INT_ARITH_TAC);;
5231 let SIMPLEX_EMPTY = prove
5232 (`!n. n simplex {} <=> n = -- &1`,
5233 GEN_TAC THEN REWRITE_TAC[SIMPLEX] THEN
5234 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
5235 REWRITE_TAC[CONVEX_HULL_EQ_EMPTY; CONJ_ASSOC] THEN
5236 ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN
5237 REWRITE_TAC[FINITE_EMPTY; CARD_CLAUSES; AFFINE_INDEPENDENT_EMPTY] THEN
5240 let SIMPLEX_MINUS_1 = prove
5241 (`!s. (-- &1) simplex s <=> s = {}`,
5242 GEN_TAC THEN REWRITE_TAC[SIMPLEX; INT_ADD_LINV; INT_OF_NUM_EQ] THEN
5243 ONCE_REWRITE_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN
5244 SIMP_TAC[CARD_EQ_0] THEN REWRITE_TAC[NOT_IMP] THEN
5245 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN
5246 REWRITE_TAC[UNWIND_THM2; FINITE_EMPTY; AFFINE_INDEPENDENT_EMPTY] THEN
5247 REWRITE_TAC[CONVEX_HULL_EMPTY]);;
5249 let AFF_DIM_SIMPLEX = prove
5250 (`!s n. n simplex s ==> aff_dim s = n`,
5251 REWRITE_TAC[simplex; INT_ARITH `x:int = n + &1 <=> n = x - &1`] THEN
5252 REPEAT STRIP_TAC THEN
5253 ASM_SIMP_TAC[AFF_DIM_CONVEX_HULL; AFF_DIM_AFFINE_INDEPENDENT]);;
5255 let SIMPLEX_EXTREME_POINTS = prove
5256 (`!n s:real^N->bool.
5258 ==> FINITE {v | v extreme_point_of s} /\
5259 ~(affine_dependent {v | v extreme_point_of s}) /\
5260 &(CARD {v | v extreme_point_of s}) = n + &1 /\
5261 s = convex hull {v | v extreme_point_of s}`,
5262 REPEAT GEN_TAC THEN REWRITE_TAC[SIMPLEX; LEFT_IMP_EXISTS_THM] THEN
5263 X_GEN_TAC `c:real^N->bool` THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN
5264 SUBGOAL_THEN `{v:real^N | v extreme_point_of s} = c`
5265 (fun th -> ASM_REWRITE_TAC[th]) THEN
5266 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
5267 MATCH_MP_TAC(SET_RULE `s SUBSET t /\ ~(s PSUBSET t) ==> s = t`) THEN
5268 REWRITE_TAC[SUBSET; IN_ELIM_THM; EXTREME_POINT_OF_CONVEX_HULL] THEN
5269 ABBREV_TAC `c' = {v:real^N | v extreme_point_of (convex hull c)}` THEN
5271 SUBGOAL_THEN `convex hull c:real^N->bool = convex hull c'` ASSUME_TAC THENL
5272 [EXPAND_TAC "c'" THEN MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
5273 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN MATCH_MP_TAC COMPACT_CONVEX_HULL THEN
5274 ASM_MESON_TAC[HAS_SIZE; FINITE_IMP_COMPACT];
5275 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_MEMBER]) THEN
5276 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5277 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
5278 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN
5279 REWRITE_TAC[] THEN EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN
5280 SUBGOAL_THEN `(a:real^N) IN convex hull c'` MP_TAC THENL
5281 [ASM_MESON_TAC[HULL_INC]; ALL_TAC] THEN
5282 DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
5283 CONVEX_HULL_SUBSET_AFFINE_HULL)) THEN
5284 SUBGOAL_THEN `c' SUBSET (c DELETE (a:real^N))` MP_TAC THENL
5285 [ASM SET_TAC[]; ASM_MESON_TAC[HULL_MONO; SUBSET]]]);;
5287 let SIMPLEX_FACE_OF_SIMPLEX = prove
5288 (`!n s f:real^N->bool.
5289 n simplex s /\ f face_of s ==> ?m. m <= n /\ m simplex f`,
5290 REPEAT STRIP_TAC THEN
5291 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SIMPLEX]) THEN
5292 REWRITE_TAC[HAS_SIZE; LEFT_IMP_EXISTS_THM] THEN
5293 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
5294 FIRST_X_ASSUM SUBST_ALL_TAC THEN
5295 SUBGOAL_THEN `?c':real^N->bool. c' SUBSET c /\ f = convex hull c'`
5296 STRIP_ASSUME_TAC THENL
5297 [ASM_SIMP_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]; ALL_TAC] THEN
5298 EXISTS_TAC `&(CARD(c':real^N->bool)) - &1:int` THEN ASM_REWRITE_TAC[] THEN
5300 [FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] CARD_SUBSET)) THEN
5301 ASM_REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN INT_ARITH_TAC;
5302 REWRITE_TAC[simplex] THEN EXISTS_TAC `c':real^N->bool` THEN
5303 ASM_REWRITE_TAC[INT_ARITH `a - &1 + &1:int = a`] THEN
5304 ASM_MESON_TAC[AFFINE_DEPENDENT_MONO]]);;
5306 let FACE_OF_SIMPLEX_SUBSET = prove
5307 (`!n s f:real^N->bool.
5308 n simplex s /\ f face_of s
5309 ==> ?c. c SUBSET {x | x extreme_point_of s} /\ f = convex hull c`,
5310 REPEAT STRIP_TAC THEN
5311 FIRST_ASSUM(MP_TAC o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN
5312 ABBREV_TAC `c = {x:real^N | x extreme_point_of s}` THEN
5313 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5314 DISCH_THEN SUBST_ALL_TAC THEN
5315 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
5316 ASM_MESON_TAC[FACE_OF_CONVEX_HULL_SUBSET; FINITE_IMP_COMPACT]);;
5318 let SUBSET_FACE_OF_SIMPLEX = prove
5319 (`!s n c:real^N->bool.
5320 n simplex s /\ c SUBSET {x | x extreme_point_of s}
5321 ==> (convex hull c) face_of s`,
5322 REPEAT STRIP_TAC THEN
5323 FIRST_ASSUM(MP_TAC o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN
5324 REWRITE_TAC[HAS_SIZE] THEN
5325 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN
5326 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC FACE_OF_CONVEX_HULLS THEN
5327 ASM_REWRITE_TAC[] THEN
5328 MATCH_MP_TAC(SET_RULE `!t. u SUBSET t /\ DISJOINT s t ==> DISJOINT s u`) THEN
5329 EXISTS_TAC `affine hull ({v:real^N | v extreme_point_of s} DIFF c)` THEN
5330 REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN
5331 MATCH_MP_TAC DISJOINT_AFFINE_HULL THEN
5332 EXISTS_TAC `{v:real^N | v extreme_point_of s}` THEN
5333 ASM_REWRITE_TAC[] THEN SET_TAC[]);;
5335 let FACES_OF_SIMPLEX = prove
5337 ==> {f | f face_of s} =
5338 {convex hull c | c SUBSET {v | v extreme_point_of s}}`,
5339 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
5340 REWRITE_TAC[IN_ELIM_THM] THEN
5341 ASM_MESON_TAC[FACE_OF_SIMPLEX_SUBSET; SUBSET_FACE_OF_SIMPLEX]);;
5343 let HAS_SIZE_FACES_OF_SIMPLEX = prove
5344 (`!n s:real^N->bool.
5346 ==> {f | f face_of s} HAS_SIZE 2 EXP (num_of_int(n + &1))`,
5347 REPEAT GEN_TAC THEN DISCH_TAC THEN
5348 FIRST_ASSUM(SUBST1_TAC o MATCH_MP FACES_OF_SIMPLEX) THEN
5349 FIRST_X_ASSUM(STRIP_ASSUME_TAC o GSYM o MATCH_MP SIMPLEX_EXTREME_POINTS) THEN
5350 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN
5351 REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL
5352 [REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ];
5353 MATCH_MP_TAC HAS_SIZE_POWERSET THEN
5354 ASM_REWRITE_TAC[HAS_SIZE; NUM_OF_INT_OF_NUM]] THEN
5356 `!a b. a SUBSET {v:real^N | v extreme_point_of s} /\
5357 b SUBSET {v | v extreme_point_of s} /\
5358 convex hull a SUBSET convex hull b
5360 (fun th -> MESON_TAC[th]) THEN
5361 REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN
5363 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [affine_dependent]) THEN
5364 REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
5365 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN REWRITE_TAC[] THEN
5366 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5367 MATCH_MP_TAC(SET_RULE
5368 `!s t u. x IN s /\ s SUBSET t /\ t SUBSET u /\ u SUBSET v ==> x IN v`) THEN
5369 MAP_EVERY EXISTS_TAC
5370 [`convex hull a:real^N->bool`; `convex hull b:real^N->bool`;
5371 `affine hull b:real^N->bool`] THEN
5372 ASM_SIMP_TAC[HULL_INC; CONVEX_HULL_SUBSET_AFFINE_HULL] THEN
5373 MATCH_MP_TAC HULL_MONO THEN ASM SET_TAC[]);;
5375 let FINITE_FACES_OF_SIMPLEX = prove
5376 (`!n s. n simplex s ==> FINITE {f | f face_of s}`,
5378 DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_FACES_OF_SIMPLEX) THEN
5379 SIMP_TAC[HAS_SIZE]);;
5381 let CARD_FACES_OF_SIMPLEX = prove
5382 (`!n s. n simplex s ==> CARD {f | f face_of s} = 2 EXP (num_of_int(n + &1))`,
5384 DISCH_THEN(MP_TAC o MATCH_MP HAS_SIZE_FACES_OF_SIMPLEX) THEN
5385 SIMP_TAC[HAS_SIZE]);;
5387 let CHOOSE_SIMPLEX = prove
5388 (`!n. --(&1) <= n /\ n <= &(dimindex(:N)) ==> ?s:real^N->bool. n simplex s`,
5389 X_GEN_TAC `d:int` THEN
5390 REWRITE_TAC[INT_ARITH `--(&1):int <= n <=> n = --(&1) \/ &0 <= n`] THEN
5391 DISCH_THEN(CONJUNCTS_THEN2 DISJ_CASES_TAC MP_TAC) THENL
5392 [ASM_MESON_TAC[SIMPLEX_EMPTY]; ALL_TAC] THEN
5393 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM INT_OF_NUM_EXISTS]) THEN
5394 DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST1_TAC) THEN
5395 REWRITE_TAC[INT_OF_NUM_LE; GSYM DIM_UNIV] THEN DISCH_TAC THEN
5396 FIRST_ASSUM(MP_TAC o MATCH_MP CHOOSE_SUBSPACE_OF_SUBSPACE) THEN
5397 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
5398 MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
5399 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
5400 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
5401 EXISTS_TAC `convex hull ((vec 0:real^N) INSERT c)` THEN
5402 REWRITE_TAC[simplex] THEN EXISTS_TAC `(vec 0:real^N) INSERT c` THEN
5403 FIRST_ASSUM(ASSUME_TAC o MATCH_MP INDEPENDENT_NONZERO) THEN
5404 FIRST_ASSUM(ASSUME_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN
5405 ASM_SIMP_TAC[CARD_CLAUSES; GSYM INT_OF_NUM_SUC] THEN
5406 ASM_SIMP_TAC[INDEPENDENT_IMP_AFFINE_DEPENDENT_0] THEN
5407 ASM_MESON_TAC[HAS_SIZE]);;
5409 let CHOOSE_POLYTOPE = prove
5410 (`!n. --(&1) <= n /\ n <= &(dimindex(:N))
5411 ==> ?s:real^N->bool. polytope s /\ aff_dim s = n`,
5412 MESON_TAC[CHOOSE_SIMPLEX; SIMPLEX_IMP_POLYTOPE; AFF_DIM_SIMPLEX]);;
5414 (* ------------------------------------------------------------------------- *)
5415 (* Simplicial complexes and triangulations. *)
5416 (* ------------------------------------------------------------------------- *)
5418 let simplicial_complex = new_definition
5419 `simplicial_complex c <=>
5421 (!s. s IN c ==> ?n. n simplex s) /\
5422 (!f s. s IN c /\ f face_of s ==> f IN c) /\
5423 (!s s'. s IN c /\ s' IN c
5424 ==> (s INTER s') face_of s /\ (s INTER s') face_of s')`;;
5426 let triangulation = new_definition
5427 `triangulation(tr:(real^N->bool)->bool) <=>
5429 (!t. t IN tr ==> ?n. n simplex t) /\
5430 (!t t'. t IN tr /\ t' IN tr
5431 ==> (t INTER t') face_of t /\ (t INTER t') face_of t')`;;
5433 let SIMPLICIAL_COMPLEX_IMP_TRIANGULATION = prove
5434 (`!tr. simplicial_complex tr ==> triangulation tr`,
5435 REWRITE_TAC[triangulation; simplicial_complex] THEN MESON_TAC[]);;
5437 let TRIANGULATION_UNION = prove
5439 triangulation(tr1 UNION tr2) <=>
5440 triangulation tr1 /\ triangulation tr2 /\
5441 (!s t. s IN tr1 /\ t IN tr2
5442 ==> s INTER t face_of s /\ s INTER t face_of t)`,
5443 REWRITE_TAC[triangulation; FINITE_UNION; IN_UNION] THEN
5444 MESON_TAC[INTER_COMM]);;
5446 let TRIANGULATION_INTER_SIMPLEX = prove
5447 (`!tr t t':real^N->bool.
5448 triangulation tr /\ t IN tr /\ t' IN tr
5449 ==> t INTER t' = convex hull ({x | x extreme_point_of t} INTER
5450 {x | x extreme_point_of t'})`,
5451 REWRITE_TAC[triangulation] THEN REPEAT STRIP_TAC THEN
5452 FIRST_X_ASSUM(MP_TAC o SPECL [`t:real^N->bool`; `t':real^N->bool`]) THEN
5453 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
5454 FIRST_X_ASSUM(fun th -> MAP_EVERY (MP_TAC o C SPEC th)
5455 [`t:real^N->bool`; `t':real^N->bool`]) THEN
5456 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
5457 X_GEN_TAC `m:int` THEN DISCH_TAC THEN X_GEN_TAC `n:int` THEN DISCH_TAC THEN
5458 MP_TAC(ISPECL [`m:int`; `t':real^N->bool`;
5459 `t INTER t':real^N->bool`] FACE_OF_SIMPLEX_SUBSET) THEN
5460 MP_TAC(ISPECL [`n:int`; `t:real^N->bool`;
5461 `t INTER t':real^N->bool`] FACE_OF_SIMPLEX_SUBSET) THEN
5463 DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
5464 DISCH_THEN(X_CHOOSE_THEN `d':real^N->bool` (STRIP_ASSUME_TAC o GSYM)) THEN
5465 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
5467 MATCH_MP_TAC HULL_MINIMAL THEN
5468 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[CONVEX_INTER; CONVEX_SIMPLEX]] THEN
5469 SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM; extreme_point_of]] THEN
5470 MATCH_MP_TAC SUBSET_TRANS THEN
5471 EXISTS_TAC `convex hull {x:real^N | x extreme_point_of (t INTER t')}` THEN
5473 [MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN
5474 MATCH_MP_TAC KREIN_MILMAN_MINKOWSKI THEN
5475 ASM_MESON_TAC[COMPACT_INTER; CONVEX_INTER; COMPACT_SIMPLEX; CONVEX_SIMPLEX];
5476 MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THENL
5477 [SUBST1_TAC(SYM(ASSUME `convex hull d:real^N->bool = t INTER t'`));
5478 SUBST1_TAC(SYM(ASSUME `convex hull d':real^N->bool = t INTER t'`))] THEN
5479 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN
5480 DISCH_THEN(MP_TAC o MATCH_MP EXTREME_POINT_OF_CONVEX_HULL) THEN
5483 let TRIANGULATION_SIMPLICIAL_COMPLEX = prove
5484 (`!tr. triangulation tr
5485 ==> simplicial_complex {f:real^N->bool | ?t. t IN tr /\ f face_of t}`,
5487 (`{f | ?t. t IN tr /\ P f t} = UNIONS (IMAGE (\t. {f | P f t}) tr)`,
5488 GEN_REWRITE_TAC I [EXTENSION] THEN
5489 REWRITE_TAC[IN_ELIM_THM; IN_UNIONS; IN_IMAGE; LEFT_AND_EXISTS_THM] THEN
5490 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
5491 REWRITE_TAC[GSYM CONJ_ASSOC; UNWIND_THM2; IN_ELIM_THM]) in
5492 REWRITE_TAC[triangulation; simplicial_complex] THEN
5493 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
5494 REWRITE_TAC[IN_ELIM_THM] THEN GEN_TAC THEN
5495 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
5496 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN STRIP_TAC THEN
5497 REPEAT CONJ_TAC THENL
5498 [REWRITE_TAC[lemma] THEN ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE] THEN
5499 ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN
5500 ASM_MESON_TAC[FINITE_FACES_OF_SIMPLEX];
5501 ASM_MESON_TAC[SIMPLEX_FACE_OF_SIMPLEX];
5502 ASM_MESON_TAC[FACE_OF_TRANS];
5503 ASM_MESON_TAC[FACE_OF_INTER_SUBFACE]]);;
5505 (* ------------------------------------------------------------------------- *)
5506 (* Subdividing a cell complex (not necessarily simplicial). *)
5507 (* ------------------------------------------------------------------------- *)
5509 let CELL_COMPLEX_SUBDIVISION_EXISTS = prove
5510 (`!m:(real^N->bool)->bool d e.
5513 (!c. c IN m ==> polytope c) /\
5514 (!c. c IN m ==> aff_dim c <= d) /\
5515 (!c1 c2. c1 IN m /\ c2 IN m
5516 ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)
5517 ==> ?m'. (!c. c IN m' ==> diameter c < e) /\
5518 UNIONS m' = UNIONS m /\
5520 (!c. c IN m' ==> polytope c) /\
5521 (!c. c IN m' ==> aff_dim c <= d) /\
5522 (!c1 c2. c1 IN m' /\ c2 IN m'
5523 ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)`,
5527 ==> ?n. integer n /\ (x < n * a /\ n * a < y \/
5528 y < n * a /\ n * a < x)`,
5529 REPEAT STRIP_TAC THEN
5530 ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; GSYM REAL_LT_RDIV_EQ] THEN
5531 MATCH_MP_TAC INTEGER_EXISTS_BETWEEN_ABS_LT THEN
5532 REWRITE_TAC[real_div; GSYM REAL_SUB_RDISTRIB; REAL_ABS_MUL] THEN
5533 ASM_SIMP_TAC[REAL_ABS_INV; REAL_ARITH `&0 < x ==> abs x = x`] THEN
5534 ASM_SIMP_TAC[GSYM real_div; REAL_LT_RDIV_EQ;
5535 REAL_MUL_LID; REAL_LT_IMP_LE])
5537 (`!m:(real^N->bool)->bool d.
5539 (!c. c IN m ==> polytope c) /\
5540 (!c. c IN m ==> aff_dim c <= d) /\
5541 (!c1 c2. c1 IN m /\ c2 IN m
5542 ==> c1 INTER c2 face_of c1 /\ c1 INTER c2 face_of c2)
5544 ==> ?m'. UNIONS m' = UNIONS m /\
5546 (!c. c IN m' ==> polytope c) /\
5547 (!c. c IN m' ==> aff_dim c <= d) /\
5548 (!c1 c2. c1 IN m' /\ c2 IN m'
5549 ==> c1 INTER c2 face_of c1 /\
5550 c1 INTER c2 face_of c2) /\
5551 (!c x y. c IN m' /\ x IN c /\ y IN c
5552 ==> !a b. (a,b) IN i
5553 ==> a dot x <= b /\ a dot y <= b \/
5554 a dot x >= b /\ a dot y >= b)`,
5555 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5556 REWRITE_TAC[NOT_IN_EMPTY; FORALL_PAIR_THM] THEN CONJ_TAC THENL
5557 [EXISTS_TAC `m:(real^N->bool)->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
5558 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real`; `i:(real^N#real)->bool`] THEN
5559 GEN_REWRITE_TAC I [IMP_CONJ] THEN
5560 DISCH_THEN(X_CHOOSE_THEN `n:(real^N->bool)->bool` MP_TAC) THEN
5561 DISCH_THEN(CONJUNCTS_THEN2 (SUBST1_TAC o SYM) MP_TAC) THEN
5562 POP_ASSUM_LIST(K ALL_TAC) THEN REPEAT STRIP_TAC THEN
5563 EXISTS_TAC `{c INTER {x:real^N | a dot x <= b} | c IN n} UNION
5564 {c INTER {x:real^N | a dot x >= b} | c IN n}` THEN
5565 REPEAT CONJ_TAC THENL
5566 [REWRITE_TAC[UNIONS_UNION; GSYM INTER_UNIONS; GSYM UNION_OVER_INTER] THEN
5567 MATCH_MP_TAC(SET_RULE `(!x. x IN s) ==> t INTER s = t`) THEN
5568 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC;
5569 ASM_SIMP_TAC[FINITE_UNION; SIMPLE_IMAGE; FINITE_IMAGE];
5570 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
5571 ASM_SIMP_TAC[POLYTOPE_INTER_POLYHEDRON; POLYHEDRON_HALFSPACE_LE;
5572 POLYHEDRON_HALFSPACE_GE];
5573 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
5574 ASM_MESON_TAC[INT_LE_TRANS; AFF_DIM_SUBSET; INTER_SUBSET];
5575 REWRITE_TAC[IN_UNION; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
5576 ASM_REWRITE_TAC[] THEN
5577 ONCE_REWRITE_TAC[SET_RULE
5578 `(s INTER t) INTER (s' INTER t') = (s INTER s') INTER (t INTER t')`] THEN
5579 MATCH_MP_TAC FACE_OF_INTER_INTER THEN ASM_SIMP_TAC[] THEN
5580 SIMP_TAC[SET_RULE `s INTER s = s`; FACE_OF_REFL; CONVEX_HALFSPACE_LE;
5581 CONVEX_HALFSPACE_GE] THEN
5582 REWRITE_TAC[INTER; IN_ELIM_THM; HYPERPLANE_FACE_OF_HALFSPACE_LE;
5583 HYPERPLANE_FACE_OF_HALFSPACE_GE;
5584 REAL_ARITH `a <= b /\ a >= b <=> a = b`;
5585 REAL_ARITH `a >= b /\ a <= b <=> a = b`];
5586 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_UNION; FORALL_AND_THM;
5588 TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
5589 REWRITE_TAC[FORALL_IN_GSPEC; IN_INTER; IN_ELIM_THM; PAIR_EQ] THEN
5590 SIMP_TAC[] THEN ASM_MESON_TAC[]]) in
5591 REPEAT STRIP_TAC THEN
5592 SUBGOAL_THEN `bounded(UNIONS m:real^N->bool)` MP_TAC THENL
5593 [ASM_SIMP_TAC[BOUNDED_UNIONS; POLYTOPE_IMP_BOUNDED]; ALL_TAC] THEN
5594 REWRITE_TAC[BOUNDED_POS_LT; LEFT_IMP_EXISTS_THM] THEN
5595 X_GEN_TAC `B:real` THEN REWRITE_TAC[] THEN STRIP_TAC THEN
5596 MP_TAC(ISPECL [`--B / (e / &2 / &(dimindex(:N)))`;
5597 `B / (e / &2 / &(dimindex(:N)))`] FINITE_INTSEG) THEN
5598 ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_HALF;
5599 REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
5600 REWRITE_TAC[REAL_BOUNDS_LE] THEN ABBREV_TAC
5601 `k = {i | integer i /\ abs(i * e / &2 / &(dimindex(:N))) <= B}` THEN
5603 MP_TAC(ISPECL [`m:(real^N->bool)->bool`; `d:int`] lemma2) THEN
5604 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC
5605 `{ (basis i:real^N,j * e / &2 / &(dimindex(:N))) |
5606 i IN 1..dimindex(:N) /\ j IN k}`) THEN
5607 ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FINITE_NUMSEG] THEN
5608 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:(real^N->bool)->bool` THEN
5609 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5610 X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN
5611 MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
5612 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC DIAMETER_LE THEN
5613 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
5614 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
5615 W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
5616 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
5617 MATCH_MP_TAC SUM_BOUND_GEN THEN
5618 REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG_1; NUMSEG_EMPTY] THEN
5619 REWRITE_TAC[NOT_LT; DIMINDEX_GE_1; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN
5620 X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
5621 DISCH_THEN(MP_TAC o MATCH_MP lemma1) THEN
5622 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV;
5623 REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
5624 DISCH_THEN(X_CHOOSE_THEN `j:real` (CONJUNCTS_THEN ASSUME_TAC)) THEN
5625 FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^N->bool`; `x:real^N`; `y:real^N`]) THEN
5626 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o
5627 SPECL [`basis i:real^N`; `j * e / &2 / &(dimindex(:N))`]) THEN
5628 ASM_SIMP_TAC[DOT_BASIS; IN_ELIM_THM; NOT_IMP] THEN
5629 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
5630 MAP_EVERY EXISTS_TAC [`i:num`; `j:real`] THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN
5631 EXPAND_TAC "k" THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
5632 FIRST_X_ASSUM DISJ_CASES_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
5633 (REAL_ARITH `a < x /\ x < b
5634 ==> abs a <= c /\ abs b <= c ==> abs x <= c`)) THEN
5636 W(MP_TAC o PART_MATCH (lhand o rand) COMPONENT_LE_NORM o lhand o snd) THEN
5637 ASM_REWRITE_TAC[] THEN
5638 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
5639 MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN