1 (* ========================================================================= *)
2 (* The five Platonic solids exist and there are no others. *)
3 (* ========================================================================= *)
5 needs "100/polyhedron.ml";;
6 needs "Multivariate/cross.ml";;
10 (* ------------------------------------------------------------------------- *)
11 (* Some standard regular polyhedra (vertex coordinates from Wikipedia). *)
12 (* ------------------------------------------------------------------------- *)
14 let std_tetrahedron = new_definition
17 {vector[&1;&1;&1],vector[-- &1;-- &1;&1],
18 vector[-- &1;&1;-- &1],vector[&1;-- &1;-- &1]}:real^3->bool`;;
20 let std_cube = new_definition
23 {vector[&1;&1;&1],vector[&1;&1;-- &1],
24 vector[&1;-- &1;&1],vector[&1;-- &1;-- &1],
25 vector[-- &1;&1;&1],vector[-- &1;&1;-- &1],
26 vector[-- &1;-- &1;&1],vector[-- &1;-- &1;-- &1]}:real^3->bool`;;
28 let std_octahedron = new_definition
31 {vector[&1;&0;&0],vector[-- &1;&0;&0],
32 vector[&0;&0;&1],vector[&0;&0;-- &1],
33 vector[&0;&1;&0],vector[&0;-- &1;&0]}:real^3->bool`;;
35 let std_dodecahedron = new_definition
37 let p = (&1 + sqrt(&5)) / &2 in
39 {vector[&1;&1;&1],vector[&1;&1;-- &1],
40 vector[&1;-- &1;&1],vector[&1;-- &1;-- &1],
41 vector[-- &1;&1;&1],vector[-- &1;&1;-- &1],
42 vector[-- &1;-- &1;&1],vector[-- &1;-- &1;-- &1],
43 vector[&0;inv p;p],vector[&0;inv p;--p],
44 vector[&0;--inv p;p],vector[&0;--inv p;--p],
45 vector[inv p;p;&0],vector[inv p;--p;&0],
46 vector[--inv p;p;&0],vector[--inv p;--p;&0],
47 vector[p;&0;inv p],vector[--p;&0;inv p],
48 vector[p;&0;--inv p],vector[--p;&0;--inv p]}:real^3->bool`;;
50 let std_icosahedron = new_definition
52 let p = (&1 + sqrt(&5)) / &2 in
54 {vector[&0; &1; p],vector[&0; &1; --p],
55 vector[&0; -- &1; p],vector[&0; -- &1; --p],
56 vector[&1; p; &0],vector[&1; --p; &0],
57 vector[-- &1; p; &0],vector[-- &1; --p; &0],
58 vector[p; &0; &1],vector[--p; &0; &1],
59 vector[p; &0; -- &1],vector[--p; &0; -- &1]}:real^3->bool`;;
61 (* ------------------------------------------------------------------------- *)
62 (* Slightly ad hoc conversions for computation in Q[sqrt(5)]. *)
63 (* Numbers are canonically represented as either a rational constant r or an *)
64 (* expression r1 + r2 * sqrt(5) where r2 is nonzero but r1 may be zero and *)
65 (* must be present. *)
66 (* ------------------------------------------------------------------------- *)
68 let REAL_RAT5_OF_RAT_CONV =
70 (`p = p + &0 * sqrt(&5)`,
72 let conv = REWR_CONV pth in
73 fun tm -> if is_ratconst tm then conv tm else REFL tm;;
75 let REAL_RAT_OF_RAT5_CONV =
77 (`p + &0 * sqrt(&5) = p`,
79 GEN_REWRITE_CONV TRY_CONV [pth];;
81 let REAL_RAT5_ADD_CONV =
83 (`(a1 + b1 * sqrt(&5)) + (a2 + b2 * sqrt(&5)) =
84 (a1 + a2) + (b1 + b2) * sqrt(&5)`,
86 REAL_RAT_ADD_CONV ORELSEC
87 (BINOP_CONV REAL_RAT5_OF_RAT_CONV THENC
88 GEN_REWRITE_CONV I [pth] THENC
89 LAND_CONV REAL_RAT_ADD_CONV THENC
90 RAND_CONV(LAND_CONV REAL_RAT_ADD_CONV) THENC
91 REAL_RAT_OF_RAT5_CONV);;
93 let REAL_RAT5_SUB_CONV =
95 (`(a1 + b1 * sqrt(&5)) - (a2 + b2 * sqrt(&5)) =
96 (a1 - a2) + (b1 - b2) * sqrt(&5)`,
98 REAL_RAT_SUB_CONV ORELSEC
99 (BINOP_CONV REAL_RAT5_OF_RAT_CONV THENC
100 GEN_REWRITE_CONV I [pth] THENC
101 LAND_CONV REAL_RAT_SUB_CONV THENC
102 RAND_CONV(LAND_CONV REAL_RAT_SUB_CONV) THENC
103 REAL_RAT_OF_RAT5_CONV);;
105 let REAL_RAT5_MUL_CONV =
107 (`(a1 + b1 * sqrt(&5)) * (a2 + b2 * sqrt(&5)) =
108 (a1 * a2 + &5 * b1 * b2) + (a1 * b2 + a2 * b1) * sqrt(&5)`,
109 MP_TAC(ISPEC `&5` SQRT_POW_2) THEN CONV_TAC REAL_FIELD) in
110 REAL_RAT_MUL_CONV ORELSEC
111 (BINOP_CONV REAL_RAT5_OF_RAT_CONV THENC
112 GEN_REWRITE_CONV I [pth] THENC
113 LAND_CONV(COMB_CONV (RAND_CONV REAL_RAT_MUL_CONV) THENC
114 RAND_CONV REAL_RAT_MUL_CONV THENC
115 REAL_RAT_ADD_CONV) THENC
117 (BINOP_CONV REAL_RAT_MUL_CONV THENC REAL_RAT_ADD_CONV)) THENC
118 REAL_RAT_OF_RAT5_CONV);;
120 let REAL_RAT5_INV_CONV =
122 (`~(a pow 2 = &5 * b pow 2)
123 ==> inv(a + b * sqrt(&5)) =
124 a / (a pow 2 - &5 * b pow 2) +
125 --b / (a pow 2 - &5 * b pow 2) * sqrt(&5)`,
127 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_SUB_0] THEN
129 `a pow 2 - &5 * b pow 2 = (a + b * sqrt(&5)) * (a - b * sqrt(&5))`
131 [MP_TAC(SPEC `&5` SQRT_POW_2) THEN CONV_TAC REAL_FIELD;
132 REWRITE_TAC[REAL_ENTIRE; DE_MORGAN_THM] THEN CONV_TAC REAL_FIELD]) in
134 try REAL_RAT_INV_CONV tm with Failure _ ->
135 let th1 = PART_MATCH (lhs o rand) pth tm in
136 let th2 = MP th1 (EQT_ELIM(REAL_RAT_REDUCE_CONV(lhand(concl th1)))) in
137 let th3 = CONV_RULE(funpow 2 RAND_CONV (funpow 2 LAND_CONV
138 REAL_RAT_NEG_CONV)) th2 in
139 let th4 = CONV_RULE(RAND_CONV(RAND_CONV(LAND_CONV
140 (RAND_CONV(LAND_CONV REAL_RAT_POW_CONV THENC
141 RAND_CONV(RAND_CONV REAL_RAT_POW_CONV THENC
142 REAL_RAT_MUL_CONV) THENC
143 REAL_RAT_SUB_CONV) THENC
144 REAL_RAT_DIV_CONV)))) th3 in
145 let th5 = CONV_RULE(RAND_CONV(LAND_CONV
146 (RAND_CONV(LAND_CONV REAL_RAT_POW_CONV THENC
147 RAND_CONV(RAND_CONV REAL_RAT_POW_CONV THENC
148 REAL_RAT_MUL_CONV) THENC
149 REAL_RAT_SUB_CONV) THENC
150 REAL_RAT_DIV_CONV))) th4 in
153 let REAL_RAT5_DIV_CONV =
154 GEN_REWRITE_CONV I [real_div] THENC
155 RAND_CONV REAL_RAT5_INV_CONV THENC
158 let REAL_RAT5_LE_CONV =
160 (`!x y. x <= y * sqrt(&5) <=>
161 x <= &0 /\ &0 <= y \/
162 &0 <= x /\ &0 <= y /\ x pow 2 <= &5 * y pow 2 \/
163 x <= &0 /\ y <= &0 /\ &5 * y pow 2 <= x pow 2`,
164 REPEAT GEN_TAC THEN MP_TAC(ISPEC `&5` SQRT_POW_2) THEN
165 REWRITE_TAC[REAL_POS] THEN DISCH_THEN(fun th ->
166 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th]) THEN
167 REWRITE_TAC[GSYM REAL_POW_MUL; GSYM REAL_LE_SQUARE_ABS] THEN
168 MP_TAC(ISPECL [`sqrt(&5)`; `y:real`] (CONJUNCT1 REAL_LE_MUL_EQ)) THEN
169 SIMP_TAC[SQRT_POS_LT; REAL_OF_NUM_LT; ARITH] THEN REAL_ARITH_TAC) in
171 (`(a1 + b1 * sqrt(&5)) <= (a2 + b2 * sqrt(&5)) <=>
172 a1 <= a2 /\ b1 <= b2 \/
173 a2 <= a1 /\ b1 <= b2 /\ (a1 - a2) pow 2 <= &5 * (b2 - b1) pow 2 \/
174 a1 <= a2 /\ b2 <= b1 /\ &5 * (b2 - b1) pow 2 <= (a1 - a2) pow 2`,
175 REWRITE_TAC[REAL_ARITH
176 `a + b * x <= a' + b' * x <=> a - a' <= (b' - b) * x`] THEN
177 REWRITE_TAC[lemma] THEN REAL_ARITH_TAC) in
178 REAL_RAT_LE_CONV ORELSEC
179 (BINOP_CONV REAL_RAT5_OF_RAT_CONV THENC
180 GEN_REWRITE_CONV I [pth] THENC
181 REAL_RAT_REDUCE_CONV);;
183 let REAL_RAT5_EQ_CONV =
184 GEN_REWRITE_CONV I [GSYM REAL_LE_ANTISYM] THENC
185 BINOP_CONV REAL_RAT5_LE_CONV THENC
186 GEN_REWRITE_CONV I [AND_CLAUSES];;
188 (* ------------------------------------------------------------------------- *)
189 (* Conversions for operations on 3D vectors with coordinates in Q[sqrt(5)] *)
190 (* ------------------------------------------------------------------------- *)
192 let VECTOR3_SUB_CONV =
194 (`vector[x1;x2;x3] - vector[y1;y2;y3]:real^3 =
195 vector[x1-y1; x2-y2; x3-y3]`,
196 SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3] THEN
197 REWRITE_TAC[VECTOR_3; VECTOR_SUB_COMPONENT]) in
198 GEN_REWRITE_CONV I [pth] THENC RAND_CONV(LIST_CONV REAL_RAT5_SUB_CONV);;
200 let VECTOR3_CROSS_CONV =
202 (`(vector[x1;x2;x3]) cross (vector[y1;y2;y3]) =
203 vector[x2 * y3 - x3 * y2; x3 * y1 - x1 * y3; x1 * y2 - x2 * y1]`,
204 REWRITE_TAC[cross; VECTOR_3]) in
205 GEN_REWRITE_CONV I [pth] THENC
206 RAND_CONV(LIST_CONV(BINOP_CONV REAL_RAT5_MUL_CONV THENC REAL_RAT5_SUB_CONV));;
208 let VECTOR3_EQ_0_CONV =
210 (`vector[x1;x2;x3]:real^3 = vec 0 <=>
211 x1 = &0 /\ x2 = &0 /\ x3 = &0`,
212 SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3] THEN
213 REWRITE_TAC[VECTOR_3; VEC_COMPONENT]) in
214 GEN_REWRITE_CONV I [pth] THENC
215 DEPTH_BINOP_CONV `(/\)` REAL_RAT5_EQ_CONV THENC
218 let VECTOR3_DOT_CONV =
220 (`(vector[x1;x2;x3]:real^3) dot (vector[y1;y2;y3]) =
221 x1*y1 + x2*y2 + x3*y3`,
222 REWRITE_TAC[DOT_3; VECTOR_3]) in
223 GEN_REWRITE_CONV I [pth] THENC
224 DEPTH_BINOP_CONV `(+):real->real->real` REAL_RAT5_MUL_CONV THENC
225 RAND_CONV REAL_RAT5_ADD_CONV THENC
228 (* ------------------------------------------------------------------------- *)
229 (* Put any irrational coordinates in our standard form. *)
230 (* ------------------------------------------------------------------------- *)
232 let STD_DODECAHEDRON = prove
235 { vector[&1; &1; &1],
236 vector[&1; &1; -- &1],
237 vector[&1; -- &1; &1],
238 vector[&1; -- &1; -- &1],
239 vector[-- &1; &1; &1],
240 vector[-- &1; &1; -- &1],
241 vector[-- &1; -- &1; &1],
242 vector[-- &1; -- &1; -- &1],
243 vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)],
244 vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)],
245 vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)],
246 vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)],
247 vector[-- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0],
248 vector[-- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0],
249 vector[&1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0],
250 vector[&1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0],
251 vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)],
252 vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)],
253 vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)],
254 vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)]}`,
255 let golden_inverse = prove
256 (`inv((&1 + sqrt(&5)) / &2) = -- &1 / &2 + &1 / &2 * sqrt(&5)`,
257 MP_TAC(ISPEC `&5` SQRT_POW_2) THEN CONV_TAC REAL_FIELD) in
258 REWRITE_TAC[std_dodecahedron] THEN
259 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
260 REWRITE_TAC[golden_inverse] THEN
261 REWRITE_TAC[REAL_ARITH `(&1 + s) / &2 = &1 / &2 + &1 / &2 * s`] THEN
262 REWRITE_TAC[REAL_ARITH `--(a + b * sqrt(&5)) = --a + --b * sqrt(&5)`] THEN
263 CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[]);;
265 let STD_ICOSAHEDRON = prove
268 { vector[&0; &1; &1 / &2 + &1 / &2 * sqrt(&5)],
269 vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)],
270 vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt(&5)],
271 vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)],
272 vector[&1; &1 / &2 + &1 / &2 * sqrt(&5); &0],
273 vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0],
274 vector[-- &1; &1 / &2 + &1 / &2 * sqrt(&5); &0],
275 vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0],
276 vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1],
277 vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1],
278 vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1],
279 vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1]}`,
280 REWRITE_TAC[std_icosahedron] THEN
281 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
282 REWRITE_TAC[REAL_ARITH `(&1 + s) / &2 = &1 / &2 + &1 / &2 * s`] THEN
283 REWRITE_TAC[REAL_ARITH `--(a + b * sqrt(&5)) = --a + --b * sqrt(&5)`] THEN
284 CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[]);;
286 (* ------------------------------------------------------------------------- *)
287 (* Explicit computation of facets. *)
288 (* ------------------------------------------------------------------------- *)
290 let COMPUTE_FACES_2 = prove
293 ==> (f face_of (convex hull s) /\ aff_dim f = &2 <=>
294 ?x y z. x IN s /\ y IN s /\ z IN s /\
295 let a = (z - x) cross (y - x) in
298 ((!w. w IN s ==> a dot w <= b) \/
299 (!w. w IN s ==> a dot w >= b)) /\
300 f = convex hull (s INTER {x | a dot x = b}))`,
301 REPEAT GEN_TAC THEN STRIP_TAC THEN EQ_TAC THENL
303 SUBGOAL_THEN `?t:real^3->bool. t SUBSET s /\ f = convex hull t`
305 [MATCH_MP_TAC FACE_OF_CONVEX_HULL_SUBSET THEN
306 ASM_SIMP_TAC[FINITE_IMP_COMPACT];
307 DISCH_THEN(X_CHOOSE_THEN `t:real^3->bool` MP_TAC)] THEN
308 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN
309 RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_CONVEX_HULL]) THEN
310 MP_TAC(ISPEC `t:real^3->bool` AFFINE_BASIS_EXISTS) THEN
311 DISCH_THEN(X_CHOOSE_THEN `u:real^3->bool` STRIP_ASSUME_TAC) THEN
312 SUBGOAL_THEN `(u:real^3->bool) HAS_SIZE 3` MP_TAC THENL
313 [ASM_SIMP_TAC[HAS_SIZE; AFFINE_INDEPENDENT_IMP_FINITE] THEN
314 REWRITE_TAC[GSYM INT_OF_NUM_EQ] THEN MATCH_MP_TAC(INT_ARITH
315 `aff_dim(u:real^3->bool) = &2 /\ aff_dim u = &(CARD u) - &1
316 ==> &(CARD u):int = &3`) THEN CONJ_TAC
317 THENL [ASM_MESON_TAC[AFF_DIM_AFFINE_HULL]; ASM_MESON_TAC[AFF_DIM_UNIQUE]];
319 CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN
320 MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`; `z:real^3`] THEN
321 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
322 DISCH_THEN SUBST_ALL_TAC THEN
323 MAP_EVERY EXISTS_TAC [`x:real^3`; `y:real^3`; `z:real^3`] THEN
324 REPLICATE_TAC 3 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
326 SUBGOAL_THEN `~collinear{x:real^3,y,z}` MP_TAC THENL
327 [ASM_REWRITE_TAC[COLLINEAR_3_EQ_AFFINE_DEPENDENT]; ALL_TAC] THEN
328 ONCE_REWRITE_TAC[SET_RULE `{x,y,z} = {z,x,y}`] THEN
329 ONCE_REWRITE_TAC[COLLINEAR_3] THEN ASM_REWRITE_TAC[GSYM CROSS_EQ_0] THEN
330 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
331 SUBGOAL_THEN `(a:real^3) dot y = b /\ (a:real^3) dot z = b`
332 STRIP_ASSUME_TAC THENL
333 [MAP_EVERY UNDISCH_TAC
334 [`(z - x) cross (y - x) = a`; `(a:real^3) dot x = b`] THEN VEC3_TAC;
336 MP_TAC(ISPECL [`convex hull s:real^3->bool`; `convex hull t:real^3->bool`]
337 EXPOSED_FACE_OF_POLYHEDRON) THEN
338 ASM_SIMP_TAC[POLYHEDRON_CONVEX_HULL; exposed_face_of] THEN
339 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
340 MAP_EVERY X_GEN_TAC [`a':real^3`; `b':real`] THEN
341 DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN
343 `aff_dim(t:real^3->bool)
344 <= aff_dim({x:real^3 | a dot x = b} INTER {x | a' dot x = b'})`
346 [GEN_REWRITE_TAC LAND_CONV [GSYM AFF_DIM_AFFINE_HULL] THEN
347 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV)
349 REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN MATCH_MP_TAC AFF_DIM_SUBSET THEN
350 REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THENL
352 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `t:real^3->bool` THEN
353 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
354 EXISTS_TAC `convex hull t:real^3->bool` THEN
355 REWRITE_TAC[HULL_SUBSET] THEN ASM SET_TAC[]];
357 ASM_SIMP_TAC[AFF_DIM_AFFINE_INTER_HYPERPLANE; AFF_DIM_HYPERPLANE;
358 AFFINE_HYPERPLANE; DIMINDEX_3] THEN
359 REPEAT(COND_CASES_TAC THEN CONV_TAC INT_REDUCE_CONV) THEN
360 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
361 [SUBSET_HYPERPLANES]) THEN
362 ASM_REWRITE_TAC[HYPERPLANE_EQ_EMPTY] THEN
363 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC (MP_TAC o SYM)) THENL
364 [RULE_ASSUM_TAC(REWRITE_RULE[INTER_UNIV]) THEN
365 SUBGOAL_THEN `s SUBSET {x:real^3 | a dot x = b}` ASSUME_TAC THENL
366 [MATCH_MP_TAC SUBSET_TRANS THEN
367 EXISTS_TAC `convex hull s:real^3->bool` THEN
368 REWRITE_TAC[HULL_SUBSET] THEN ASM_REWRITE_TAC[] THEN
369 MATCH_MP_TAC SUBSET_TRANS THEN
370 EXISTS_TAC `affine hull t:real^3->bool` THEN
371 REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN
372 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
373 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[AFFINE_HYPERPLANE] THEN
377 [RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_ELIM_THM]) THEN
378 ASM_SIMP_TAC[real_ge; REAL_LE_REFL];
379 ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER t = s`]];
381 DISCH_THEN(fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th) THEN
383 [MATCH_MP_TAC(TAUT `(~p /\ ~q ==> F) ==> p \/ q`) THEN
384 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; real_ge; REAL_NOT_LE] THEN
385 DISCH_THEN(CONJUNCTS_THEN2
386 (X_CHOOSE_TAC `u:real^3`) (X_CHOOSE_TAC `v:real^3`)) THEN
387 SUBGOAL_THEN `(a':real^3) dot u < b' /\ a' dot v < b'` ASSUME_TAC THENL
388 [REWRITE_TAC[REAL_LT_LE] THEN REWRITE_TAC
389 [SET_RULE `f x <= b /\ ~(f x = b) <=>
390 x IN {x | f x <= b} /\ ~(x IN {x | f x = b})`] THEN
391 ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[IN_ELIM_THM; REAL_LT_IMP_NE] THEN
392 SUBGOAL_THEN `(u:real^3) IN convex hull s /\ v IN convex hull s`
393 MP_TAC THENL [ASM_SIMP_TAC[HULL_INC]; ASM SET_TAC[]];
395 SUBGOAL_THEN `?w:real^3. w IN segment[u,v] /\ w IN {w | a' dot w = b'}`
397 [ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_ELIM_THM] THEN
398 MATCH_MP_TAC CONNECTED_IVT_HYPERPLANE THEN
399 MAP_EVERY EXISTS_TAC [`v:real^3`; `u:real^3`] THEN
400 ASM_SIMP_TAC[ENDS_IN_SEGMENT; CONNECTED_SEGMENT; REAL_LT_IMP_LE];
401 REWRITE_TAC[IN_SEGMENT; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN
402 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
403 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM] THEN
404 REWRITE_TAC[UNWIND_THM2; DOT_RADD; DOT_RMUL; CONJ_ASSOC] THEN
405 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN
406 MATCH_MP_TAC(REAL_ARITH `a < b ==> a = b ==> F`) THEN
407 MATCH_MP_TAC REAL_CONVEX_BOUND_LT THEN ASM_REAL_ARITH_TAC];
408 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
409 [MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET_INTER] THEN
410 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
411 EXISTS_TAC `convex hull t:real^3->bool` THEN
412 REWRITE_TAC[HULL_SUBSET] THEN ASM SET_TAC[];
413 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN
414 REWRITE_TAC[SUBSET_INTER] THEN
415 SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN
416 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
417 EXISTS_TAC `convex hull {x:real^3 | a dot x = b}` THEN
418 SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN
419 MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN
420 REWRITE_TAC[CONVEX_HULL_EQ; CONVEX_HYPERPLANE]]];
421 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
422 MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`; `z:real^3`] THEN
424 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN CONJ_TAC THENL
425 [ASM_REWRITE_TAC[] THEN
427 `convex hull (s INTER {x:real^3 | a dot x = b}) =
428 (convex hull s) INTER {x | a dot x = b}`
430 [MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
431 [SIMP_TAC[SUBSET_INTER; HULL_MONO; INTER_SUBSET] THEN
432 MATCH_MP_TAC SUBSET_TRANS THEN
433 EXISTS_TAC `convex hull {x:real^3 | a dot x = b}` THEN
434 SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN
435 MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN
436 REWRITE_TAC[CONVEX_HULL_EQ; CONVEX_HYPERPLANE];
438 ASM_CASES_TAC `s SUBSET {x:real^3 | a dot x = b}` THENL
439 [ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER t = s`] THEN SET_TAC[];
441 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC
442 `convex hull (convex hull (s INTER {x:real^3 | a dot x = b}) UNION
443 convex hull (s DIFF {x | a dot x = b})) INTER
444 {x | a dot x = b}` THEN
446 [MATCH_MP_TAC(SET_RULE
447 `s SUBSET t ==> (s INTER u) SUBSET (t INTER u)`) THEN
448 MATCH_MP_TAC HULL_MONO THEN MATCH_MP_TAC(SET_RULE
449 `s INTER t SUBSET (P hull (s INTER t)) /\
450 s DIFF t SUBSET (P hull (s DIFF t))
451 ==> s SUBSET (P hull (s INTER t)) UNION (P hull (s DIFF t))`) THEN
452 REWRITE_TAC[HULL_SUBSET];
454 W(MP_TAC o PART_MATCH (lhs o rand) CONVEX_HULL_UNION_NONEMPTY_EXPLICIT o
455 lhand o lhand o snd) THEN
457 [SIMP_TAC[CONVEX_CONVEX_HULL; CONVEX_HULL_EQ_EMPTY] THEN ASM SET_TAC[];
458 DISCH_THEN SUBST1_TAC] THEN
459 REWRITE_TAC[SUBSET; IN_INTER; IMP_CONJ; FORALL_IN_GSPEC] THEN
460 MAP_EVERY X_GEN_TAC [`p:real^3`; `u:real`; `q:real^3`] THEN
461 REPLICATE_TAC 4 DISCH_TAC THEN ASM_CASES_TAC `u = &0` THEN
462 ASM_REWRITE_TAC[VECTOR_ARITH `(&1 - &0) % p + &0 % q:real^N = p`] THEN
463 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[IN_ELIM_THM] THEN
464 REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN FIRST_X_ASSUM DISJ_CASES_TAC THENL
465 [MATCH_MP_TAC(REAL_ARITH `x < y ==> ~(x = y)`) THEN
466 MATCH_MP_TAC(REAL_ARITH
467 `(&1 - u) * p = (&1 - u) * b /\ u * q < u * b
468 ==> (&1 - u) * p + u * q < b`) THEN
470 [SUBGOAL_THEN `p IN {x:real^3 | a dot x = b}` MP_TAC THENL
471 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
472 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
473 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HYPERPLANE] THEN
475 SIMP_TAC[IN_ELIM_THM]];
476 MATCH_MP_TAC REAL_LT_LMUL THEN CONJ_TAC THENL
477 [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
478 ONCE_REWRITE_TAC[SET_RULE
479 `(a:real^3) dot q < b <=> q IN {x | a dot x < b}`] THEN
480 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
481 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
482 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_LT] THEN
483 ASM_SIMP_TAC[SUBSET; IN_DIFF; IN_ELIM_THM; REAL_LT_LE]];
484 MATCH_MP_TAC(REAL_ARITH `x > y ==> ~(x = y)`) THEN
485 MATCH_MP_TAC(REAL_ARITH
486 `(&1 - u) * p = (&1 - u) * b /\ u * b < u * q
487 ==> (&1 - u) * p + u * q > b`) THEN
489 [SUBGOAL_THEN `p IN {x:real^3 | a dot x = b}` MP_TAC THENL
490 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
491 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
492 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HYPERPLANE] THEN
494 SIMP_TAC[IN_ELIM_THM]];
495 MATCH_MP_TAC REAL_LT_LMUL THEN CONJ_TAC THENL
496 [ASM_REAL_ARITH_TAC; REWRITE_TAC[GSYM real_gt]] THEN
497 ONCE_REWRITE_TAC[SET_RULE
498 `(a:real^3) dot q > b <=> q IN {x | a dot x > b}`] THEN
499 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
500 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
501 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_GT] THEN
502 RULE_ASSUM_TAC(REWRITE_RULE[real_ge]) THEN
503 ASM_SIMP_TAC[SUBSET; IN_DIFF; IN_ELIM_THM; real_gt; REAL_LT_LE]]];
505 FIRST_X_ASSUM DISJ_CASES_TAC THENL
506 [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
507 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN
508 SIMP_TAC[SET_RULE `(!x. x IN s ==> P x) <=> s SUBSET {x | P x}`] THEN
509 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_LE] THEN
510 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM];
511 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN
512 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN
513 SIMP_TAC[SET_RULE `(!x. x IN s ==> P x) <=> s SUBSET {x | P x}`] THEN
514 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_GE] THEN
515 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM]];
516 REWRITE_TAC[GSYM INT_LE_ANTISYM] THEN CONJ_TAC THENL
517 [MATCH_MP_TAC INT_LE_TRANS THEN
518 EXISTS_TAC `aff_dim {x:real^3 | a dot x = b}` THEN CONJ_TAC THENL
519 [MATCH_MP_TAC AFF_DIM_SUBSET THEN ASM_REWRITE_TAC[] THEN
520 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HYPERPLANE] THEN
522 ASM_SIMP_TAC[AFF_DIM_HYPERPLANE; DIMINDEX_3] THEN INT_ARITH_TAC];
523 MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim {x:real^3,y,z}` THEN
525 [SUBGOAL_THEN `~collinear{x:real^3,y,z}` MP_TAC THENL
526 [ONCE_REWRITE_TAC[SET_RULE `{x,y,z} = {z,x,y}`] THEN
527 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
528 ASM_REWRITE_TAC[GSYM CROSS_EQ_0];
529 REWRITE_TAC[COLLINEAR_3_EQ_AFFINE_DEPENDENT; DE_MORGAN_THM] THEN
531 ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT] THEN
532 SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
533 ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH] THEN
534 CONV_TAC INT_REDUCE_CONV;
535 MATCH_MP_TAC AFF_DIM_SUBSET THEN ASM_REWRITE_TAC[INSERT_SUBSET] THEN
536 REWRITE_TAC[EMPTY_SUBSET] THEN REPEAT CONJ_TAC THEN
537 MATCH_MP_TAC HULL_INC THEN
538 ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
539 MAP_EVERY UNDISCH_TAC
540 [`(z - x) cross (y - x) = a`; `(a:real^3) dot x = b`] THEN
543 let COMPUTE_FACES_2_STEP_1 = prove
544 (`!f v s t:real^3->bool.
545 (?x y z. x IN (v INSERT s) /\ y IN (v INSERT s) /\ z IN (v INSERT s) /\
546 let a = (z - x) cross (y - x) in
549 ((!w. w IN t ==> a dot w <= b) \/
550 (!w. w IN t ==> a dot w >= b)) /\
551 f = convex hull (t INTER {x | a dot x = b})) <=>
552 (?y z. y IN s /\ z IN s /\
553 let a = (z - v) cross (y - v) in
556 ((!w. w IN t ==> a dot w <= b) \/
557 (!w. w IN t ==> a dot w >= b)) /\
558 f = convex hull (t INTER {x | a dot x = b})) \/
559 (?x y z. x IN s /\ y IN s /\ z IN s /\
560 let a = (z - x) cross (y - x) in
563 ((!w. w IN t ==> a dot w <= b) \/
564 (!w. w IN t ==> a dot w >= b)) /\
565 f = convex hull (t INTER {x | a dot x = b}))`,
566 REPEAT GEN_TAC THEN REWRITE_TAC[IN_INSERT] THEN MATCH_MP_TAC(MESON[]
567 `(!x y z. Q x y z ==> Q x z y) /\
568 (!x y z. Q x y z ==> Q y x z) /\
570 ==> ((?x y z. (x = v \/ P x) /\ (y = v \/ P y) /\ (z = v \/ P z) /\
572 (?y z. P y /\ P z /\ Q v y z) \/
573 (?x y z. P x /\ P y /\ P z /\ Q x y z))`) THEN
574 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
575 REWRITE_TAC[VECTOR_SUB_REFL; CROSS_0] THEN
576 CONJ_TAC THEN REPEAT GEN_TAC THEN
577 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
578 MAP_EVERY (SUBST1_TAC o VEC3_RULE)
579 [`(z - y) cross (x - y) = --((z - x) cross (y - x))`;
580 `(y - x) cross (z - x) = --((z - x) cross (y - x))`] THEN
581 REWRITE_TAC[VECTOR_NEG_EQ_0; DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2;
583 REWRITE_TAC[DISJ_ACI] THEN
584 REWRITE_TAC[VEC3_RULE
585 `((z - x) cross (y - x)) dot y = ((z - x) cross (y - x)) dot x`]);;
587 let COMPUTE_FACES_2_STEP_2 = prove
588 (`!f u v s:real^3->bool.
589 (?y z. y IN (u INSERT s) /\ z IN (u INSERT s) /\
590 let a = (z - v) cross (y - v) in
593 ((!w. w IN t ==> a dot w <= b) \/
594 (!w. w IN t ==> a dot w >= b)) /\
595 f = convex hull (t INTER {x | a dot x = b})) <=>
597 let a = (z - v) cross (u - v) in
600 ((!w. w IN t ==> a dot w <= b) \/
601 (!w. w IN t ==> a dot w >= b)) /\
602 f = convex hull (t INTER {x | a dot x = b})) \/
603 (?y z. y IN s /\ z IN s /\
604 let a = (z - v) cross (y - v) in
607 ((!w. w IN t ==> a dot w <= b) \/
608 (!w. w IN t ==> a dot w >= b)) /\
609 f = convex hull (t INTER {x | a dot x = b}))`,
610 REPEAT GEN_TAC THEN REWRITE_TAC[IN_INSERT] THEN MATCH_MP_TAC(MESON[]
611 `(!x y. Q x y ==> Q y x) /\
613 ==> ((?y z. (y = u \/ P y) /\ (z = u \/ P z) /\
615 (?z. P z /\ Q u z) \/
616 (?y z. P y /\ P z /\ Q y z))`) THEN
617 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
618 REWRITE_TAC[CROSS_REFL] THEN REPEAT GEN_TAC THEN
619 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN SUBST1_TAC
620 (VEC3_RULE `(x - v) cross (y - v) = --((y - v) cross (x - v))`) THEN
621 REWRITE_TAC[VECTOR_NEG_EQ_0; DOT_LNEG; REAL_EQ_NEG2; REAL_LE_NEG2;
622 real_ge] THEN REWRITE_TAC[DISJ_ACI]);;
624 let COMPUTE_FACES_TAC =
626 (`(x INSERT s) INTER {x | P x} =
627 if P x then x INSERT (s INTER {x | P x})
628 else s INTER {x | P x}`,
629 COND_CASES_TAC THEN ASM SET_TAC[]) in
630 SIMP_TAC[COMPUTE_FACES_2; FINITE_INSERT; FINITE_EMPTY] THEN
631 REWRITE_TAC[COMPUTE_FACES_2_STEP_1] THEN
632 REWRITE_TAC[COMPUTE_FACES_2_STEP_2] THEN
633 REWRITE_TAC[NOT_IN_EMPTY] THEN
634 REWRITE_TAC[EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN
635 REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN
636 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_SUB_CONV) THEN
637 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_CROSS_CONV) THEN
638 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
639 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_EQ_0_CONV) THEN
640 REWRITE_TAC[real_ge] THEN
641 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_DOT_CONV) THEN
642 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN
643 CONV_TAC(ONCE_DEPTH_CONV REAL_RAT5_LE_CONV) THEN
644 REWRITE_TAC[INSERT_AC] THEN REWRITE_TAC[DISJ_ACI] THEN
646 (ONCE_REWRITE_TAC[lemma] THEN
647 CONV_TAC(ONCE_DEPTH_CONV
648 (LAND_CONV VECTOR3_DOT_CONV THENC REAL_RAT5_EQ_CONV))) THEN
650 REWRITE_TAC[INTER_EMPTY] THEN
651 REWRITE_TAC[INSERT_AC] THEN REWRITE_TAC[DISJ_ACI];;
653 (* ------------------------------------------------------------------------- *)
654 (* Apply this to our standard Platonic solids to derive facets. *)
655 (* Note: this is quite slow and can take a couple of hours. *)
656 (* ------------------------------------------------------------------------- *)
658 let TETRAHEDRON_FACETS = time prove
660 f face_of std_tetrahedron /\ aff_dim f = &2 <=>
661 f = convex hull {vector[-- &1; -- &1; &1], vector[-- &1; &1; -- &1], vector[&1; -- &1; -- &1]} \/
662 f = convex hull {vector[-- &1; -- &1; &1], vector[-- &1; &1; -- &1], vector[&1; &1; &1]} \/
663 f = convex hull {vector[-- &1; -- &1; &1], vector[&1; -- &1; -- &1], vector[&1; &1; &1]} \/
664 f = convex hull {vector[-- &1; &1; -- &1], vector[&1; -- &1; -- &1], vector[&1; &1; &1]}`,
665 GEN_TAC THEN REWRITE_TAC[std_tetrahedron] THEN COMPUTE_FACES_TAC);;
667 let CUBE_FACETS = time prove
669 f face_of std_cube /\ aff_dim f = &2 <=>
670 f = convex hull {vector[-- &1; -- &1; -- &1], vector[-- &1; -- &1; &1], vector[-- &1; &1; -- &1], vector[-- &1; &1; &1]} \/
671 f = convex hull {vector[-- &1; -- &1; -- &1], vector[-- &1; -- &1; &1], vector[&1; -- &1; -- &1], vector[&1; -- &1; &1]} \/
672 f = convex hull {vector[-- &1; -- &1; -- &1], vector[-- &1; &1; -- &1], vector[&1; -- &1; -- &1], vector[&1; &1; -- &1]} \/
673 f = convex hull {vector[-- &1; -- &1; &1], vector[-- &1; &1; &1], vector[&1; -- &1; &1], vector[&1; &1; &1]} \/
674 f = convex hull {vector[-- &1; &1; -- &1], vector[-- &1; &1; &1], vector[&1; &1; -- &1], vector[&1; &1; &1]} \/
675 f = convex hull {vector[&1; -- &1; -- &1], vector[&1; -- &1; &1], vector[&1; &1; -- &1], vector[&1; &1; &1]}`,
676 GEN_TAC THEN REWRITE_TAC[std_cube] THEN COMPUTE_FACES_TAC);;
678 let OCTAHEDRON_FACETS = time prove
680 f face_of std_octahedron /\ aff_dim f = &2 <=>
681 f = convex hull {vector[-- &1; &0; &0], vector[&0; -- &1; &0], vector[&0; &0; -- &1]} \/
682 f = convex hull {vector[-- &1; &0; &0], vector[&0; -- &1; &0], vector[&0; &0; &1]} \/
683 f = convex hull {vector[-- &1; &0; &0], vector[&0; &1; &0], vector[&0; &0; -- &1]} \/
684 f = convex hull {vector[-- &1; &0; &0], vector[&0; &1; &0], vector[&0; &0; &1]} \/
685 f = convex hull {vector[&1; &0; &0], vector[&0; -- &1; &0], vector[&0; &0; -- &1]} \/
686 f = convex hull {vector[&1; &0; &0], vector[&0; -- &1; &0], vector[&0; &0; &1]} \/
687 f = convex hull {vector[&1; &0; &0], vector[&0; &1; &0], vector[&0; &0; -- &1]} \/
688 f = convex hull {vector[&1; &0; &0], vector[&0; &1; &0], vector[&0; &0; &1]}`,
689 GEN_TAC THEN REWRITE_TAC[std_octahedron] THEN COMPUTE_FACES_TAC);;
691 let ICOSAHEDRON_FACETS = time prove
693 f face_of std_icosahedron /\ aff_dim f = &2 <=>
694 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1], vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1], vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0]} \/
695 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1], vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1], vector[-- &1; &1 / &2 + &1 / &2 * sqrt(&5); &0]} \/
696 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1], vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
697 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1], vector[-- &1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
698 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
699 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1], vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
700 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1], vector[-- &1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
701 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt(&5)], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
702 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1], vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0]} \/
703 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1], vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1], vector[&1; &1 / &2 + &1 / &2 * sqrt(&5); &0]} \/
704 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
705 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1], vector[&1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
706 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
707 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
708 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1], vector[&1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
709 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt(&5)], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
710 f = convex hull {vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
711 f = convex hull {vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt(&5)]} \/
712 f = convex hull {vector[-- &1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
713 f = convex hull {vector[-- &1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&1; &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt(&5)]}`,
714 GEN_TAC THEN REWRITE_TAC[STD_ICOSAHEDRON] THEN COMPUTE_FACES_TAC);;
716 let DODECAHEDRON_FACETS = time prove
718 f face_of std_dodecahedron /\ aff_dim f = &2 <=>
719 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)], vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[-- &1; -- &1; -- &1], vector[-- &1; -- &1; &1]} \/
720 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)], vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[-- &1; &1; -- &1], vector[-- &1; &1; &1]} \/
721 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)], vector[-- &1; -- &1; &1], vector[-- &1; &1; &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)], vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)]} \/
722 f = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[-- &1; -- &1; -- &1], vector[-- &1; &1; -- &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
723 f = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[-- &1; -- &1; -- &1], vector[&1; -- &1; -- &1], vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
724 f = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[-- &1; -- &1; &1], vector[&1; -- &1; &1], vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)]} \/
725 f = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5); &0], vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)], vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&1; -- &1; -- &1], vector[&1; -- &1; &1]} \/
726 f = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[-- &1; &1; -- &1], vector[&1; &1; -- &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)]} \/
727 f = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[-- &1; &1; &1], vector[&1; &1; &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)]} \/
728 f = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5); &0], vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)], vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&1; &1; -- &1], vector[&1; &1; &1]} \/
729 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; -- &1 / &2 + &1 / &2 * sqrt(&5)], vector[&1; -- &1; &1], vector[&1; &1; &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)], vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); &1 / &2 + &1 / &2 * sqrt(&5)]} \/
730 f = convex hull {vector[&1 / &2 + &1 / &2 * sqrt(&5); &0; &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&1; -- &1; -- &1], vector[&1; &1; -- &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)], vector[&0; &1 / &2 + -- &1 / &2 * sqrt(&5); -- &1 / &2 + -- &1 / &2 * sqrt(&5)]}`,
731 GEN_TAC THEN REWRITE_TAC[STD_DODECAHEDRON] THEN COMPUTE_FACES_TAC);;
733 (* ------------------------------------------------------------------------- *)
734 (* Given a coplanar set, return a hyperplane containing it. *)
735 (* Maps term s to theorem |- !x. x IN s ==> n dot x = d *)
736 (* Currently assumes |s| >= 3 but it would be trivial to do other cases. *)
737 (* ------------------------------------------------------------------------- *)
739 let COPLANAR_HYPERPLANE_RULE =
740 let rec allsets m l =
741 if m = 0 then [[]] else
744 | h::t -> map (fun g -> h::g) (allsets (m - 1) t) @ allsets m t in
745 let mk_sub = mk_binop `(-):real^3->real^3->real^3`
746 and mk_cross = mk_binop `cross`
747 and mk_dot = mk_binop `(dot):real^3->real^3->real`
748 and zerovec_tm = `vector[&0;&0;&0]:real^3`
749 and template = `(!x:real^3. x IN s ==> n dot x = d)`
750 and s_tm = `s:real^3->bool`
751 and n_tm = `n:real^3`
752 and d_tm = `d:real` in
753 let mk_normal [x;y;z] = mk_cross (mk_sub y x) (mk_sub z x) in
755 (BINOP_CONV VECTOR3_SUB_CONV THENC VECTOR3_CROSS_CONV) (mk_normal t) in
757 let th = eval_normal t in
758 let n = rand(concl th) in
759 if n = zerovec_tm then failwith "check_normal" else n in
761 let s = dest_setenum tm in
762 if length s < 3 then failwith "COPLANAR_HYPERPLANE_RULE: trivial" else
763 let n = tryfind check_normal (allsets 3 s) in
764 let d = rand(concl(VECTOR3_DOT_CONV(mk_dot n (hd s)))) in
765 let ptm = vsubst [tm,s_tm; n,n_tm; d,d_tm] template in
767 ((REWRITE_CONV[FORALL_IN_INSERT; NOT_IN_EMPTY] THENC
768 DEPTH_BINOP_CONV `/\`
769 (LAND_CONV VECTOR3_DOT_CONV THENC REAL_RAT5_EQ_CONV) THENC
770 GEN_REWRITE_CONV DEPTH_CONV [AND_CLAUSES]) ptm);;
772 (* ------------------------------------------------------------------------- *)
773 (* Explicit computation of edges, assuming hyperplane containing the set. *)
774 (* ------------------------------------------------------------------------- *)
776 let COMPUTE_FACES_1 = prove
777 (`!s:real^3->bool n d.
778 (!x. x IN s ==> n dot x = d)
779 ==> FINITE s /\ ~(n = vec 0)
780 ==> !f. f face_of (convex hull s) /\ aff_dim f = &1 <=>
781 ?x y. x IN s /\ y IN s /\
782 let a = n cross (y - x) in
785 ((!w. w IN s ==> a dot w <= b) \/
786 (!w. w IN s ==> a dot w >= b)) /\
787 f = convex hull (s INTER {x | a dot x = b})`,
788 REPEAT GEN_TAC THEN STRIP_TAC THEN STRIP_TAC THEN GEN_TAC THEN EQ_TAC THENL
790 SUBGOAL_THEN `?t:real^3->bool. t SUBSET s /\ f = convex hull t`
792 [MATCH_MP_TAC FACE_OF_CONVEX_HULL_SUBSET THEN
793 ASM_SIMP_TAC[FINITE_IMP_COMPACT];
794 DISCH_THEN(X_CHOOSE_THEN `t:real^3->bool` MP_TAC)] THEN
795 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN
796 RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_CONVEX_HULL]) THEN
797 MP_TAC(ISPEC `t:real^3->bool` AFFINE_BASIS_EXISTS) THEN
798 DISCH_THEN(X_CHOOSE_THEN `u:real^3->bool` STRIP_ASSUME_TAC) THEN
799 SUBGOAL_THEN `(u:real^3->bool) HAS_SIZE 2` MP_TAC THENL
800 [ASM_SIMP_TAC[HAS_SIZE; AFFINE_INDEPENDENT_IMP_FINITE] THEN
801 REWRITE_TAC[GSYM INT_OF_NUM_EQ] THEN MATCH_MP_TAC(INT_ARITH
802 `aff_dim(u:real^3->bool) = &1 /\ aff_dim u = &(CARD u) - &1
803 ==> &(CARD u):int = &2`) THEN CONJ_TAC
804 THENL [ASM_MESON_TAC[AFF_DIM_AFFINE_HULL]; ASM_MESON_TAC[AFF_DIM_UNIQUE]];
806 CONV_TAC(LAND_CONV HAS_SIZE_CONV) THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN
807 MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`] THEN
808 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN
809 MAP_EVERY EXISTS_TAC [`x:real^3`; `y:real^3`] THEN
810 REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
811 SUBGOAL_THEN `(x:real^3) IN s /\ y IN s` STRIP_ASSUME_TAC THENL
812 [ASM SET_TAC[]; ALL_TAC] THEN
814 MP_TAC(ISPECL [`n:real^3`; `y - x:real^3`] NORM_AND_CROSS_EQ_0) THEN
815 ASM_SIMP_TAC[DOT_RSUB; VECTOR_SUB_EQ; REAL_SUB_0] THEN DISCH_TAC THEN
816 SUBGOAL_THEN `(a:real^3) dot y = b` ASSUME_TAC THENL
817 [MAP_EVERY UNDISCH_TAC
818 [`n cross (y - x) = a`; `(a:real^3) dot x = b`] THEN VEC3_TAC;
820 MP_TAC(ISPECL [`convex hull s:real^3->bool`; `convex hull t:real^3->bool`]
821 EXPOSED_FACE_OF_POLYHEDRON) THEN
822 ASM_SIMP_TAC[POLYHEDRON_CONVEX_HULL; EXPOSED_FACE_OF_PARALLEL] THEN
823 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
824 MAP_EVERY X_GEN_TAC [`a':real^3`; `b':real`] THEN
825 SUBGOAL_THEN `~(convex hull t:real^3->bool = {})` ASSUME_TAC THENL
826 [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `x:real^3` THEN
827 MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[];
828 ASM_REWRITE_TAC[]] THEN
829 ASM_CASES_TAC `convex hull t:real^3->bool = convex hull s` THEN
830 ASM_REWRITE_TAC[] THENL
831 [FIRST_X_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE RAND_CONV
832 [GSYM AFFINE_HULL_CONVEX_HULL]) THEN
833 UNDISCH_THEN `convex hull t:real^3->bool = convex hull s`
834 (fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th) THEN
835 RULE_ASSUM_TAC(REWRITE_RULE[AFFINE_HULL_CONVEX_HULL]) THEN
836 REWRITE_TAC[SET_RULE `s = s INTER t <=> s SUBSET t`] THEN STRIP_TAC THEN
837 SUBGOAL_THEN `s SUBSET {x:real^3 | a dot x = b}` ASSUME_TAC THENL
838 [MATCH_MP_TAC SUBSET_TRANS THEN
839 EXISTS_TAC `affine hull s:real^3->bool` THEN
840 REWRITE_TAC[HULL_SUBSET] THEN
841 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
842 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[AFFINE_HYPERPLANE] THEN
845 [RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_ELIM_THM]) THEN
846 ASM_SIMP_TAC[real_ge; REAL_LE_REFL];
847 AP_TERM_TAC THEN ASM SET_TAC[]]];
849 RULE_ASSUM_TAC(REWRITE_RULE[AFFINE_HULL_CONVEX_HULL]) THEN
851 `aff_dim(t:real^3->bool)
852 <= aff_dim(({x:real^3 | a dot x = b} INTER {x:real^3 | a' dot x = b'})
853 INTER {x | n dot x = d})`
855 [GEN_REWRITE_TAC LAND_CONV [GSYM AFF_DIM_AFFINE_HULL] THEN
856 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV)
858 REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN MATCH_MP_TAC AFF_DIM_SUBSET THEN
859 REWRITE_TAC[SUBSET_INTER; INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM] THEN
861 SUBGOAL_THEN `(x:real^3) IN convex hull t /\ y IN convex hull t`
863 [CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[];
866 ASM_SIMP_TAC[AFF_DIM_AFFINE_INTER_HYPERPLANE; AFF_DIM_HYPERPLANE;
867 AFFINE_HYPERPLANE; DIMINDEX_3; AFFINE_INTER] THEN
868 ASM_CASES_TAC `{x:real^3 | a dot x = b} SUBSET {v | a' dot v = b'}` THEN
869 ASM_REWRITE_TAC[] THENL
871 REPEAT(COND_CASES_TAC THEN CONV_TAC INT_REDUCE_CONV) THEN
872 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
873 `s INTER t SUBSET u ==> !x. x IN s /\ x IN t ==> x IN u`)) THEN
874 DISCH_THEN(MP_TAC o SPEC `x + n:real^3`) THEN
875 MATCH_MP_TAC(TAUT `p /\ q /\ ~r ==> (p /\ q ==> r) ==> s`) THEN
876 ASM_SIMP_TAC[IN_ELIM_THM; DOT_RADD] THEN REPEAT CONJ_TAC THENL
877 [EXPAND_TAC "a" THEN VEC3_TAC;
879 ASM_REWRITE_TAC[REAL_EQ_ADD_LCANCEL_0; DOT_EQ_0]] THEN
880 SUBGOAL_THEN `a' dot (x:real^3) = b'` SUBST1_TAC THENL
881 [SUBGOAL_THEN `(x:real^3) IN convex hull t` MP_TAC THENL
882 [MATCH_MP_TAC HULL_INC THEN ASM SET_TAC[]; ASM SET_TAC[]];
884 SUBGOAL_THEN `(n:real^3) dot (x + a') = n dot x` MP_TAC THENL
886 SIMP_TAC[DOT_RADD] THEN REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC] THEN
887 MATCH_MP_TAC(REAL_ARITH `x:real = d /\ y = d ==> x = y`) THEN
889 `affine hull s SUBSET {x:real^3 | n dot x = d}`
891 [MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[AFFINE_HYPERPLANE] THEN
892 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM];
893 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_SIMP_TAC[HULL_INC]]] THEN
894 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_HYPERPLANES]) THEN
895 ASM_REWRITE_TAC[HYPERPLANE_EQ_EMPTY; HYPERPLANE_EQ_UNIV] THEN
896 DISCH_THEN(fun th -> DISCH_THEN(K ALL_TAC) THEN MP_TAC(SYM th)) THEN
897 DISCH_THEN(fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th) THEN
899 [MATCH_MP_TAC(TAUT `(~p /\ ~q ==> F) ==> p \/ q`) THEN
900 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; real_ge; REAL_NOT_LE] THEN
901 DISCH_THEN(CONJUNCTS_THEN2
902 (X_CHOOSE_TAC `u:real^3`) (X_CHOOSE_TAC `v:real^3`)) THEN
903 SUBGOAL_THEN `(a':real^3) dot u < b' /\ a' dot v < b'` ASSUME_TAC THENL
904 [REWRITE_TAC[REAL_LT_LE] THEN REWRITE_TAC
905 [SET_RULE `f x <= b /\ ~(f x = b) <=>
906 x IN {x | f x <= b} /\ ~(x IN {x | f x = b})`] THEN
907 ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[IN_ELIM_THM; REAL_LT_IMP_NE] THEN
908 SUBGOAL_THEN `(u:real^3) IN convex hull s /\ v IN convex hull s`
909 MP_TAC THENL [ASM_SIMP_TAC[HULL_INC]; ASM SET_TAC[]];
911 SUBGOAL_THEN `?w:real^3. w IN segment[u,v] /\ w IN {w | a' dot w = b'}`
913 [ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_ELIM_THM] THEN
914 MATCH_MP_TAC CONNECTED_IVT_HYPERPLANE THEN
915 MAP_EVERY EXISTS_TAC [`v:real^3`; `u:real^3`] THEN
916 ASM_SIMP_TAC[ENDS_IN_SEGMENT; CONNECTED_SEGMENT; REAL_LT_IMP_LE];
917 REWRITE_TAC[IN_SEGMENT; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN
918 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
919 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM] THEN
920 REWRITE_TAC[UNWIND_THM2; DOT_RADD; DOT_RMUL; CONJ_ASSOC] THEN
921 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN
922 MATCH_MP_TAC(REAL_ARITH `a < b ==> a = b ==> F`) THEN
923 MATCH_MP_TAC REAL_CONVEX_BOUND_LT THEN ASM_REAL_ARITH_TAC];
924 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
925 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
926 [MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET_INTER] THEN
927 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
928 EXISTS_TAC `convex hull t:real^3->bool` THEN
929 REWRITE_TAC[HULL_SUBSET] THEN ASM SET_TAC[];
930 ASM_REWRITE_TAC[SUBSET_INTER] THEN
931 SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN
932 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
933 EXISTS_TAC `convex hull {x:real^3 | a dot x = b}` THEN
934 SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN
935 MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN
936 REWRITE_TAC[CONVEX_HULL_EQ; CONVEX_HYPERPLANE]]];
937 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
938 MAP_EVERY X_GEN_TAC [`x:real^3`; `y:real^3`] THEN
940 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN CONJ_TAC THENL
941 [ASM_REWRITE_TAC[] THEN
943 `convex hull (s INTER {x:real^3 | a dot x = b}) =
944 (convex hull s) INTER {x | a dot x = b}`
946 [MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
947 [SIMP_TAC[SUBSET_INTER; HULL_MONO; INTER_SUBSET] THEN
948 MATCH_MP_TAC SUBSET_TRANS THEN
949 EXISTS_TAC `convex hull {x:real^3 | a dot x = b}` THEN
950 SIMP_TAC[HULL_MONO; INTER_SUBSET] THEN
951 MATCH_MP_TAC(SET_RULE `s = t ==> s SUBSET t`) THEN
952 REWRITE_TAC[CONVEX_HULL_EQ; CONVEX_HYPERPLANE];
954 ASM_CASES_TAC `s SUBSET {x:real^3 | a dot x = b}` THENL
955 [ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER t = s`] THEN SET_TAC[];
957 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC
958 `convex hull (convex hull (s INTER {x:real^3 | a dot x = b}) UNION
959 convex hull (s DIFF {x | a dot x = b})) INTER
960 {x | a dot x = b}` THEN
962 [MATCH_MP_TAC(SET_RULE
963 `s SUBSET t ==> (s INTER u) SUBSET (t INTER u)`) THEN
964 MATCH_MP_TAC HULL_MONO THEN MATCH_MP_TAC(SET_RULE
965 `s INTER t SUBSET (P hull (s INTER t)) /\
966 s DIFF t SUBSET (P hull (s DIFF t))
967 ==> s SUBSET (P hull (s INTER t)) UNION (P hull (s DIFF t))`) THEN
968 REWRITE_TAC[HULL_SUBSET];
970 W(MP_TAC o PART_MATCH (lhs o rand) CONVEX_HULL_UNION_NONEMPTY_EXPLICIT o
971 lhand o lhand o snd) THEN
973 [SIMP_TAC[CONVEX_CONVEX_HULL; CONVEX_HULL_EQ_EMPTY] THEN ASM SET_TAC[];
974 DISCH_THEN SUBST1_TAC] THEN
975 REWRITE_TAC[SUBSET; IN_INTER; IMP_CONJ; FORALL_IN_GSPEC] THEN
976 MAP_EVERY X_GEN_TAC [`p:real^3`; `u:real`; `q:real^3`] THEN
977 REPLICATE_TAC 4 DISCH_TAC THEN ASM_CASES_TAC `u = &0` THEN
978 ASM_REWRITE_TAC[VECTOR_ARITH `(&1 - &0) % p + &0 % q:real^N = p`] THEN
979 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN REWRITE_TAC[IN_ELIM_THM] THEN
980 REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN FIRST_X_ASSUM DISJ_CASES_TAC THENL
981 [MATCH_MP_TAC(REAL_ARITH `x < y ==> ~(x = y)`) THEN
982 MATCH_MP_TAC(REAL_ARITH
983 `(&1 - u) * p = (&1 - u) * b /\ u * q < u * b
984 ==> (&1 - u) * p + u * q < b`) THEN
986 [SUBGOAL_THEN `p IN {x:real^3 | a dot x = b}` MP_TAC THENL
987 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
988 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
989 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HYPERPLANE] THEN
991 SIMP_TAC[IN_ELIM_THM]];
992 MATCH_MP_TAC REAL_LT_LMUL THEN CONJ_TAC THENL
993 [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
994 ONCE_REWRITE_TAC[SET_RULE
995 `(a:real^3) dot q < b <=> q IN {x | a dot x < b}`] THEN
996 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
997 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
998 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_LT] THEN
999 ASM_SIMP_TAC[SUBSET; IN_DIFF; IN_ELIM_THM; REAL_LT_LE]];
1000 MATCH_MP_TAC(REAL_ARITH `x > y ==> ~(x = y)`) THEN
1001 MATCH_MP_TAC(REAL_ARITH
1002 `(&1 - u) * p = (&1 - u) * b /\ u * b < u * q
1003 ==> (&1 - u) * p + u * q > b`) THEN
1005 [SUBGOAL_THEN `p IN {x:real^3 | a dot x = b}` MP_TAC THENL
1006 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
1007 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
1008 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HYPERPLANE] THEN
1010 SIMP_TAC[IN_ELIM_THM]];
1011 MATCH_MP_TAC REAL_LT_LMUL THEN CONJ_TAC THENL
1012 [ASM_REAL_ARITH_TAC; REWRITE_TAC[GSYM real_gt]] THEN
1013 ONCE_REWRITE_TAC[SET_RULE
1014 `(a:real^3) dot q > b <=> q IN {x | a dot x > b}`] THEN
1015 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
1016 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
1017 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_GT] THEN
1018 RULE_ASSUM_TAC(REWRITE_RULE[real_ge]) THEN
1019 ASM_SIMP_TAC[SUBSET; IN_DIFF; IN_ELIM_THM; real_gt; REAL_LT_LE]]];
1021 FIRST_X_ASSUM DISJ_CASES_TAC THENL
1022 [MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN
1023 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN
1024 SIMP_TAC[SET_RULE `(!x. x IN s ==> P x) <=> s SUBSET {x | P x}`] THEN
1025 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_LE] THEN
1026 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM];
1027 MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_GE THEN
1028 REWRITE_TAC[CONVEX_CONVEX_HULL] THEN
1029 SIMP_TAC[SET_RULE `(!x. x IN s ==> P x) <=> s SUBSET {x | P x}`] THEN
1030 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[CONVEX_HALFSPACE_GE] THEN
1031 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM]];
1032 ASM_REWRITE_TAC[GSYM INT_LE_ANTISYM] THEN CONJ_TAC THENL
1034 MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim{x:real^3,y}` THEN
1036 [ASM_REWRITE_TAC[AFF_DIM_2] THEN
1037 ASM_MESON_TAC[CROSS_0; VECTOR_SUB_REFL; INT_LE_REFL];
1038 MATCH_MP_TAC AFF_DIM_SUBSET THEN
1039 REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET] THEN
1040 CONJ_TAC THEN MATCH_MP_TAC HULL_INC THEN
1041 ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
1042 MAP_EVERY UNDISCH_TAC
1043 [`n cross (y - x) = a`; `(a:real^3) dot x = b`] THEN
1045 REWRITE_TAC[AFF_DIM_CONVEX_HULL] THEN MATCH_MP_TAC INT_LE_TRANS THEN
1047 `aff_dim({x:real^3 | a dot x = b} INTER {x | n dot x = d})` THEN
1049 [MATCH_MP_TAC AFF_DIM_SUBSET THEN ASM SET_TAC[]; ALL_TAC] THEN
1050 ASM_SIMP_TAC[AFF_DIM_AFFINE_INTER_HYPERPLANE; AFFINE_HYPERPLANE;
1051 AFF_DIM_HYPERPLANE; DIMINDEX_3] THEN
1052 REPEAT(COND_CASES_TAC THEN CONV_TAC INT_REDUCE_CONV) THEN
1053 FIRST_X_ASSUM(MP_TAC o SPEC `x + n:real^3` o
1054 GEN_REWRITE_RULE I [SUBSET]) THEN
1055 ASM_SIMP_TAC[IN_ELIM_THM; DOT_RADD; REAL_EQ_ADD_LCANCEL_0; DOT_EQ_0] THEN
1056 EXPAND_TAC "a" THEN VEC3_TAC]]);;
1058 (* ------------------------------------------------------------------------- *)
1059 (* Given a coplanar set, return exhaustive edge case theorem. *)
1060 (* ------------------------------------------------------------------------- *)
1062 let COMPUTE_EDGES_CONV =
1064 (`(x INSERT s) INTER {x | P x} =
1065 if P x then x INSERT (s INTER {x | P x})
1066 else s INTER {x | P x}`,
1067 COND_CASES_TAC THEN ASM SET_TAC[]) in
1069 let th1 = MATCH_MP COMPUTE_FACES_1 (COPLANAR_HYPERPLANE_RULE tm) in
1070 let th2 = MP (CONV_RULE(LAND_CONV
1071 (COMB2_CONV (RAND_CONV(PURE_REWRITE_CONV[FINITE_INSERT; FINITE_EMPTY]))
1072 (RAND_CONV VECTOR3_EQ_0_CONV THENC
1073 GEN_REWRITE_CONV I [NOT_CLAUSES]) THENC
1074 GEN_REWRITE_CONV I [AND_CLAUSES])) th1) TRUTH in
1076 (BINDER_CONV(RAND_CONV
1077 (REWRITE_CONV[RIGHT_EXISTS_AND_THM] THENC
1078 REWRITE_CONV[EXISTS_IN_INSERT; NOT_IN_EMPTY] THENC
1079 REWRITE_CONV[FORALL_IN_INSERT; NOT_IN_EMPTY] THENC
1080 ONCE_DEPTH_CONV VECTOR3_SUB_CONV THENC
1081 ONCE_DEPTH_CONV VECTOR3_CROSS_CONV THENC
1082 ONCE_DEPTH_CONV let_CONV THENC
1083 ONCE_DEPTH_CONV VECTOR3_EQ_0_CONV THENC
1084 REWRITE_CONV[real_ge] THENC
1085 ONCE_DEPTH_CONV VECTOR3_DOT_CONV THENC
1086 ONCE_DEPTH_CONV let_CONV THENC
1087 ONCE_DEPTH_CONV REAL_RAT5_LE_CONV THENC
1088 REWRITE_CONV[INSERT_AC] THENC REWRITE_CONV[DISJ_ACI] THENC
1089 REPEATC(CHANGED_CONV
1090 (ONCE_REWRITE_CONV[lemma] THENC
1091 ONCE_DEPTH_CONV(LAND_CONV VECTOR3_DOT_CONV THENC
1092 REAL_RAT5_EQ_CONV) THENC
1093 REWRITE_CONV[])) THENC
1094 REWRITE_CONV[INTER_EMPTY] THENC
1095 REWRITE_CONV[INSERT_AC] THENC REWRITE_CONV[DISJ_ACI]
1098 (* ------------------------------------------------------------------------- *)
1099 (* Use this to prove the number of edges per face for each Platonic solid. *)
1100 (* ------------------------------------------------------------------------- *)
1102 let CARD_EQ_LEMMA = prove
1103 (`!x s n. 0 < n /\ ~(x IN s) /\ s HAS_SIZE (n - 1)
1104 ==> (x INSERT s) HAS_SIZE n`,
1105 REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN
1106 ASM_SIMP_TAC[CARD_CLAUSES; FINITE_INSERT] THEN ASM_ARITH_TAC);;
1108 let EDGES_PER_FACE_TAC th =
1109 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
1110 EXISTS_TAC `CARD {e:real^3->bool | e face_of f /\ aff_dim(e) = &1}` THEN
1112 [AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
1113 REWRITE_TAC[IN_ELIM_THM] THEN
1114 ASM_MESON_TAC[FACE_OF_FACE; FACE_OF_TRANS; FACE_OF_IMP_SUBSET];
1116 MP_TAC(ISPEC `f:real^3->bool` th) THEN ASM_REWRITE_TAC[] THEN
1117 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN SUBST1_TAC) THEN
1118 W(fun (_,w) -> REWRITE_TAC[COMPUTE_EDGES_CONV(find_term is_setenum w)]) THEN
1119 REWRITE_TAC[SET_RULE `x = a \/ x = b <=> x IN {a,b}`] THEN
1120 REWRITE_TAC[GSYM IN_INSERT; SET_RULE `{x | x IN s} = s`] THEN
1121 REWRITE_TAC[GSYM SEGMENT_CONVEX_HULL] THEN MATCH_MP_TAC
1122 (MESON[HAS_SIZE] `s HAS_SIZE n ==> CARD s = n`) THEN
1124 (MATCH_MP_TAC CARD_EQ_LEMMA THEN REPEAT CONJ_TAC THENL
1125 [CONV_TAC NUM_REDUCE_CONV THEN NO_TAC;
1126 REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; SEGMENT_EQ; DE_MORGAN_THM] THEN
1127 REPEAT CONJ_TAC THEN MATCH_MP_TAC(SET_RULE
1128 `~(a = c /\ b = d) /\ ~(a = d /\ b = c) /\ ~(a = b /\ c = d)
1129 ==> ~({a,b} = {c,d})`) THEN
1130 PURE_ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
1131 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_SUB_CONV) THEN
1132 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_EQ_0_CONV) THEN
1133 REWRITE_TAC[] THEN NO_TAC;
1135 CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[CONJUNCT1 HAS_SIZE_CLAUSES];;
1137 let TETRAHEDRON_EDGES_PER_FACE = prove
1138 (`!f. f face_of std_tetrahedron /\ aff_dim(f) = &2
1139 ==> CARD {e | e face_of std_tetrahedron /\ aff_dim(e) = &1 /\
1141 EDGES_PER_FACE_TAC TETRAHEDRON_FACETS);;
1143 let CUBE_EDGES_PER_FACE = prove
1144 (`!f. f face_of std_cube /\ aff_dim(f) = &2
1145 ==> CARD {e | e face_of std_cube /\ aff_dim(e) = &1 /\
1147 EDGES_PER_FACE_TAC CUBE_FACETS);;
1149 let OCTAHEDRON_EDGES_PER_FACE = prove
1150 (`!f. f face_of std_octahedron /\ aff_dim(f) = &2
1151 ==> CARD {e | e face_of std_octahedron /\ aff_dim(e) = &1 /\
1153 EDGES_PER_FACE_TAC OCTAHEDRON_FACETS);;
1155 let DODECAHEDRON_EDGES_PER_FACE = prove
1156 (`!f. f face_of std_dodecahedron /\ aff_dim(f) = &2
1157 ==> CARD {e | e face_of std_dodecahedron /\ aff_dim(e) = &1 /\
1159 EDGES_PER_FACE_TAC DODECAHEDRON_FACETS);;
1161 let ICOSAHEDRON_EDGES_PER_FACE = prove
1162 (`!f. f face_of std_icosahedron /\ aff_dim(f) = &2
1163 ==> CARD {e | e face_of std_icosahedron /\ aff_dim(e) = &1 /\
1165 EDGES_PER_FACE_TAC ICOSAHEDRON_FACETS);;
1167 (* ------------------------------------------------------------------------- *)
1168 (* Show that the Platonic solids are all full-dimensional. *)
1169 (* ------------------------------------------------------------------------- *)
1171 let POLYTOPE_3D_LEMMA = prove
1172 (`(let a = (z - x) cross (y - x) in
1173 ~(a = vec 0) /\ ?w. w IN s /\ ~(a dot w = a dot x))
1174 ==> aff_dim(convex hull (x INSERT y INSERT z INSERT s:real^3->bool)) = &3`,
1175 REPEAT GEN_TAC THEN LET_TAC THEN STRIP_TAC THEN
1176 REWRITE_TAC[GSYM INT_LE_ANTISYM] THEN CONJ_TAC THENL
1177 [REWRITE_TAC[GSYM DIMINDEX_3; AFF_DIM_LE_UNIV]; ALL_TAC] THEN
1178 REWRITE_TAC[AFF_DIM_CONVEX_HULL] THEN MATCH_MP_TAC INT_LE_TRANS THEN
1179 EXISTS_TAC `aff_dim {w:real^3,x,y,z}` THEN CONJ_TAC THENL
1180 [ALL_TAC; MATCH_MP_TAC AFF_DIM_SUBSET THEN ASM SET_TAC[]] THEN
1181 ONCE_REWRITE_TAC[AFF_DIM_INSERT] THEN COND_CASES_TAC THENL
1182 [SUBGOAL_THEN `w IN {w:real^3 | a dot w = a dot x}` MP_TAC THENL
1183 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
1184 `x IN s ==> s SUBSET t ==> x IN t`)) THEN
1185 MATCH_MP_TAC HULL_MINIMAL THEN REWRITE_TAC[AFFINE_HYPERPLANE] THEN
1186 REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; IN_ELIM_THM] THEN
1187 UNDISCH_TAC `~(a:real^3 = vec 0)` THEN EXPAND_TAC "a" THEN VEC3_TAC;
1188 ASM_REWRITE_TAC[IN_ELIM_THM]];
1189 UNDISCH_TAC `~(a:real^3 = vec 0)` THEN EXPAND_TAC "a" THEN
1190 REWRITE_TAC[CROSS_EQ_0; GSYM COLLINEAR_3] THEN
1191 REWRITE_TAC[COLLINEAR_3_EQ_AFFINE_DEPENDENT; INSERT_AC; DE_MORGAN_THM] THEN
1192 STRIP_TAC THEN ASM_SIMP_TAC[AFF_DIM_AFFINE_INDEPENDENT] THEN
1193 SIMP_TAC[CARD_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
1194 ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; ARITH] THEN INT_ARITH_TAC]);;
1196 let POLYTOPE_FULLDIM_TAC =
1197 MATCH_MP_TAC POLYTOPE_3D_LEMMA THEN
1198 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_SUB_CONV) THEN
1199 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_CROSS_CONV) THEN
1200 CONV_TAC(ONCE_DEPTH_CONV let_CONV) THEN CONJ_TAC THENL
1201 [CONV_TAC(RAND_CONV VECTOR3_EQ_0_CONV) THEN REWRITE_TAC[];
1202 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_DOT_CONV) THEN
1203 REWRITE_TAC[EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN
1204 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_DOT_CONV) THEN
1205 CONV_TAC(ONCE_DEPTH_CONV REAL_RAT5_EQ_CONV) THEN
1208 let STD_TETRAHEDRON_FULLDIM = prove
1209 (`aff_dim std_tetrahedron = &3`,
1210 REWRITE_TAC[std_tetrahedron] THEN POLYTOPE_FULLDIM_TAC);;
1212 let STD_CUBE_FULLDIM = prove
1213 (`aff_dim std_cube = &3`,
1214 REWRITE_TAC[std_cube] THEN POLYTOPE_FULLDIM_TAC);;
1216 let STD_OCTAHEDRON_FULLDIM = prove
1217 (`aff_dim std_octahedron = &3`,
1218 REWRITE_TAC[std_octahedron] THEN POLYTOPE_FULLDIM_TAC);;
1220 let STD_DODECAHEDRON_FULLDIM = prove
1221 (`aff_dim std_dodecahedron = &3`,
1222 REWRITE_TAC[STD_DODECAHEDRON] THEN POLYTOPE_FULLDIM_TAC);;
1224 let STD_ICOSAHEDRON_FULLDIM = prove
1225 (`aff_dim std_icosahedron = &3`,
1226 REWRITE_TAC[STD_ICOSAHEDRON] THEN POLYTOPE_FULLDIM_TAC);;
1228 (* ------------------------------------------------------------------------- *)
1229 (* Complete list of edges for each Platonic solid. *)
1230 (* ------------------------------------------------------------------------- *)
1232 let COMPUTE_EDGES_TAC defn fulldim facets =
1233 GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
1235 (vsubst[lhs(concl defn),`p:real^3->bool`]
1236 `?f:real^3->bool. (f face_of p /\ aff_dim f = &2) /\
1237 (e face_of f /\ aff_dim e = &1)`) THEN
1239 [EQ_TAC THENL [STRIP_TAC; MESON_TAC[FACE_OF_TRANS]] THEN
1240 MP_TAC(ISPECL [lhs(concl defn); `e:real^3->bool`]
1241 FACE_OF_POLYHEDRON_SUBSET_FACET) THEN
1243 [ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1244 [REWRITE_TAC[defn] THEN
1245 MATCH_MP_TAC POLYHEDRON_CONVEX_HULL THEN
1246 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1248 DISCH_THEN(MP_TAC o AP_TERM `aff_dim:(real^3->bool)->int`) THEN
1249 ASM_REWRITE_TAC[fulldim; AFF_DIM_EMPTY] THEN
1250 CONV_TAC INT_REDUCE_CONV];
1251 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[facet_of] THEN
1252 REWRITE_TAC[fulldim] THEN CONV_TAC INT_REDUCE_CONV THEN
1253 ASM_MESON_TAC[FACE_OF_FACE]];
1254 REWRITE_TAC[facets] THEN
1255 REWRITE_TAC[TAUT `(a \/ b) /\ c <=> a /\ c \/ b /\ c`] THEN
1256 REWRITE_TAC[EXISTS_OR_THM; UNWIND_THM2] THEN
1257 CONV_TAC(LAND_CONV(DEPTH_BINOP_CONV `\/`
1258 (fun tm -> REWR_CONV (COMPUTE_EDGES_CONV(rand(rand(lhand tm)))) tm))) THEN
1259 REWRITE_TAC[INSERT_AC] THEN REWRITE_TAC[DISJ_ACI]];;
1261 let TETRAHEDRON_EDGES = prove
1262 (`!e. e face_of std_tetrahedron /\ aff_dim e = &1 <=>
1263 e = convex hull {vector[-- &1; -- &1; &1], vector[-- &1; &1; -- &1]} \/
1264 e = convex hull {vector[-- &1; -- &1; &1], vector[&1; -- &1; -- &1]} \/
1265 e = convex hull {vector[-- &1; -- &1; &1], vector[&1; &1; &1]} \/
1266 e = convex hull {vector[-- &1; &1; -- &1], vector[&1; -- &1; -- &1]} \/
1267 e = convex hull {vector[-- &1; &1; -- &1], vector[&1; &1; &1]} \/
1268 e = convex hull {vector[&1; -- &1; -- &1], vector[&1; &1; &1]}`,
1270 std_tetrahedron STD_TETRAHEDRON_FULLDIM TETRAHEDRON_FACETS);;
1272 let CUBE_EDGES = prove
1273 (`!e. e face_of std_cube /\ aff_dim e = &1 <=>
1274 e = convex hull {vector[-- &1; -- &1; -- &1], vector[-- &1; -- &1; &1]} \/
1275 e = convex hull {vector[-- &1; -- &1; -- &1], vector[-- &1; &1; -- &1]} \/
1276 e = convex hull {vector[-- &1; -- &1; -- &1], vector[&1; -- &1; -- &1]} \/
1277 e = convex hull {vector[-- &1; -- &1; &1], vector[-- &1; &1; &1]} \/
1278 e = convex hull {vector[-- &1; -- &1; &1], vector[&1; -- &1; &1]} \/
1279 e = convex hull {vector[-- &1; &1; -- &1], vector[-- &1; &1; &1]} \/
1280 e = convex hull {vector[-- &1; &1; -- &1], vector[&1; &1; -- &1]} \/
1281 e = convex hull {vector[-- &1; &1; &1], vector[&1; &1; &1]} \/
1282 e = convex hull {vector[&1; -- &1; -- &1], vector[&1; -- &1; &1]} \/
1283 e = convex hull {vector[&1; -- &1; -- &1], vector[&1; &1; -- &1]} \/
1284 e = convex hull {vector[&1; -- &1; &1], vector[&1; &1; &1]} \/
1285 e = convex hull {vector[&1; &1; -- &1], vector[&1; &1; &1]}`,
1287 std_cube STD_CUBE_FULLDIM CUBE_FACETS);;
1289 let OCTAHEDRON_EDGES = prove
1290 (`!e. e face_of std_octahedron /\ aff_dim e = &1 <=>
1291 e = convex hull {vector[-- &1; &0; &0], vector[&0; -- &1; &0]} \/
1292 e = convex hull {vector[-- &1; &0; &0], vector[&0; &1; &0]} \/
1293 e = convex hull {vector[-- &1; &0; &0], vector[&0; &0; -- &1]} \/
1294 e = convex hull {vector[-- &1; &0; &0], vector[&0; &0; &1]} \/
1295 e = convex hull {vector[&1; &0; &0], vector[&0; -- &1; &0]} \/
1296 e = convex hull {vector[&1; &0; &0], vector[&0; &1; &0]} \/
1297 e = convex hull {vector[&1; &0; &0], vector[&0; &0; -- &1]} \/
1298 e = convex hull {vector[&1; &0; &0], vector[&0; &0; &1]} \/
1299 e = convex hull {vector[&0; -- &1; &0], vector[&0; &0; -- &1]} \/
1300 e = convex hull {vector[&0; -- &1; &0], vector[&0; &0; &1]} \/
1301 e = convex hull {vector[&0; &1; &0], vector[&0; &0; -- &1]} \/
1302 e = convex hull {vector[&0; &1; &0], vector[&0; &0; &1]}`,
1304 std_octahedron STD_OCTAHEDRON_FULLDIM OCTAHEDRON_FACETS);;
1306 let DODECAHEDRON_EDGES = prove
1307 (`!e. e face_of std_dodecahedron /\ aff_dim e = &1 <=>
1308 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)], vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1309 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)], vector[-- &1; -- &1; &1]} \/
1310 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)], vector[-- &1; &1; &1]} \/
1311 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)], vector[-- &1; -- &1; -- &1]} \/
1312 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)], vector[-- &1; &1; -- &1]} \/
1313 e = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1314 e = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&1; -- &1; -- &1]} \/
1315 e = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&1; -- &1; &1]} \/
1316 e = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1317 e = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&1; &1; -- &1]} \/
1318 e = convex hull {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&1; &1; &1]} \/
1319 e = convex hull {vector[&1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[-- &1; -- &1; -- &1]} \/
1320 e = convex hull {vector[&1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[-- &1; -- &1; &1]} \/
1321 e = convex hull {vector[&1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[-- &1; &1; -- &1]} \/
1322 e = convex hull {vector[&1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[-- &1; &1; &1]} \/
1323 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)], vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1324 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)], vector[&1; -- &1; &1]} \/
1325 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)], vector[&1; &1; &1]} \/
1326 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)], vector[&1; -- &1; -- &1]} \/
1327 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)], vector[&1; &1; -- &1]} \/
1328 e = convex hull {vector[-- &1; -- &1; -- &1], vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1329 e = convex hull {vector[-- &1; -- &1; &1], vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1330 e = convex hull {vector[-- &1; &1; -- &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1331 e = convex hull {vector[-- &1; &1; &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1332 e = convex hull {vector[&1; -- &1; -- &1], vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1333 e = convex hull {vector[&1; -- &1; &1], vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1334 e = convex hull {vector[&1; &1; -- &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1335 e = convex hull {vector[&1; &1; &1], vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1336 e = convex hull {vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)], vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1337 e = convex hull {vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)], vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]}`,
1339 STD_DODECAHEDRON STD_DODECAHEDRON_FULLDIM DODECAHEDRON_FACETS);;
1341 let ICOSAHEDRON_EDGES = prove
1342 (`!e. e face_of std_icosahedron /\ aff_dim e = &1 <=>
1343 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1], vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1]} \/
1344 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1], vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1345 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1], vector[-- &1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1346 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1347 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1348 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1], vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1349 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1], vector[-- &1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1350 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1351 e = convex hull {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1352 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1], vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1]} \/
1353 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1354 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1], vector[&1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1355 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1356 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1357 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1358 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1], vector[&1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1359 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1360 e = convex hull {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1361 e = convex hull {vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1362 e = convex hull {vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1363 e = convex hull {vector[-- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1364 e = convex hull {vector[-- &1; &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1365 e = convex hull {vector[-- &1; &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1366 e = convex hull {vector[-- &1; &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1367 e = convex hull {vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1368 e = convex hull {vector[&1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0], vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1369 e = convex hull {vector[&1; &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1370 e = convex hull {vector[&1; &1 / &2 + &1 / &2 * sqrt (&5); &0], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1371 e = convex hull {vector[&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)], vector[&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1372 e = convex hull {vector[&0; -- &1; &1 / &2 + &1 / &2 * sqrt (&5)], vector[&0; &1; &1 / &2 + &1 / &2 * sqrt (&5)]}`,
1374 STD_ICOSAHEDRON STD_ICOSAHEDRON_FULLDIM ICOSAHEDRON_FACETS);;
1376 (* ------------------------------------------------------------------------- *)
1377 (* Enumerate all the vertices. *)
1378 (* ------------------------------------------------------------------------- *)
1380 let COMPUTE_VERTICES_TAC defn fulldim edges =
1381 GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
1383 (vsubst[lhs(concl defn),`p:real^3->bool`]
1384 `?e:real^3->bool. (e face_of p /\ aff_dim e = &1) /\
1385 (v face_of e /\ aff_dim v = &0)`) THEN
1387 [EQ_TAC THENL [STRIP_TAC; MESON_TAC[FACE_OF_TRANS]] THEN
1388 MP_TAC(ISPECL [lhs(concl defn); `v:real^3->bool`]
1389 FACE_OF_POLYHEDRON_SUBSET_FACET) THEN
1391 [ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1392 [REWRITE_TAC[defn] THEN
1393 MATCH_MP_TAC POLYHEDRON_CONVEX_HULL THEN
1394 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1396 DISCH_THEN(MP_TAC o AP_TERM `aff_dim:(real^3->bool)->int`) THEN
1397 ASM_REWRITE_TAC[fulldim; AFF_DIM_EMPTY] THEN
1398 CONV_TAC INT_REDUCE_CONV];
1399 REWRITE_TAC[facet_of] THEN
1400 DISCH_THEN(X_CHOOSE_THEN `f:real^3->bool` STRIP_ASSUME_TAC)] THEN
1401 MP_TAC(ISPECL [`f:real^3->bool`; `v:real^3->bool`]
1402 FACE_OF_POLYHEDRON_SUBSET_FACET) THEN
1404 [REPEAT CONJ_TAC THENL
1405 [MATCH_MP_TAC FACE_OF_POLYHEDRON_POLYHEDRON THEN
1406 FIRST_ASSUM(fun th ->
1407 EXISTS_TAC (rand(concl th)) THEN
1408 CONJ_TAC THENL [ALL_TAC; ACCEPT_TAC th]) THEN
1409 REWRITE_TAC[defn] THEN
1410 MATCH_MP_TAC POLYHEDRON_CONVEX_HULL THEN
1411 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1412 ASM_MESON_TAC[FACE_OF_FACE];
1413 DISCH_THEN(MP_TAC o AP_TERM `aff_dim:(real^3->bool)->int`) THEN
1414 ASM_REWRITE_TAC[fulldim; AFF_DIM_EMPTY] THEN
1415 CONV_TAC INT_REDUCE_CONV;
1416 DISCH_THEN(MP_TAC o AP_TERM `aff_dim:(real^3->bool)->int`) THEN
1417 ASM_REWRITE_TAC[fulldim; AFF_DIM_EMPTY] THEN
1418 CONV_TAC INT_REDUCE_CONV];
1419 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[facet_of] THEN
1420 ASM_REWRITE_TAC[fulldim] THEN CONV_TAC INT_REDUCE_CONV THEN
1421 ASM_MESON_TAC[FACE_OF_FACE; FACE_OF_TRANS]];
1422 REWRITE_TAC[edges] THEN
1423 REWRITE_TAC[TAUT `(a \/ b) /\ c <=> a /\ c \/ b /\ c`] THEN
1424 REWRITE_TAC[EXISTS_OR_THM; UNWIND_THM2] THEN
1425 REWRITE_TAC[AFF_DIM_EQ_0; RIGHT_AND_EXISTS_THM] THEN
1426 ONCE_REWRITE_TAC[MESON[]
1427 `v face_of s /\ v = {a} <=> {a} face_of s /\ v = {a}`] THEN
1428 REWRITE_TAC[GSYM SEGMENT_CONVEX_HULL; FACE_OF_SING] THEN
1429 REWRITE_TAC[EXTREME_POINT_OF_SEGMENT] THEN
1430 REWRITE_TAC[TAUT `(a \/ b) /\ c <=> a /\ c \/ b /\ c`] THEN
1431 REWRITE_TAC[EXISTS_OR_THM; UNWIND_THM2] THEN
1432 REWRITE_TAC[DISJ_ACI]];;
1434 let TETRAHEDRON_VERTICES = prove
1435 (`!v. v face_of std_tetrahedron /\ aff_dim v = &0 <=>
1436 v = {vector [-- &1; -- &1; &1]} \/
1437 v = {vector [-- &1; &1; -- &1]} \/
1438 v = {vector [&1; -- &1; -- &1]} \/
1439 v = {vector [&1; &1; &1]}`,
1440 COMPUTE_VERTICES_TAC
1441 std_tetrahedron STD_TETRAHEDRON_FULLDIM TETRAHEDRON_EDGES);;
1443 let CUBE_VERTICES = prove
1444 (`!v. v face_of std_cube /\ aff_dim v = &0 <=>
1445 v = {vector [-- &1; -- &1; -- &1]} \/
1446 v = {vector [-- &1; -- &1; &1]} \/
1447 v = {vector [-- &1; &1; -- &1]} \/
1448 v = {vector [-- &1; &1; &1]} \/
1449 v = {vector [&1; -- &1; -- &1]} \/
1450 v = {vector [&1; -- &1; &1]} \/
1451 v = {vector [&1; &1; -- &1]} \/
1452 v = {vector [&1; &1; &1]}`,
1453 COMPUTE_VERTICES_TAC
1454 std_cube STD_CUBE_FULLDIM CUBE_EDGES);;
1456 let OCTAHEDRON_VERTICES = prove
1457 (`!v. v face_of std_octahedron /\ aff_dim v = &0 <=>
1458 v = {vector [-- &1; &0; &0]} \/
1459 v = {vector [&1; &0; &0]} \/
1460 v = {vector [&0; -- &1; &0]} \/
1461 v = {vector [&0; &1; &0]} \/
1462 v = {vector [&0; &0; -- &1]} \/
1463 v = {vector [&0; &0; &1]}`,
1464 COMPUTE_VERTICES_TAC
1465 std_octahedron STD_OCTAHEDRON_FULLDIM OCTAHEDRON_EDGES);;
1467 let DODECAHEDRON_VERTICES = prove
1468 (`!v. v face_of std_dodecahedron /\ aff_dim v = &0 <=>
1469 v = {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1470 v = {vector[-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1471 v = {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1472 v = {vector[-- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1473 v = {vector[&1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1474 v = {vector[&1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1475 v = {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1476 v = {vector[&1 / &2 + &1 / &2 * sqrt (&5); &0; &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1477 v = {vector[-- &1; -- &1; -- &1]} \/
1478 v = {vector[-- &1; -- &1; &1]} \/
1479 v = {vector[-- &1; &1; -- &1]} \/
1480 v = {vector[-- &1; &1; &1]} \/
1481 v = {vector[&1; -- &1; -- &1]} \/
1482 v = {vector[&1; -- &1; &1]} \/
1483 v = {vector[&1; &1; -- &1]} \/
1484 v = {vector[&1; &1; &1]} \/
1485 v = {vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1486 v = {vector[&0; -- &1 / &2 + &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1487 v = {vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1488 v = {vector[&0; &1 / &2 + -- &1 / &2 * sqrt (&5); &1 / &2 + &1 / &2 * sqrt (&5)]}`,
1489 COMPUTE_VERTICES_TAC
1490 STD_DODECAHEDRON STD_DODECAHEDRON_FULLDIM DODECAHEDRON_EDGES);;
1492 let ICOSAHEDRON_VERTICES = prove
1493 (`!v. v face_of std_icosahedron /\ aff_dim v = &0 <=>
1494 v = {vector [-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; -- &1]} \/
1495 v = {vector [-- &1 / &2 + -- &1 / &2 * sqrt (&5); &0; &1]} \/
1496 v = {vector [&1 / &2 + &1 / &2 * sqrt (&5); &0; -- &1]} \/
1497 v = {vector [&1 / &2 + &1 / &2 * sqrt (&5); &0; &1]} \/
1498 v = {vector [-- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1499 v = {vector [-- &1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1500 v = {vector [&1; -- &1 / &2 + -- &1 / &2 * sqrt (&5); &0]} \/
1501 v = {vector [&1; &1 / &2 + &1 / &2 * sqrt (&5); &0]} \/
1502 v = {vector [&0; -- &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1503 v = {vector [&0; -- &1; &1 / &2 + &1 / &2 * sqrt (&5)]} \/
1504 v = {vector [&0; &1; -- &1 / &2 + -- &1 / &2 * sqrt (&5)]} \/
1505 v = {vector [&0; &1; &1 / &2 + &1 / &2 * sqrt (&5)]}`,
1506 COMPUTE_VERTICES_TAC
1507 STD_ICOSAHEDRON STD_ICOSAHEDRON_FULLDIM ICOSAHEDRON_EDGES);;
1509 (* ------------------------------------------------------------------------- *)
1510 (* Number of edges meeting at each vertex. *)
1511 (* ------------------------------------------------------------------------- *)
1513 let EDGES_PER_VERTEX_TAC defn edges verts =
1514 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
1516 (vsubst[lhs(concl defn),`p:real^3->bool`]
1517 `CARD {e | (e face_of p /\ aff_dim(e) = &1) /\
1518 (v:real^3->bool) face_of e}`) THEN
1520 [AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
1521 ASM_MESON_TAC[FACE_OF_FACE];
1523 MP_TAC(ISPEC `v:real^3->bool` verts) THEN
1524 ASM_REWRITE_TAC[] THEN
1525 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN SUBST1_TAC) THEN
1526 REWRITE_TAC[edges] THEN
1527 REWRITE_TAC[SET_RULE
1528 `{e | (P e \/ Q e) /\ R e} =
1529 {e | P e /\ R e} UNION {e | Q e /\ R e}`] THEN
1530 REWRITE_TAC[MESON[FACE_OF_SING]
1531 `e = a /\ {x} face_of e <=> e = a /\ x extreme_point_of a`] THEN
1532 REWRITE_TAC[GSYM SEGMENT_CONVEX_HULL; EXTREME_POINT_OF_SEGMENT] THEN
1533 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
1534 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_SUB_CONV) THEN
1535 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_EQ_0_CONV) THEN
1536 REWRITE_TAC[EMPTY_GSPEC; UNION_EMPTY] THEN
1537 REWRITE_TAC[SET_RULE `{x | x = a} = {a}`] THEN
1538 REWRITE_TAC[SET_RULE `{x} UNION s = x INSERT s`] THEN MATCH_MP_TAC
1539 (MESON[HAS_SIZE] `s HAS_SIZE n ==> CARD s = n`) THEN
1541 (MATCH_MP_TAC CARD_EQ_LEMMA THEN REPEAT CONJ_TAC THENL
1542 [CONV_TAC NUM_REDUCE_CONV THEN NO_TAC;
1543 REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM; SEGMENT_EQ] THEN
1544 REPEAT CONJ_TAC THEN MATCH_MP_TAC(SET_RULE
1545 `~(a = c /\ b = d) /\ ~(a = d /\ b = c) /\ ~(a = b /\ c = d)
1546 ==> ~({a,b} = {c,d})`) THEN
1547 PURE_ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
1548 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_SUB_CONV) THEN
1549 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_EQ_0_CONV) THEN
1550 REWRITE_TAC[] THEN NO_TAC;
1552 CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[CONJUNCT1 HAS_SIZE_CLAUSES];;
1554 let TETRAHEDRON_EDGES_PER_VERTEX = prove
1555 (`!v. v face_of std_tetrahedron /\ aff_dim(v) = &0
1556 ==> CARD {e | e face_of std_tetrahedron /\ aff_dim(e) = &1 /\
1558 EDGES_PER_VERTEX_TAC
1559 std_tetrahedron TETRAHEDRON_EDGES TETRAHEDRON_VERTICES);;
1561 let CUBE_EDGES_PER_VERTEX = prove
1562 (`!v. v face_of std_cube /\ aff_dim(v) = &0
1563 ==> CARD {e | e face_of std_cube /\ aff_dim(e) = &1 /\
1565 EDGES_PER_VERTEX_TAC
1566 std_cube CUBE_EDGES CUBE_VERTICES);;
1568 let OCTAHEDRON_EDGES_PER_VERTEX = prove
1569 (`!v. v face_of std_octahedron /\ aff_dim(v) = &0
1570 ==> CARD {e | e face_of std_octahedron /\ aff_dim(e) = &1 /\
1572 EDGES_PER_VERTEX_TAC
1573 std_octahedron OCTAHEDRON_EDGES OCTAHEDRON_VERTICES);;
1575 let DODECAHEDRON_EDGES_PER_VERTEX = prove
1576 (`!v. v face_of std_dodecahedron /\ aff_dim(v) = &0
1577 ==> CARD {e | e face_of std_dodecahedron /\ aff_dim(e) = &1 /\
1579 EDGES_PER_VERTEX_TAC
1580 STD_DODECAHEDRON DODECAHEDRON_EDGES DODECAHEDRON_VERTICES);;
1582 let ICOSAHEDRON_EDGES_PER_VERTEX = prove
1583 (`!v. v face_of std_icosahedron /\ aff_dim(v) = &0
1584 ==> CARD {e | e face_of std_icosahedron /\ aff_dim(e) = &1 /\
1586 EDGES_PER_VERTEX_TAC
1587 STD_ICOSAHEDRON ICOSAHEDRON_EDGES ICOSAHEDRON_VERTICES);;
1589 (* ------------------------------------------------------------------------- *)
1590 (* Number of Platonic solids. *)
1591 (* ------------------------------------------------------------------------- *)
1593 let MULTIPLE_COUNTING_LEMMA = prove
1594 (`!R:A->B->bool s t.
1595 FINITE s /\ FINITE t /\
1596 (!x. x IN s ==> CARD {y | y IN t /\ R x y} = m) /\
1597 (!y. y IN t ==> CARD {x | x IN s /\ R x y} = n)
1598 ==> m * CARD s = n * CARD t`,
1599 REPEAT STRIP_TAC THEN
1600 MP_TAC(ISPECL [`R:A->B->bool`; `\x:A y:B. 1`; `s:A->bool`; `t:B->bool`]
1601 NSUM_NSUM_RESTRICT) THEN
1602 ASM_SIMP_TAC[NSUM_CONST; FINITE_RESTRICT] THEN ARITH_TAC);;
1604 let SIZE_ZERO_DIMENSIONAL_FACES = prove
1607 ==> CARD {f | f face_of s /\ aff_dim f = &0} =
1608 CARD {v | v extreme_point_of s} /\
1609 (FINITE {f | f face_of s /\ aff_dim f = &0} <=>
1610 FINITE {v | v extreme_point_of s}) /\
1611 (!n. {f | f face_of s /\ aff_dim f = &0} HAS_SIZE n <=>
1612 {v | v extreme_point_of s} HAS_SIZE n)`,
1613 REWRITE_TAC[RIGHT_AND_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
1614 SUBGOAL_THEN `{f | f face_of s /\ aff_dim f = &0} =
1615 IMAGE (\v:real^N. {v}) {v | v extreme_point_of s}`
1617 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
1618 REWRITE_TAC[AFF_DIM_SING; FACE_OF_SING; IN_ELIM_THM] THEN
1619 REWRITE_TAC[AFF_DIM_EQ_0] THEN MESON_TAC[];
1620 REPEAT STRIP_TAC THENL
1621 [MATCH_MP_TAC CARD_IMAGE_INJ;
1622 MATCH_MP_TAC FINITE_IMAGE_INJ_EQ;
1623 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ_EQ] THEN
1624 ASM_SIMP_TAC[FINITE_POLYHEDRON_EXTREME_POINTS] THEN SET_TAC[]]);;
1626 let PLATONIC_SOLIDS_LIMITS = prove
1627 (`!p:real^3->bool m n.
1628 polytope p /\ aff_dim p = &3 /\
1629 (!f. f face_of p /\ aff_dim(f) = &2
1630 ==> CARD {e | e face_of p /\ aff_dim(e) = &1 /\ e SUBSET f} = m) /\
1631 (!v. v face_of p /\ aff_dim(v) = &0
1632 ==> CARD {e | e face_of p /\ aff_dim(e) = &1 /\ v SUBSET e} = n)
1633 ==> m = 3 /\ n = 3 \/ // Tetrahedron
1634 m = 4 /\ n = 3 \/ // Cube
1635 m = 3 /\ n = 4 \/ // Octahedron
1636 m = 5 /\ n = 3 \/ // Dodecahedron
1637 m = 3 /\ n = 5 // Icosahedron`,
1638 REPEAT STRIP_TAC THEN
1639 MP_TAC(ISPEC `p:real^3->bool` EULER_RELATION) THEN
1640 ASM_REWRITE_TAC[] THEN
1642 `m * CARD {f:real^3->bool | f face_of p /\ aff_dim f = &2} =
1643 2 * CARD {e | e face_of p /\ aff_dim e = &1} /\
1644 n * CARD {v | v face_of p /\ aff_dim v = &0} =
1645 2 * CARD {e | e face_of p /\ aff_dim e = &1}`
1647 [CONJ_TAC THEN MATCH_MP_TAC MULTIPLE_COUNTING_LEMMA THENL
1648 [EXISTS_TAC `\(f:real^3->bool) (e:real^3->bool). e SUBSET f`;
1649 EXISTS_TAC `\(v:real^3->bool) (e:real^3->bool). v SUBSET e`] THEN
1650 ONCE_REWRITE_TAC[SET_RULE `f face_of s <=> f IN {f | f face_of s}`] THEN
1651 ASM_SIMP_TAC[FINITE_POLYTOPE_FACES; FINITE_RESTRICT] THEN
1652 ASM_REWRITE_TAC[IN_ELIM_THM; GSYM CONJ_ASSOC] THEN
1653 X_GEN_TAC `e:real^3->bool` THEN STRIP_TAC THENL
1654 [MP_TAC(ISPECL [`p:real^3->bool`; `e:real^3->bool`]
1655 POLYHEDRON_RIDGE_TWO_FACETS) THEN
1656 ASM_SIMP_TAC[POLYTOPE_IMP_POLYHEDRON] THEN ANTS_TAC THENL
1657 [CONV_TAC INT_REDUCE_CONV THEN DISCH_THEN SUBST_ALL_TAC THEN
1658 RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_EMPTY]) THEN ASM_INT_ARITH_TAC;
1659 CONV_TAC INT_REDUCE_CONV THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1660 MAP_EVERY X_GEN_TAC [`f1:real^3->bool`; `f2:real^3->bool`] THEN
1661 STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
1662 EXISTS_TAC `CARD {f1:real^3->bool,f2}` THEN CONJ_TAC THENL
1663 [AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
1664 REWRITE_TAC[IN_ELIM_THM; IN_INSERT; NOT_IN_EMPTY] THEN
1666 ASM_SIMP_TAC[CARD_CLAUSES; IN_INSERT; FINITE_RULES;
1667 NOT_IN_EMPTY; ARITH]]];
1668 SUBGOAL_THEN `?a b:real^3. e = segment[a,b]` STRIP_ASSUME_TAC THENL
1669 [MATCH_MP_TAC COMPACT_CONVEX_COLLINEAR_SEGMENT THEN
1670 REPEAT CONJ_TAC THENL
1671 [DISCH_THEN SUBST_ALL_TAC THEN
1672 RULE_ASSUM_TAC(REWRITE_RULE[AFF_DIM_EMPTY]) THEN ASM_INT_ARITH_TAC;
1673 MATCH_MP_TAC FACE_OF_IMP_COMPACT THEN
1674 EXISTS_TAC `p:real^3->bool` THEN
1675 ASM_SIMP_TAC[POLYTOPE_IMP_CONVEX; POLYTOPE_IMP_COMPACT];
1676 ASM_MESON_TAC[FACE_OF_IMP_CONVEX];
1677 MP_TAC(ISPEC `e:real^3->bool` AFF_DIM) THEN
1678 DISCH_THEN(X_CHOOSE_THEN `b:real^3->bool` MP_TAC) THEN
1679 ASM_REWRITE_TAC[INT_ARITH `&1:int = b - &1 <=> b = &2`] THEN
1680 DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) MP_TAC) THEN
1681 ASM_CASES_TAC `FINITE(b:real^3->bool)` THENL
1682 [ALL_TAC; ASM_MESON_TAC[AFFINE_INDEPENDENT_IMP_FINITE]] THEN
1683 REWRITE_TAC[INT_OF_NUM_EQ] THEN STRIP_TAC THEN
1684 SUBGOAL_THEN `(b:real^3->bool) HAS_SIZE 2` MP_TAC THENL
1685 [ASM_REWRITE_TAC[HAS_SIZE]; CONV_TAC(LAND_CONV HAS_SIZE_CONV)] THEN
1686 REWRITE_TAC[COLLINEAR_AFFINE_HULL] THEN
1687 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1688 ASM_MESON_TAC[HULL_SUBSET]];
1689 ASM_CASES_TAC `a:real^3 = b` THENL
1690 [UNDISCH_TAC `aff_dim(e:real^3->bool) = &1` THEN
1691 ASM_REWRITE_TAC[SEGMENT_REFL; AFF_DIM_SING; INT_OF_NUM_EQ; ARITH_EQ];
1693 MATCH_MP_TAC EQ_TRANS THEN
1694 EXISTS_TAC `CARD {v:real^3 | v extreme_point_of segment[a,b]}` THEN
1696 [MATCH_MP_TAC CARD_IMAGE_INJ_EQ THEN
1697 EXISTS_TAC `\v:real^3. {v}` THEN
1698 REWRITE_TAC[IN_ELIM_THM; FACE_OF_SING; AFF_DIM_SING] THEN
1699 REPEAT CONJ_TAC THENL
1700 [ASM_REWRITE_TAC[EXTREME_POINT_OF_SEGMENT] THEN
1701 REWRITE_TAC[SET_RULE `{x | x = a \/ x = b} = {a,b}`] THEN
1702 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1703 X_GEN_TAC `v:real^3` THEN REWRITE_TAC[GSYM FACE_OF_SING] THEN
1704 ASM_MESON_TAC[FACE_OF_TRANS; FACE_OF_IMP_SUBSET];
1705 X_GEN_TAC `s:real^3->bool` THEN REWRITE_TAC[AFF_DIM_EQ_0] THEN
1706 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1707 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
1708 DISCH_THEN(X_CHOOSE_THEN `v:real^3` SUBST_ALL_TAC) THEN
1709 REWRITE_TAC[EXISTS_UNIQUE] THEN EXISTS_TAC `v:real^3` THEN
1710 ASM_REWRITE_TAC[GSYM FACE_OF_SING] THEN CONJ_TAC THENL
1711 [ASM_MESON_TAC[FACE_OF_FACE]; SET_TAC[]]];
1712 ASM_REWRITE_TAC[EXTREME_POINT_OF_SEGMENT] THEN
1713 REWRITE_TAC[SET_RULE `{x | x = a \/ x = b} = {a,b}`] THEN
1714 ASM_SIMP_TAC[FINITE_INSERT; CARD_CLAUSES; FINITE_EMPTY] THEN
1715 ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; ARITH]]]];
1718 DISCH_THEN(ASSUME_TAC o MATCH_MP (ARITH_RULE
1719 `(a + b) - c = 2 ==> a + b = c + 2`)) THEN
1720 SUBGOAL_THEN `4 <= CARD {v:real^3->bool | v face_of p /\ aff_dim v = &0}`
1722 [ASM_SIMP_TAC[SIZE_ZERO_DIMENSIONAL_FACES; POLYTOPE_IMP_POLYHEDRON] THEN
1723 MP_TAC(ISPEC `p:real^3->bool` POLYTOPE_VERTEX_LOWER_BOUND) THEN
1724 ASM_REWRITE_TAC[] THEN CONV_TAC INT_REDUCE_CONV THEN
1725 REWRITE_TAC[INT_OF_NUM_LE];
1727 SUBGOAL_THEN `4 <= CARD {f:real^3->bool | f face_of p /\ aff_dim f = &2}`
1729 [MP_TAC(ISPEC `p:real^3->bool` POLYTOPE_FACET_LOWER_BOUND) THEN
1730 ASM_REWRITE_TAC[] THEN CONV_TAC INT_REDUCE_CONV THEN
1731 ASM_REWRITE_TAC[INT_OF_NUM_LE; facet_of] THEN
1732 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
1733 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN
1734 CONV_TAC INT_REDUCE_CONV THEN GEN_TAC THEN EQ_TAC THEN
1735 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1736 ASM_MESON_TAC[INT_ARITH `~(&2:int = -- &1)`; AFF_DIM_EMPTY];
1738 FIRST_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE
1739 `v + f = e + 2 ==> 4 <= v /\ 4 <= f ==> 6 <= e`)) THEN
1740 ASM_REWRITE_TAC[] THEN
1742 `CARD {e:real^3->bool | e face_of p /\ aff_dim e = &1} = 0` THEN
1743 ASM_REWRITE_TAC[ARITH] THEN DISCH_TAC THEN
1744 SUBGOAL_THEN `3 <= m` ASSUME_TAC THENL
1745 [ASM_CASES_TAC `{f:real^3->bool | f face_of p /\ aff_dim f = &2} = {}` THENL
1747 `4 <= CARD {f:real^3->bool | f face_of p /\ aff_dim f = &2}` THEN
1748 ASM_REWRITE_TAC[CARD_CLAUSES] THEN ARITH_TAC;
1749 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY])] THEN
1750 REWRITE_TAC[IN_ELIM_THM] THEN
1751 DISCH_THEN(X_CHOOSE_THEN `f:real^3->bool` MP_TAC) THEN
1752 DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN
1753 FIRST_X_ASSUM(SUBST1_TAC o SYM o C MATCH_MP th)) THEN
1754 MP_TAC(ISPEC `f:real^3->bool` POLYTOPE_FACET_LOWER_BOUND) THEN
1755 ASM_REWRITE_TAC[facet_of] THEN CONV_TAC INT_REDUCE_CONV THEN
1756 ANTS_TAC THENL [ASM_MESON_TAC[FACE_OF_POLYTOPE_POLYTOPE]; ALL_TAC] THEN
1757 REWRITE_TAC[INT_OF_NUM_LE] THEN MATCH_MP_TAC EQ_IMP THEN
1758 AP_TERM_TAC THEN AP_TERM_TAC THEN
1759 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM] THEN
1760 CONV_TAC INT_REDUCE_CONV THEN X_GEN_TAC `e:real^3->bool` THEN
1761 EQ_TAC THEN ASM_CASES_TAC `e:real^3->bool = {}` THEN
1762 ASM_SIMP_TAC[AFF_DIM_EMPTY] THEN CONV_TAC INT_REDUCE_CONV THENL
1763 [ASM_MESON_TAC[FACE_OF_TRANS; FACE_OF_IMP_SUBSET];
1764 ASM_MESON_TAC[FACE_OF_FACE]];
1766 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (ARITH_RULE `3 <= m ==> ~(m = 0)`)) THEN
1767 ASM_CASES_TAC `n = 0` THENL
1768 [UNDISCH_THEN `n = 0` SUBST_ALL_TAC THEN
1769 FIRST_X_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE
1770 `0 * x = 2 * e ==> e = 0`)) THEN ASM_REWRITE_TAC[];
1772 FIRST_ASSUM(MP_TAC o MATCH_MP (NUM_RING
1773 `v + f = e + 2 ==> !m n. m * n * v + n * m * f = m * n * (e + 2)`)) THEN
1774 DISCH_THEN(MP_TAC o SPECL [`m:num`; `n:num`]) THEN ASM_REWRITE_TAC[] THEN
1775 REWRITE_TAC[ARITH_RULE `m * 2 * e + n * 2 * e = m * n * (e + 2) <=>
1776 e * 2 * (m + n) = m * n * (e + 2)`] THEN
1777 ABBREV_TAC `E = CARD {e:real^3->bool | e face_of p /\ aff_dim e = &1}` THEN
1778 ASM_CASES_TAC `n = 1` THENL
1779 [ASM_REWRITE_TAC[MULT_CLAUSES; ARITH_RULE
1780 `E * 2 * (n + 1) = n * (E + 2) <=> E * (n + 2) = 2 * n`] THEN
1781 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
1782 MATCH_MP_TAC(ARITH_RULE `n:num < m ==> ~(m = n)`) THEN
1783 MATCH_MP_TAC LTE_TRANS THEN EXISTS_TAC `2 * (m + 2)` THEN
1784 CONJ_TAC THENL [ARITH_TAC; MATCH_MP_TAC LE_MULT2 THEN ASM_ARITH_TAC];
1786 ASM_CASES_TAC `n = 2` THENL
1787 [ASM_REWRITE_TAC[ARITH_RULE `E * 2 * (n + 2) = n * 2 * (E + 2) <=>
1789 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
1790 FIRST_X_ASSUM(MP_TAC o MATCH_MP (NUM_RING
1791 `E * c = 2 * E ==> E = 0 \/ c = 2`)) THEN
1794 SUBGOAL_THEN `3 <= n` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
1795 ASM_CASES_TAC `m * n < 2 * (m + n)` THENL
1797 DISCH_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[NOT_LT]) THEN
1798 SUBGOAL_THEN `E * 2 * (m + n) <= E * m * n` MP_TAC THENL
1799 [REWRITE_TAC[LE_MULT_LCANCEL] THEN ASM_ARITH_TAC;
1800 ASM_REWRITE_TAC[ARITH_RULE `m * n * (E + 2) <= E * m * n <=>
1801 2 * m * n = 0`] THEN
1802 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
1803 REWRITE_TAC[MULT_EQ_0] THEN ASM_ARITH_TAC]] THEN
1804 SUBGOAL_THEN `&m - &2:real < &4 /\ &n - &2 < &4` MP_TAC THENL
1806 [MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN EXISTS_TAC `&n - &2`;
1807 MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `&m - &2`] THEN
1808 ASM_SIMP_TAC[REAL_SUB_LT; REAL_OF_NUM_LT;
1809 ARITH_RULE `2 < n <=> 3 <= n`] THEN
1810 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&4` THEN
1811 REWRITE_TAC[REAL_ARITH `(m - &2) * (n - &2) < &4 <=>
1812 m * n < &2 * (m + n)`] THEN
1813 ASM_REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_ADD; REAL_OF_NUM_LT] THEN
1814 REWRITE_TAC[REAL_SUB_LDISTRIB; REAL_SUB_RDISTRIB; REAL_LE_SUB_LADD] THEN
1815 REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_ADD; REAL_OF_NUM_LE] THEN
1818 REWRITE_TAC[REAL_LT_SUB_RADD; REAL_OF_NUM_ADD; REAL_OF_NUM_LT] THEN
1819 REWRITE_TAC[ARITH_RULE `m < 4 + 2 <=> m <= 5`] THEN
1820 ASM_SIMP_TAC[ARITH_RULE
1821 `3 <= m ==> (m <= 5 <=> m = 3 \/ m = 4 \/ m = 5)`] THEN
1822 STRIP_TAC THEN UNDISCH_TAC `E * 2 * (m + n) = m * n * (E + 2)` THEN
1823 ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC);;
1825 (* ------------------------------------------------------------------------- *)
1826 (* If-and-only-if version. *)
1827 (* ------------------------------------------------------------------------- *)
1829 let PLATONIC_SOLIDS = prove
1832 polytope p /\ aff_dim p = &3 /\
1833 (!f. f face_of p /\ aff_dim(f) = &2
1834 ==> CARD {e | e face_of p /\ aff_dim(e) = &1 /\ e SUBSET f} = m) /\
1835 (!v. v face_of p /\ aff_dim(v) = &0
1836 ==> CARD {e | e face_of p /\ aff_dim(e) = &1 /\ v SUBSET e} = n)) <=>
1837 m = 3 /\ n = 3 \/ // Tetrahedron
1838 m = 4 /\ n = 3 \/ // Cube
1839 m = 3 /\ n = 4 \/ // Octahedron
1840 m = 5 /\ n = 3 \/ // Dodecahedron
1841 m = 3 /\ n = 5 // Icosahedron`,
1842 REPEAT GEN_TAC THEN EQ_TAC THEN
1843 REWRITE_TAC[LEFT_IMP_EXISTS_THM; PLATONIC_SOLIDS_LIMITS] THEN
1845 [EXISTS_TAC `std_tetrahedron` THEN
1846 ASM_REWRITE_TAC[TETRAHEDRON_EDGES_PER_VERTEX; TETRAHEDRON_EDGES_PER_FACE;
1847 STD_TETRAHEDRON_FULLDIM] THEN
1848 REWRITE_TAC[std_tetrahedron] THEN MATCH_MP_TAC POLYTOPE_CONVEX_HULL THEN
1849 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1850 EXISTS_TAC `std_cube` THEN
1851 ASM_REWRITE_TAC[CUBE_EDGES_PER_VERTEX; CUBE_EDGES_PER_FACE;
1852 STD_CUBE_FULLDIM] THEN
1853 REWRITE_TAC[std_cube] THEN MATCH_MP_TAC POLYTOPE_CONVEX_HULL THEN
1854 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1855 EXISTS_TAC `std_octahedron` THEN
1856 ASM_REWRITE_TAC[OCTAHEDRON_EDGES_PER_VERTEX; OCTAHEDRON_EDGES_PER_FACE;
1857 STD_OCTAHEDRON_FULLDIM] THEN
1858 REWRITE_TAC[std_octahedron] THEN MATCH_MP_TAC POLYTOPE_CONVEX_HULL THEN
1859 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1860 EXISTS_TAC `std_dodecahedron` THEN
1861 ASM_REWRITE_TAC[DODECAHEDRON_EDGES_PER_VERTEX; DODECAHEDRON_EDGES_PER_FACE;
1862 STD_DODECAHEDRON_FULLDIM] THEN
1863 REWRITE_TAC[STD_DODECAHEDRON] THEN MATCH_MP_TAC POLYTOPE_CONVEX_HULL THEN
1864 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY];
1865 EXISTS_TAC `std_icosahedron` THEN
1866 ASM_REWRITE_TAC[ICOSAHEDRON_EDGES_PER_VERTEX; ICOSAHEDRON_EDGES_PER_FACE;
1867 STD_ICOSAHEDRON_FULLDIM] THEN
1868 REWRITE_TAC[STD_ICOSAHEDRON] THEN MATCH_MP_TAC POLYTOPE_CONVEX_HULL THEN
1869 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY]]);;
1871 (* ------------------------------------------------------------------------- *)
1872 (* Show that the regular polyhedra do have all edges and faces congruent. *)
1873 (* ------------------------------------------------------------------------- *)
1875 parse_as_infix("congruent",(12,"right"));;
1877 let congruent = new_definition
1878 `(s:real^N->bool) congruent (t:real^N->bool) <=>
1879 ?c f. orthogonal_transformation f /\ t = IMAGE (\x. c + f x) s`;;
1881 let CONGRUENT_SIMPLE = prove
1882 (`(?A:real^3^3. orthogonal_matrix A /\ IMAGE (\x:real^3. A ** x) s = t)
1883 ==> (convex hull s) congruent (convex hull t)`,
1885 DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM))) THEN
1886 SIMP_TAC[CONVEX_HULL_LINEAR_IMAGE; MATRIX_VECTOR_MUL_LINEAR] THEN
1887 REWRITE_TAC[congruent] THEN EXISTS_TAC `vec 0:real^3` THEN
1888 EXISTS_TAC `\x:real^3. (A:real^3^3) ** x` THEN
1889 REWRITE_TAC[VECTOR_ADD_LID; ORTHOGONAL_TRANSFORMATION_MATRIX] THEN
1890 ASM_SIMP_TAC[MATRIX_OF_MATRIX_VECTOR_MUL; MATRIX_VECTOR_MUL_LINEAR]);;
1892 let CONGRUENT_SEGMENTS = prove
1894 dist(a,b) = dist(c,d)
1895 ==> segment[a,b] congruent segment[c,d]`,
1896 REPEAT STRIP_TAC THEN
1897 MP_TAC(ISPECL [`b - a:real^N`; `d - c:real^N`]
1898 ORTHOGONAL_TRANSFORMATION_EXISTS) THEN
1899 ANTS_TAC THENL [POP_ASSUM MP_TAC THEN NORM_ARITH_TAC; ALL_TAC] THEN
1900 DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` STRIP_ASSUME_TAC) THEN
1901 REWRITE_TAC[congruent] THEN
1902 EXISTS_TAC `c - (f:real^N->real^N) a` THEN
1903 EXISTS_TAC `f:real^N->real^N` THEN
1904 FIRST_ASSUM(ASSUME_TAC o MATCH_MP ORTHOGONAL_TRANSFORMATION_LINEAR) THEN
1906 `(\x. (c - f a) + (f:real^N->real^N) x) = (\x. (c - f a) + x) o f`
1907 SUBST1_TAC THENL [REWRITE_TAC[FUN_EQ_THM; o_THM]; ALL_TAC] THEN
1908 ASM_SIMP_TAC[GSYM CONVEX_HULL_LINEAR_IMAGE; SEGMENT_CONVEX_HULL; IMAGE_o;
1909 GSYM CONVEX_HULL_TRANSLATION] THEN
1910 REWRITE_TAC[IMAGE_CLAUSES] THEN
1911 AP_TERM_TAC THEN BINOP_TAC THENL
1912 [VECTOR_ARITH_TAC; AP_THM_TAC THEN AP_TERM_TAC] THEN
1913 REWRITE_TAC[VECTOR_ARITH `d:real^N = c - a + b <=> b - a = d - c`] THEN
1914 ASM_MESON_TAC[LINEAR_SUB]);;
1917 let mk_sub = mk_binop `(-):real^3->real^3->real^3`
1918 and dot_tm = `(dot):real^3->real^3->real` in
1919 fun v1 v2 -> let vth = VECTOR3_SUB_CONV(mk_sub v1 v2) in
1920 let dth = CONV_RULE(RAND_CONV VECTOR3_DOT_CONV)
1921 (MK_COMB(AP_TERM dot_tm vth,vth)) in
1925 let mk_le = mk_binop `(<=):real->real->bool` and t_tm = `T` in
1926 fun r1 r2 -> rand(concl(REAL_RAT5_LE_CONV(mk_le r1 r2))) = t_tm;;
1928 let three_adjacent_points s =
1930 | x::t -> let (y,_)::(z,_)::_ =
1931 sort (fun (_,r1) (_,r2) -> le_rat5 r1 r2)
1932 (map (fun y -> y,compute_dist x y) t) in
1934 | _ -> failwith "three_adjacent_points: no points";;
1937 let a11_tm = `a11:real`
1938 and a12_tm = `a12:real`
1939 and a13_tm = `a13:real`
1940 and a21_tm = `a21:real`
1941 and a22_tm = `a22:real`
1942 and a23_tm = `a23:real`
1943 and a31_tm = `a31:real`
1944 and a32_tm = `a32:real`
1945 and a33_tm = `a33:real`
1947 `vector[vector[a11; a12; a13];
1948 vector[a21; a22; a23];
1949 vector[a31; a32; a33]]:real^3^3` in
1950 fun [a11;a12;a13;a21;a22;a23;a31;a32;a33] ->
1959 a33,a33_tm] pat_tm;;
1961 let MATRIX_VECTOR_MUL_3 = prove
1962 (`(vector[vector[a11;a12;a13];
1963 vector[a21; a22; a23];
1964 vector[a31; a32; a33]]:real^3^3) **
1965 (vector[x1;x2;x3]:real^3) =
1966 vector[a11 * x1 + a12 * x2 + a13 * x3;
1967 a21 * x1 + a22 * x2 + a23 * x3;
1968 a31 * x1 + a32 * x2 + a33 * x3]`,
1969 SIMP_TAC[CART_EQ; matrix_vector_mul; LAMBDA_BETA] THEN
1970 REWRITE_TAC[DIMINDEX_3; FORALL_3; SUM_3; VECTOR_3]);;
1972 let MATRIX_LEMMA = prove
1977 (vector [x1; y1; z1]:real^3^3) ** (row 1 A:real^3) =
1978 vector [x2$1; y2$1; z2$1] /\
1979 (vector [x1; y1; z1]:real^3^3) ** (row 2 A:real^3) =
1980 vector [x2$2; y2$2; z2$2] /\
1981 (vector [x1; y1; z1]:real^3^3) ** (row 3 A:real^3) =
1982 vector [x2$3; y2$3; z2$3]`,
1983 SIMP_TAC[CART_EQ; transp; matrix_vector_mul; row; VECTOR_3; LAMBDA_BETA] THEN
1984 REWRITE_TAC[FORALL_3; DIMINDEX_3; VECTOR_3; SUM_3] THEN REAL_ARITH_TAC);;
1986 let MATRIX_BY_CRAMER_LEMMA = prove
1988 ~(det(vector[x1; y1; z1]:real^3^3) = &0)
1989 ==> (A ** x1 = x2 /\
1992 A = lambda m k. det((lambda i j.
1994 then (vector[x2$m; y2$m; z2$m]:real^3)$i
1995 else (vector[x1; y1; z1]:real^3^3)$i$j)
1997 det(vector[x1;y1;z1]:real^3^3))`,
1998 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [MATRIX_LEMMA] THEN
1999 ASM_SIMP_TAC[CRAMER] THEN REWRITE_TAC[CART_EQ; row] THEN
2000 SIMP_TAC[LAMBDA_BETA] THEN REWRITE_TAC[DIMINDEX_3; FORALL_3]);;
2002 let MATRIX_BY_CRAMER = prove
2003 (`!A:real^3^3 x1 y1 z1 x2 y2 z2.
2004 let d = det(vector[x1; y1; z1]:real^3^3) in
2006 ==> (A ** x1 = x2 /\
2010 (x2$1 * y1$2 * z1$3 +
2011 x1$2 * y1$3 * z2$1 +
2012 x1$3 * y2$1 * z1$2 -
2013 x2$1 * y1$3 * z1$2 -
2014 x1$2 * y2$1 * z1$3 -
2015 x1$3 * y1$2 * z2$1) / d /\
2017 (x1$1 * y2$1 * z1$3 +
2018 x2$1 * y1$3 * z1$1 +
2019 x1$3 * y1$1 * z2$1 -
2020 x1$1 * y1$3 * z2$1 -
2021 x2$1 * y1$1 * z1$3 -
2022 x1$3 * y2$1 * z1$1) / d /\
2024 (x1$1 * y1$2 * z2$1 +
2025 x1$2 * y2$1 * z1$1 +
2026 x2$1 * y1$1 * z1$2 -
2027 x1$1 * y2$1 * z1$2 -
2028 x1$2 * y1$1 * z2$1 -
2029 x2$1 * y1$2 * z1$1) / d /\
2031 (x2$2 * y1$2 * z1$3 +
2032 x1$2 * y1$3 * z2$2 +
2033 x1$3 * y2$2 * z1$2 -
2034 x2$2 * y1$3 * z1$2 -
2035 x1$2 * y2$2 * z1$3 -
2036 x1$3 * y1$2 * z2$2) / d /\
2038 (x1$1 * y2$2 * z1$3 +
2039 x2$2 * y1$3 * z1$1 +
2040 x1$3 * y1$1 * z2$2 -
2041 x1$1 * y1$3 * z2$2 -
2042 x2$2 * y1$1 * z1$3 -
2043 x1$3 * y2$2 * z1$1) / d /\
2045 (x1$1 * y1$2 * z2$2 +
2046 x1$2 * y2$2 * z1$1 +
2047 x2$2 * y1$1 * z1$2 -
2048 x1$1 * y2$2 * z1$2 -
2049 x1$2 * y1$1 * z2$2 -
2050 x2$2 * y1$2 * z1$1) / d /\
2052 (x2$3 * y1$2 * z1$3 +
2053 x1$2 * y1$3 * z2$3 +
2054 x1$3 * y2$3 * z1$2 -
2055 x2$3 * y1$3 * z1$2 -
2056 x1$2 * y2$3 * z1$3 -
2057 x1$3 * y1$2 * z2$3) / d /\
2059 (x1$1 * y2$3 * z1$3 +
2060 x2$3 * y1$3 * z1$1 +
2061 x1$3 * y1$1 * z2$3 -
2062 x1$1 * y1$3 * z2$3 -
2063 x2$3 * y1$1 * z1$3 -
2064 x1$3 * y2$3 * z1$1) / d /\
2066 (x1$1 * y1$2 * z2$3 +
2067 x1$2 * y2$3 * z1$1 +
2068 x2$3 * y1$1 * z1$2 -
2069 x1$1 * y2$3 * z1$2 -
2070 x1$2 * y1$1 * z2$3 -
2071 x2$3 * y1$2 * z1$1) / d)`,
2072 REPEAT GEN_TAC THEN CONV_TAC let_CONV THEN DISCH_TAC THEN
2073 ASM_SIMP_TAC[MATRIX_BY_CRAMER_LEMMA] THEN
2074 REWRITE_TAC[DET_3; CART_EQ] THEN
2075 SIMP_TAC[LAMBDA_BETA; DIMINDEX_3; ARITH; VECTOR_3] THEN
2076 REWRITE_TAC[FORALL_3; ARITH; VECTOR_3] THEN REWRITE_TAC[CONJ_ACI]);;
2078 let CONGRUENT_EDGES_TAC edges =
2079 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REWRITE_TAC[IMP_IMP] THEN
2080 REWRITE_TAC[edges] THEN
2081 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[GSYM SEGMENT_CONVEX_HULL] THEN
2082 MATCH_MP_TAC CONGRUENT_SEGMENTS THEN REWRITE_TAC[DIST_EQ] THEN
2083 REWRITE_TAC[dist; NORM_POW_2] THEN
2084 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_SUB_CONV) THEN
2085 CONV_TAC(ONCE_DEPTH_CONV VECTOR3_DOT_CONV) THEN
2086 CONV_TAC(ONCE_DEPTH_CONV REAL_RAT5_EQ_CONV) THEN
2089 let CONGRUENT_FACES_TAC facets =
2090 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REWRITE_TAC[IMP_IMP] THEN
2091 REWRITE_TAC[facets] THEN
2092 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2094 let t1 = rand(lhand w) and t2 = rand(rand w) in
2095 let (x1,y1,z1) = three_adjacent_points (dest_setenum t1)
2096 and (x2,y2,z2) = three_adjacent_points (dest_setenum t2) in
2097 let th1 = SPECL [`A:real^3^3`;x1;y1;z1;x2;y2;z2] MATRIX_BY_CRAMER in
2098 let th2 = REWRITE_RULE[VECTOR_3; DET_3] th1 in
2099 let th3 = CONV_RULE (DEPTH_CONV REAL_RAT5_MUL_CONV) th2 in
2100 let th4 = CONV_RULE (DEPTH_CONV
2101 (REAL_RAT5_ADD_CONV ORELSEC REAL_RAT5_SUB_CONV)) th3 in
2102 let th5 = CONV_RULE let_CONV th4 in
2103 let th6 = CONV_RULE(ONCE_DEPTH_CONV REAL_RAT5_DIV_CONV) th5 in
2104 let th7 = CONV_RULE(ONCE_DEPTH_CONV REAL_RAT5_EQ_CONV) th6 in
2105 let th8 = MP th7 (EQT_ELIM(REWRITE_CONV[] (lhand(concl th7)))) in
2106 let tms = map rhs (conjuncts(rand(concl th8))) in
2107 let matt = mk_33matrix tms in
2108 MATCH_MP_TAC CONGRUENT_SIMPLE THEN EXISTS_TAC matt THEN CONJ_TAC THENL
2109 [REWRITE_TAC[ORTHOGONAL_MATRIX; CART_EQ] THEN
2110 SIMP_TAC[transp; LAMBDA_BETA; matrix_mul; mat] THEN
2111 REWRITE_TAC[DIMINDEX_3; SUM_3; FORALL_3; VECTOR_3; ARITH] THEN
2112 CONV_TAC(ONCE_DEPTH_CONV REAL_RAT5_MUL_CONV) THEN
2113 CONV_TAC(DEPTH_CONV REAL_RAT5_ADD_CONV) THEN
2114 CONV_TAC(ONCE_DEPTH_CONV REAL_RAT5_EQ_CONV) THEN
2115 REWRITE_TAC[] THEN NO_TAC;
2116 REWRITE_TAC[IMAGE_CLAUSES; MATRIX_VECTOR_MUL_3] THEN
2117 CONV_TAC(ONCE_DEPTH_CONV REAL_RAT5_MUL_CONV) THEN
2118 CONV_TAC(DEPTH_CONV REAL_RAT5_ADD_CONV) THEN
2119 REWRITE_TAC[INSERT_AC]]);;
2121 let TETRAHEDRON_CONGRUENT_EDGES = prove
2122 (`!e1 e2. e1 face_of std_tetrahedron /\ aff_dim e1 = &1 /\
2123 e2 face_of std_tetrahedron /\ aff_dim e2 = &1
2124 ==> e1 congruent e2`,
2125 CONGRUENT_EDGES_TAC TETRAHEDRON_EDGES);;
2127 let TETRAHEDRON_CONGRUENT_FACETS = prove
2128 (`!f1 f2. f1 face_of std_tetrahedron /\ aff_dim f1 = &2 /\
2129 f2 face_of std_tetrahedron /\ aff_dim f2 = &2
2130 ==> f1 congruent f2`,
2131 CONGRUENT_FACES_TAC TETRAHEDRON_FACETS);;
2133 let CUBE_CONGRUENT_EDGES = prove
2134 (`!e1 e2. e1 face_of std_cube /\ aff_dim e1 = &1 /\
2135 e2 face_of std_cube /\ aff_dim e2 = &1
2136 ==> e1 congruent e2`,
2137 CONGRUENT_EDGES_TAC CUBE_EDGES);;
2139 let CUBE_CONGRUENT_FACETS = prove
2140 (`!f1 f2. f1 face_of std_cube /\ aff_dim f1 = &2 /\
2141 f2 face_of std_cube /\ aff_dim f2 = &2
2142 ==> f1 congruent f2`,
2143 CONGRUENT_FACES_TAC CUBE_FACETS);;
2145 let OCTAHEDRON_CONGRUENT_EDGES = prove
2146 (`!e1 e2. e1 face_of std_octahedron /\ aff_dim e1 = &1 /\
2147 e2 face_of std_octahedron /\ aff_dim e2 = &1
2148 ==> e1 congruent e2`,
2149 CONGRUENT_EDGES_TAC OCTAHEDRON_EDGES);;
2151 let OCTAHEDRON_CONGRUENT_FACETS = prove
2152 (`!f1 f2. f1 face_of std_octahedron /\ aff_dim f1 = &2 /\
2153 f2 face_of std_octahedron /\ aff_dim f2 = &2
2154 ==> f1 congruent f2`,
2155 CONGRUENT_FACES_TAC OCTAHEDRON_FACETS);;
2157 let DODECAHEDRON_CONGRUENT_EDGES = prove
2158 (`!e1 e2. e1 face_of std_dodecahedron /\ aff_dim e1 = &1 /\
2159 e2 face_of std_dodecahedron /\ aff_dim e2 = &1
2160 ==> e1 congruent e2`,
2161 CONGRUENT_EDGES_TAC DODECAHEDRON_EDGES);;
2163 let DODECAHEDRON_CONGRUENT_FACETS = prove
2164 (`!f1 f2. f1 face_of std_dodecahedron /\ aff_dim f1 = &2 /\
2165 f2 face_of std_dodecahedron /\ aff_dim f2 = &2
2166 ==> f1 congruent f2`,
2167 CONGRUENT_FACES_TAC DODECAHEDRON_FACETS);;
2169 let ICOSAHEDRON_CONGRUENT_EDGES = prove
2170 (`!e1 e2. e1 face_of std_icosahedron /\ aff_dim e1 = &1 /\
2171 e2 face_of std_icosahedron /\ aff_dim e2 = &1
2172 ==> e1 congruent e2`,
2173 CONGRUENT_EDGES_TAC ICOSAHEDRON_EDGES);;
2175 let ICOSAHEDRON_CONGRUENT_FACETS = prove
2176 (`!f1 f2. f1 face_of std_icosahedron /\ aff_dim f1 = &2 /\
2177 f2 face_of std_icosahedron /\ aff_dim f2 = &2
2178 ==> f1 congruent f2`,
2179 CONGRUENT_FACES_TAC ICOSAHEDRON_FACETS);;