(* ========================================================================== *)
(* FLYSPECK - BOOK FORMALIZATION                                              *)
(*                                                                            *)
(* Chapter: Packing/Rogers simplex                                            *)
(* Author: Alexey Solovyev                                                    *)
(* Date: 2010-08-12                                                           *)
(* ========================================================================== *)


flyspeck_needs "packing/pack3.hl";;
flyspeck_needs "fan/HypermapAndFan.hl";;


module Rogers = struct

open Pack_defs;;
open Sphere;;
open Packing3;;



(*****************************************************************)
			   
(*****************************************)
(* Faces                                 *)
(*****************************************)
	 
	 
(*********************************************)
(* KHEJKCI                                   *)
(*********************************************)


(* A(u, v) is a face of A+(u, v) *)
let BIS_FACE_OF_BIS_LE = 
prove(`!(u:real^N) v. bis u v face_of bis_le u v`,
REPEAT GEN_TAC THEN SUBGOAL_THEN `bis (u:real^N) v = bis_le u v INTER bis u v` (fun th -> ONCE_REWRITE_TAC[th]) THENL [ REWRITE_TAC[bis; bis_le; EXTENSION; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[BIS_EQ_HYPERPLANE] THEN MATCH_MP_TAC FACE_OF_INTER_SUPPORTING_HYPERPLANE_LE THEN REWRITE_TAC[CONVEX_BIS_LE; BIS_LE_EQ_HALFSPACE; IN_ELIM_THM]);;
(* Generalized version of the target theorem *)
let KHEJKCI_GEN = 
prove(`!V k r ul vl. saturated V /\ packing V /\ barV V k ul /\ barV V r vl /\ initial_sublist ul vl ==> (voronoi_list V vl) face_of (voronoi_list V ul) `,
REWRITE_TAC[INITIAL_SUBLIST] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `?h tl. ul = CONS (h:real^3) tl` MP_TAC THENL [ ASM_MESON_TAC[BARV_CONS]; ALL_TAC ] THEN STRIP_TAC THEN SUBGOAL_THEN `voronoi_list (V:real^3->bool) ul = voronoi_closed V h INTER INTERS {bis h u | u IN set_of_list tl}` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC VORONOI_LIST_BIS THEN ASM_MESON_TAC[BARV_SUBSET]; ALL_TAC ] THEN SUBGOAL_THEN `voronoi_list (V:real^3->bool) vl = voronoi_closed V h INTER INTERS {bis h u | u IN set_of_list (APPEND tl yl)}` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC VORONOI_LIST_BIS THEN ASM_MESON_TAC[BARV_SUBSET; APPEND]; ALL_TAC ] THEN REWRITE_TAC[face_of; IN_SET_OF_LIST; MEM_APPEND] THEN REPEAT CONJ_TAC THENL [ SET_TAC[]; MATCH_MP_TAC CONVEX_INTER THEN CONJ_TAC THENL [ ASM_MESON_TAC[DRUQUFE]; ALL_TAC ] THEN MATCH_MP_TAC CONVEX_INTERS THEN REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[CONVEX_BIS]; ALL_TAC ] THEN REPEAT GEN_TAC THEN SIMP_TAC[IN_INTER; IN_INTERS; IN_ELIM_THM] THEN REPLICATE_TAC 2 (DISCH_THEN (CONJUNCTS_THEN2 (ASSUME_TAC o CONJUNCT1) MP_TAC)) THEN STRIP_TAC THEN SUBGOAL_THEN `!u:real^3. u IN V ==> a:real^3 IN bis_le h u /\ b:real^3 IN bis_le h u` ASSUME_TAC THENL [ REPLICATE_TAC 3 (POP_ASSUM (fun th -> ALL_TAC)) THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[voronoi_closed; bis_le; IN_ELIM_THM; IN] THEN MESON_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!u:real^3. (MEM u tl ==> u IN V) /\ (MEM u yl ==> u IN V)` ASSUME_TAC THENL [ GEN_TAC THEN REPLICATE_TAC 6 (POP_ASSUM (fun th -> ALL_TAC)) THEN REPLICATE_TAC 2 (POP_ASSUM MP_TAC) THEN POP_ASSUM (MP_TAC o (fun th -> MATCH_MP BARV_SUBSET th)) THEN POP_ASSUM (MP_TAC o (fun th -> MATCH_MP BARV_SUBSET th)) THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN REWRITE_TAC[IMP_CONJ_ALT] THEN REPLICATE_TAC 2 (DISCH_THEN (fun th -> REWRITE_TAC[th])) THEN REWRITE_TAC[SUBSET; IN_SET_OF_LIST; MEM_APPEND; MEM] THEN SIMP_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!u:real^3. u IN V /\ x IN bis h u ==> a IN bis h u /\ b IN bis h u` ASSUME_TAC THENL [ POP_ASSUM (fun th -> ALL_TAC) THEN GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o (SPEC `u:real^3`)) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN MP_TAC (ISPECL [`h:real^3`; `u:real^3`] BIS_FACE_OF_BIS_LE) THEN REWRITE_TAC[face_of] THEN DISCH_THEN (CONJUNCTS_THEN2 (fun th -> ALL_TAC) (MP_TAC o CONJUNCT2)) THEN DISCH_THEN (MP_TAC o ISPECL [`a:real^3`; `b:real^3`; `x:real^3`]) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_MESON_TAC[]);;
(* vor_list -> barV *)
let KHEJKCI = 
prove(`!V k ul. saturated V /\ packing V /\ barV V k ul ==> ((voronoi_list V ul) face_of (voronoi_closed V (HD ul)) )`,
REPEAT STRIP_TAC THEN FIRST_ASSUM (MP_TAC o (fun th -> MATCH_MP BARV_CONS th)) THEN STRIP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[GSYM VORONOI_LIST_SING] THEN MATCH_MP_TAC KHEJKCI_GEN THEN EXISTS_TAC `0` THEN EXISTS_TAC `k:num` THEN SUBGOAL_THEN `initial_sublist [h:real^3] ul` ASSUME_TAC THENL [ ASM_REWRITE_TAC[INITIAL_SUBLIST; APPEND] THEN MESON_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`; `[h:real^3]`] BARV_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[LENGTH; ARITH_RULE `0 < SUC 0`; ARITH_RULE `SUC 0 - 1 = 0`]);;
(*********************************************) (* IDBEZAL *) (* Characterization of facets of Omega(V,W) *) (*********************************************) (* Canonical representation for Omega(V, barV(k)) *)
let VORONOI_BARV_CANONICAL = 
prove(`!V k ul. packing V /\ saturated V /\ barV V k ul ==> ?K. FINITE K /\ voronoi_list V ul = affine hull (voronoi_list V ul) INTER INTERS K /\ (!a. a IN K ==> (?v. v IN V /\ ~(v = HD ul) /\ (a = bis_le v (HD ul) \/ a = bis_le (HD ul) v))) /\ (!K'. K' PSUBSET K ==> (voronoi_list V ul) PSUBSET (affine hull (voronoi_list V ul) INTER INTERS K'))`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`] BARV_CONS) THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`] BARV_SUBSET) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `h:real^3`; `t:(real^3)list`] VORONOI_LIST_CANONICAL) THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN DISCH_THEN (LABEL_TAC "A") THEN DISCH_TAC THEN REMOVE_THEN "A" MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]));;
let REAL_LINE_BOUNDED = 
prove(`!a b. (!t. t * a <= b) ==> a = &0`,
REPEAT STRIP_TAC THEN DISJ_CASES_TAC (TAUT `a = &0 \/ ~(a = &0)`) THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `(b + &1) * inv(a)`) THEN ASM_REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN REAL_ARITH_TAC);;
let REAL_NEG_LE_RMUL = 
prove(`!x y z. z < &0 ==> (x <= y <=> y * z <= x * z)`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`x:real`; `y:real`; `--z:real`] REAL_LE_LMUL_EQ) THEN ASM_REWRITE_TAC[REAL_NEG_GT0] THEN REWRITE_TAC[REAL_MUL_LNEG; REAL_LE_NEG; REAL_MUL_AC] THEN SIMP_TAC[]);;
let HALFSPACE_EQ = 
prove(`!(a:real^N) b c d. {x | a dot x <= b} = {x | c dot x <= d} <=> (?t. c = t % a /\ d = t * b /\ &0 < t) \/ (a = vec 0 /\ c = vec 0 /\ ((&0 <= b /\ &0 <= d) \/ (b < &0 /\ d < &0)))`,
REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN EQ_TAC THENL [ DISCH_TAC THEN DISJ_CASES_TAC (TAUT `(a:real^N) = vec 0 \/ ~(a = vec 0)`) THENL [ DISJ2_TAC THEN ASM_REWRITE_TAC[] THEN DISJ_CASES_TAC (TAUT `(c:real^N) = vec 0 \/ ~(c = vec 0)`) THEN ASM_REWRITE_TAC[] THENL [ FIRST_X_ASSUM (MP_TAC o check (is_forall o concl)) THEN ASM_REWRITE_TAC[DOT_LZERO] THEN REAL_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_TAC "A" `~((c:real^N) dot c = &0)` [ ASM_REWRITE_TAC[DOT_EQ_0] ] THEN DISJ_CASES_TAC (REAL_ARITH `&0 <= b \/ b < &0`) THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `((d + &1) * inv((c:real^N) dot c)) % c`) THEN ASM_REWRITE_TAC[DOT_LZERO] THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN REAL_ARITH_TAC; FIRST_X_ASSUM (MP_TAC o SPEC `(d * inv((c:real^N) dot c)) % c`) THEN ASM_REWRITE_TAC[DOT_LZERO] THEN ASM_SIMP_TAC[REAL_ARITH `b < &0 ==> ((&0 <= b) <=> F)`] THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN REWRITE_TAC[REAL_MUL_RID; REAL_LE_REFL] ]; ALL_TAC ] THEN DISJ1_TAC THEN SUBGOAL_TAC "A" `~((a:real^N dot a) = &0)` [ ASM_REWRITE_TAC[DOT_EQ_0] ] THEN SUBGOAL_THEN `!u. u*((a:real^N dot a)*(c dot c) - (a dot c)*(a dot c)) <= d*(a dot a) - b*(a dot c)` MP_TAC THENL [ GEN_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `((b - u * (a:real^N dot c)) * inv(a dot a)) % a + u % c`) THEN REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RID; REAL_ARITH `(b:real - a) + a = b`; REAL_LE_REFL] THEN DISCH_TAC THEN ASSUME_TAC (ISPEC `a:real^N` DOT_POS_LE) THEN MP_TAC (SPECL [`(b - u * (a:real^N dot c)) * inv(a dot a) * (c dot a) + u * (c dot c)`; `d:real`; `a:real^N dot a`] REAL_LE_RMUL) THEN ASM_REWRITE_TAC[REAL_ADD_RDISTRIB] THEN REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_FIELD `~(a:real^N dot a = &0) ==> inv(a dot a) * (c dot a) * (a dot a) = (c dot a)`] THEN REWRITE_TAC[REAL_SUB_RDISTRIB; REAL_SUB_LDISTRIB; DOT_SYM] THEN REAL_ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (MP_TAC o (fun th -> MATCH_MP REAL_LINE_BOUNDED th)) THEN REWRITE_TAC[GSYM REAL_POW_2; REAL_ARITH `a - b = &0 <=> b = a`] THEN DISCH_TAC THEN SUBGOAL_THEN `?t. c = t % (a:real^N)` MP_TAC THENL [ MP_TAC (SPECL [`a:real^N`; `c:real^N`] DOT_CAUCHY_SCHWARZ_EQUAL) THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN STRIP_TAC THENL [ EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO]; ALL_TAC ] THEN EXISTS_TAC `c':real` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN EXISTS_TAC `t:real` THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o check (is_forall o concl)) THEN ASM_REWRITE_TAC[DOT_LMUL] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `(b * inv(a:real^N dot a)) % a`) THEN FIRST_ASSUM (MP_TAC o SPEC `(d * inv(t) * inv(a:real^N dot a)) % a`) THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN REWRITE_TAC[REAL_MUL_RID; REAL_LE_REFL] THEN SUBGOAL_THEN `~(t = &0)` ASSUME_TAC THENL [ DISJ_CASES_TAC (TAUT `~(t = &0) \/ t = &0`) THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o check (is_forall o concl)) THEN ASM_REWRITE_TAC[REAL_ARITH `&0 * a = &0`] THEN DISCH_TAC THEN DISJ_CASES_TAC (REAL_ARITH `&0 <= d \/ d < &0`) THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `((b + &1) * inv((a:real^N) dot a)) % a`) THEN ASM_REWRITE_TAC[DOT_LZERO] THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN REAL_ARITH_TAC; FIRST_X_ASSUM (MP_TAC o SPEC `(b * inv((a:real^N) dot a)) % a`) THEN ASM_REWRITE_TAC[DOT_LZERO] THEN ASM_SIMP_TAC[REAL_ARITH `b < &0 ==> ((&0 <= b) <=> F)`] THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN REWRITE_TAC[REAL_MUL_RID; REAL_LE_REFL] ]; ALL_TAC ] THEN ASM_SIMP_TAC[REAL_FIELD `~(t = &0) ==> t * d * inv t = d`] THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN SUBGOAL_THEN `&0 < t` ASSUME_TAC THENL [ DISJ_CASES_TAC (REAL_ARITH `&0 < t \/ t <= &0`) THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[REAL_LE_LT] THEN DISCH_TAC THEN DISJ_CASES_TAC (REAL_ARITH `t * b - d - &1 <= &0 \/ &0 < t * b - d - &1`) THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `((d + &1) * inv(t) * inv(a:real^N dot a)) % a`) THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RID; REAL_FIELD `~(t = &0) ==> (t * d * inv t = d)`] THEN REWRITE_TAC[REAL_ARITH `d + &1 <= d <=> F`] THEN SUBGOAL_THEN `(d + &1) * inv t <= b` MP_TAC THENL [ MP_TAC (SPECL [`(d + &1) * inv t`; `b:real`; `t:real`] REAL_NEG_LE_RMUL) THEN ASM_REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RID] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; ALL_TAC ] THEN MESON_TAC[]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `(b * inv(a:real^N dot a)) % a`) THEN REWRITE_TAC[DOT_RMUL; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RID; REAL_LE_REFL] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; ALL_TAC ] THEN DISCH_TAC THEN SUBGOAL_THEN `d:real <= t * b` MP_TAC THENL [ MP_TAC (SPECL [`t:real`; `(d:real) * inv t`; `b:real`] REAL_LE_LMUL) THEN ASM_SIMP_TAC[REAL_ARITH `&0 < t ==> &0 <= t`; REAL_FIELD `~(t = &0) ==> t * d * inv t = d`]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THENL [ GEN_TAC THEN ASM_REWRITE_TAC[DOT_LMUL] THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ]; GEN_TAC THEN ASM_REWRITE_TAC[DOT_LZERO]; GEN_TAC THEN ASM_REWRITE_TAC[DOT_LZERO] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC ]);;
let HALFSPACE_EQ_BIS_LE_IMP_HYPERPLANE_EQ_BIS = 
prove(`!(a:real^N) b v w. ~(a = vec 0) /\ {x | a dot x <= b} = bis_le v w ==> {x | a dot x = b} = bis v w`,
REPEAT GEN_TAC THEN REWRITE_TAC[BIS_LE_EQ_HALFSPACE; BIS_EQ_HYPERPLANE] THEN REWRITE_TAC[HALFSPACE_EQ] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[DOT_LZERO; EXTENSION; IN_ELIM_THM] THENL [ GEN_TAC THEN REWRITE_TAC[DOT_LMUL] THEN REWRITE_TAC[REAL_EQ_MUL_LCANCEL] THEN ASM_SIMP_TAC[REAL_ARITH `&0 < t ==> ~(t = &0)`]; ASM_MESON_TAC[]; ASM_MESON_TAC[] ]);;
(* A special version of the FACET_OF_POLYHEDRON_EXPLICIT theorem for bisectors *)
let FACET_OF_POLYHEDRON_EXPLICIT_BIS = 
prove(`!(V:real^3->bool) K s u. FINITE K /\ s = affine hull s INTER INTERS K /\ (!a. a IN K ==> (?v. v IN V /\ ~(v = u) /\ (a = bis_le v u \/ a = bis_le u v))) /\ (!K'. K' PSUBSET K ==> s PSUBSET (affine hull s INTER INTERS K')) ==> (!c. c facet_of s <=> (?v. v IN V /\ (bis_le v u IN K \/ bis_le u v IN K) /\ c = s INTER bis u v))`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `?a b. !h:real^3->bool. h IN K ==> ~(a h = vec 0) /\ h = {x | a h dot x <= b h}` MP_TAC THENL [ POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN REPLICATE_TAC 2 (POP_ASSUM (fun th -> ALL_TAC)) THEN DISCH_TAC THEN REWRITE_TAC[GSYM SKOLEM_THM] THEN GEN_TAC THEN REWRITE_TAC[RIGHT_EXISTS_IMP_THM] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `h:(real^3->bool)`) THEN ASM_REWRITE_TAC[BIS_LE_EQ_HALFSPACE] THEN STRIP_TAC THENL [ EXISTS_TAC `&2 % (u - (v:real^3))` THEN EXISTS_TAC `(u:real^3) dot u - (v:real^3) dot v` THEN ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_ARITH `&2 = &0 <=> F`; VECTOR_SUB_EQ]; EXISTS_TAC `&2 % ((v:real^3) - u)` THEN EXISTS_TAC `(v:real^3) dot v - (u:real^3) dot u` THEN ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_ARITH `&2 = &0 <=> F`; VECTOR_SUB_EQ] ]; ALL_TAC ] THEN STRIP_TAC THEN MP_TAC (ISPECL [`s:(real^3->bool)`; `K:(real^3->bool)->bool`; `a:(real^3->bool)->real^3`; `b:(real^3->bool)->real`] FACET_OF_POLYHEDRON_EXPLICIT) THEN ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ ASM_MESON_TAC[]; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN EQ_TAC THENL [ STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `h:real^3->bool`) THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (is_forall o concl)) THEN FIRST_X_ASSUM (MP_TAC o SPEC `h:real^3->bool`) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `v:real^3` THEN SUBGOAL_THEN `{x:real^3 | x | (a:(real^3->bool)->real^3) h dot x = b h} = bis u v` ASSUME_TAC THENL [ MP_TAC (ISPECL [`(a:(real^3->bool)->real^3) h`; `(b:(real^3->bool)->real) h`; `v:real^3`; `u:real^3`] HALFSPACE_EQ_BIS_LE_IMP_HYPERPLANE_EQ_BIS) THEN ASM_MESON_TAC[BIS_SYM]; ALL_TAC ] THEN ASM_MESON_TAC[]; EXISTS_TAC `v:real^3` THEN SUBGOAL_THEN `{x:real^3 | x | (a:(real^3->bool)->real^3) h dot x = b h} = bis u v` ASSUME_TAC THENL [ MP_TAC (ISPECL [`(a:(real^3->bool)->real^3) h`; `(b:(real^3->bool)->real) h`; `u:real^3`; `v:real^3`] HALFSPACE_EQ_BIS_LE_IMP_HYPERPLANE_EQ_BIS) THEN ASM_MESON_TAC[]; ALL_TAC ] THEN ASM_MESON_TAC[] ]; ALL_TAC ] THEN STRIP_TAC THENL [ ABBREV_TAC `h = bis_le (v:real^3) u` THEN FIRST_X_ASSUM (MP_TAC o SPEC `h:real^3->bool`) THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (is_forall o concl)) THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o SPEC `h:real^3->bool`) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `h:real^3->bool` THEN SUBGOAL_THEN `{x:real^3 | x | (a:(real^3->bool)->real^3) h dot x = b h} = bis u v` ASSUME_TAC THENL [ MP_TAC (ISPECL [`(a:(real^3->bool)->real^3) h`; `(b:(real^3->bool)->real) h`; `v:real^3`; `u:real^3`] HALFSPACE_EQ_BIS_LE_IMP_HYPERPLANE_EQ_BIS) THEN ASM_MESON_TAC[BIS_SYM]; ALL_TAC ] THEN ASM_MESON_TAC[]; ABBREV_TAC `h = bis_le (u:real^3) v` THEN FIRST_X_ASSUM (MP_TAC o SPEC `h:real^3->bool`) THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (is_forall o concl)) THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o SPEC `h:real^3->bool`) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `h:real^3->bool` THEN SUBGOAL_THEN `{x:real^3 | x | (a:(real^3->bool)->real^3) h dot x = b h} = bis u v` ASSUME_TAC THENL [ MP_TAC (ISPECL [`(a:(real^3->bool)->real^3) h`; `(b:(real^3->bool)->real) h`; `u:real^3`; `v:real^3`] HALFSPACE_EQ_BIS_LE_IMP_HYPERPLANE_EQ_BIS) THEN ASM_MESON_TAC[BIS_SYM]; ALL_TAC ] THEN ASM_MESON_TAC[] ]);;
(************************************************************) (* IDBEZAL: characterization of facets of Omega(V, ul) *) (************************************************************) (* vor_list -> barV *)
let IDBEZAL = 
prove(`!V ul k F. saturated V /\ packing V /\ barV V k ul /\ (k < 3) ==> (F facet_of voronoi_list V ul <=> (?vl. (F = voronoi_list V vl) /\ barV V (k+1) vl /\ (truncate_simplex k vl = ul)))`,
REPEAT STRIP_TAC THEN EQ_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`] VORONOI_BARV_CANONICAL) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ABBREV_TAC `s = voronoi_list (V:real^3->bool) ul` THEN MP_TAC (SPECL [`V:real^3->bool`; `K:(real^3->bool)->bool`; `s:real^3->bool`; `(HD ul):real^3`] FACET_OF_POLYHEDRON_EXPLICIT_BIS) THEN ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ ASM_MESON_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN DISCH_TAC THEN SUBGOAL_THEN `aff_dim (F':real^3->bool) = aff_dim (s:real^3->bool) - &1` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN REWRITE_TAC[facet_of] THEN SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN DISCH_THEN (CHOOSE_THEN MP_TAC) THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN DISCH_THEN (ASSUME_TAC o CONJUNCT2) THEN DISCH_TAC THEN EXISTS_TAC `APPEND ul [v:real^3]` THEN SUBGOAL_THEN `truncate_simplex k (APPEND ul [v:real^3]) = ul` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[TRUNCATE_SIMPLEX] THEN MATCH_MP_TAC CHOICE_LEMMA THEN CONJ_TAC THENL [ EXISTS_TAC `ul:(real^3)list` THEN CONJ_TAC THENL [ ASM_MESON_TAC[BARV]; ALL_TAC] THEN REWRITE_TAC[INITIAL_SUBLIST_APPEND]; ALL_TAC ] THEN REPLICATE_TAC 9 (POP_ASSUM (fun th -> ALL_TAC)) THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[BARV] THEN REPEAT STRIP_TAC THEN ASSUME_TAC (ISPECL [`ul:(real^3)list`; `[v:real^3]`] INITIAL_SUBLIST_APPEND) THEN ASM_MESON_TAC[INITIAL_SUBLIST_UNIQUE]; ALL_TAC ] THEN SUBGOAL_THEN `F' = voronoi_list V (APPEND ul [v:real^3])` ASSUME_TAC THENL [ POP_ASSUM (fun th -> ALL_TAC) THEN REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN REPLICATE_TAC 5 (POP_ASSUM (fun th -> ALL_TAC)) THEN FIRST_ASSUM (MP_TAC o (fun th -> MATCH_MP BARV_SUBSET th)) THEN FIRST_ASSUM (MP_TAC o (fun th -> MATCH_MP BARV_CONS th)) THEN STRIP_TAC THEN FIRST_X_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN DISCH_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN DISCH_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MATCH_MP_TAC VORONOI_LIST_INTER_BIS THEN ASM_MESON_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `barV (V:real^3->bool) (k + 1) (APPEND ul [v])` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[BARV] THEN CONJ_TAC THENL [ REPLICATE_TAC 10 (POP_ASSUM (fun th -> ALL_TAC)) THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[BARV; LENGTH_APPEND] THEN REWRITE_TAC[LENGTH; SYM ONE] THEN SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[VORONOI_NONDG; INITIAL_SUBLIST_APPEND_SING] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "s" THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN REPLICATE_TAC 5 (POP_ASSUM (fun th -> ALL_TAC)) THEN POP_ASSUM MP_TAC THEN FIRST_ASSUM (MP_TAC o (fun th -> MATCH_MP BARV_SUBSET th)) THEN POP_ASSUM MP_TAC THEN REPLICATE_TAC 2 (POP_ASSUM (fun th -> ALL_TAC)) THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THENL [ ASM_REWRITE_TAC[LENGTH_APPEND; LENGTH] THEN ASM_SIMP_TAC [ARITH_RULE `k < 3 ==> (k + 1) + SUC 0 < 5`]; REWRITE_TAC[SUBSET; IN_SET_OF_LIST; MEM_APPEND; MEM] THEN ASM_MESON_TAC[SUBSET; IN_SET_OF_LIST]; POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[LENGTH_APPEND; LENGTH] THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 1`] THEN ARITH_TAC ]; ALL_TAC ] THEN POP_ASSUM ACCEPT_TAC; ALL_TAC ] THEN REWRITE_TAC[facet_of] THEN REPEAT STRIP_TAC THENL [ SUBGOAL_THEN `initial_sublist ul (vl:(real^3)list)` ASSUME_TAC THENL [ SUBGOAL_TAC "A" `k + 1 <= LENGTH (vl:(real^3)list)` [ ASM_MESON_TAC[BARV; ARITH_RULE `k + 1 <= (k + 1) + 1`] ] THEN ASM_MESON_TAC[TRUNCATE_SIMPLEX_INITIAL_SUBLIST]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC KHEJKCI_GEN THEN ASM_MESON_TAC[]; POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN POP_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ASM_SIMP_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `k < 3 ==> (k + 1) + 1 < 5`; ARITH_RULE `0 < a + 1`] THEN DISCH_THEN ((LABEL_TAC "A") o CONJUNCT2) THEN DISCH_TAC THEN REMOVE_THEN "A" MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th; AFF_DIM_EMPTY]) THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN REWRITE_TAC[INT_ARITH `-- &1 + (((&k):int) + &1) + &1 = &4 <=> (&k):int = &3`] THEN ONCE_REWRITE_TAC[INT_OF_NUM_EQ] THEN ACCEPT_TAC (ARITH_RULE `k < 3 ==> ~(k = 3)`); POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ASM_SIMP_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < a + 1`] THEN DISCH_THEN (CONJUNCTS_THEN2 (fun th -> ALL_TAC) (ASSUME_TAC o CONJUNCT2)) THEN FIRST_X_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_SIMP_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < a + 1`] THEN DISCH_THEN (CONJUNCTS_THEN2 (fun th -> ALL_TAC) (ASSUME_TAC o CONJUNCT2)) THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC ]);;
(**************************************) (************************) (* Partitionining space *) (************************) (* GLTVHUM *)
let VORONOI_LIST_EQ_UNION_CONVEX_HULL_FACETS = 
prove(`!V ul k p. packing V /\ saturated V /\ barV V k ul /\ k < 3 /\ p IN voronoi_list V ul ==> voronoi_list V ul = UNIONS {convex hull (p INSERT voronoi_list V vl) | vl | barV V (k + 1) vl /\ truncate_simplex k vl = ul}`,
REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`{p:real^3}`; `voronoi_list V ul`] POLYTOPE_UNION_CONVEX_HULL_FACETS) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[SUBSET; IN_SING] THEN REPEAT CONJ_TAC THENL [ MATCH_MP_TAC POLYTOPE_VORONOI_LIST THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[GSYM LENGTH_EQ_NIL] THEN UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV] THEN ARITH_TAC; UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 1`] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN UNDISCH_TAC `k < 3` THEN REWRITE_TAC[GSYM INT_OF_NUM_LT] THEN INT_ARITH_TAC; REWRITE_TAC[EXTENSION; IN_SING; NOT_IN_EMPTY; NOT_FORALL_THM] THEN EXISTS_TAC `p:real^3` THEN REWRITE_TAC[] ]; ALL_TAC ] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN AP_TERM_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`] IDBEZAL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN GEN_TAC THEN REWRITE_TAC[GSYM EXTENSION; SET_RULE `!f:real^3->bool. {p} UNION f = p INSERT f`] THEN EQ_TAC THEN STRIP_TAC THENL [ EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[]; EXISTS_TAC `voronoi_list V vl` THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[] ]);;
let NUMSEG_SUBSET_INDUCT = 
prove(`!s a b. (a IN s) /\ (!k. a <= k /\ SUC k <= b /\ k IN s ==> SUC k IN s) ==> a..b SUBSET s`,
REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET; IN_NUMSEG] THEN INDUCT_TAC THENL [ REWRITE_TAC[ARITH_RULE `a <= 0 <=> a = 0`] THEN DISCH_TAC THEN UNDISCH_TAC `a:num IN s` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN ASM_CASES_TAC `SUC x = a:num` THENL [ ASM_REWRITE_TAC[]; ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MP_TAC (ARITH_RULE `a <= SUC x /\ ~(SUC x = a) /\ SUC x <= b ==> a <= x /\ x <= b`) THEN ASM_SIMP_TAC[]);;
let BARV_EXISTS = 
prove(`!V wl k. packing V /\ saturated V /\ k < 3 /\ barV V k wl ==> ?vl. barV V (SUC k) vl /\ truncate_simplex k vl = wl`,
REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`voronoi_list V wl`] POLYTOPE_FACET_EXISTS) THEN ANTS_TAC THENL [ CONJ_TAC THENL [ MATCH_MP_TAC POLYTOPE_VORONOI_LIST_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[AFF_DIM_VORONOI_LIST] THEN UNDISCH_TAC `k < 3` THEN REWRITE_TAC[GSYM INT_OF_NUM_LT] THEN INT_ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `wl:(real^3)list`; `k:num`; `f:real^3->bool`] IDBEZAL) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[ADD1]);;
let BARV_EXISTS_ALT = 
prove(`!V k. packing V /\ saturated V /\ k <= 3 ==> ?ul. barV V k ul`,
GEN_TAC THEN INDUCT_TAC THENL [ STRIP_TAC THEN MP_TAC (SPEC_ALL TIWWFYQ) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `[v:real^3]` THEN ASM_SIMP_TAC[BARV_0]; ALL_TAC ] THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o check (is_imp o concl)) THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k <= 3`] THEN STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`] BARV_EXISTS) THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k < 3`] THEN STRIP_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[]);;
let GLTVHUM_lemma1 = 
prove(`!V ul j. packing V /\ saturated V /\ j < 3 /\ barV V j ul ==> {k | k IN j..3 /\ voronoi_list V ul = UNIONS {convex hull ({omega_list_n V vl i | i IN j..k-1} UNION voronoi_list V vl) | vl | barV V k vl /\ truncate_simplex j vl = ul}} = j..3`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL [ SIMP_TAC[SUBSET; IN_ELIM_THM]; ALL_TAC ] THEN MATCH_MP_TAC NUMSEG_SUBSET_INDUCT THEN REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM; LE_REFL] THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = j + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V j ul` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `!vl. barV V j vl /\ truncate_simplex j vl = ul <=> vl = ul` (LABEL_TAC "j") THENL [ GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL [ UNDISCH_TAC `barV V j vl` THEN UNDISCH_TAC `barV V j ul` THEN REWRITE_TAC[BARV] THEN REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`j:num`; `vl:(real^3)list`; `vl:(real^3)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[LE_REFL; INITIAL_SUBLIST_REFL; EQ_SYM_EQ]; ALL_TAC ] THEN ASM_SIMP_TAC[TRUNCATE_SIMPLEX_REFL]; ALL_TAC ] THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[SING_GSPEC_APP; UNIONS_1] THEN ASM_SIMP_TAC[LT_IMP_LE] THEN ASM_CASES_TAC `j = 0` THENL [ SUBGOAL_THEN `?x. ul = [x:real^3]` CHOOSE_TAC THENL [ EXISTS_TAC `HD ul:real^3` THEN MATCH_MP_TAC LENGTH_1_LEMMA THEN UNDISCH_TAC `LENGTH (ul:(real^3)list) = j + 1` THEN ASM_REWRITE_TAC[ARITH]; ALL_TAC ] THEN ASM_REWRITE_TAC[ARITH_RULE `0 - 1 = 0`; ARITH_RULE `j <= 0 <=> j = 0`; ARITH_RULE `0 <= i /\ i = 0 <=> i = 0`] THEN REWRITE_TAC[SING_GSPEC_APP; VORONOI_LIST; set_of_list; VORONOI_SET; INTERS_1; IN_SING; OMEGA_LIST_N; HD; SING_UNION_EQ_INSERT] THEN SUBGOAL_THEN `x:real^3 INSERT voronoi_closed V x = voronoi_closed V x` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[GSYM ABSORPTION; CENTER_IN_VORONOI_CELL]; ALL_TAC ] THEN REWRITE_TAC[EQ_SYM_EQ; CONVEX_HULL_EQ; CONVEX_VORONOI_CLOSED]; ALL_TAC ] THEN ASM_SIMP_TAC[ARITH_RULE `~(j = 0) ==> (j <= i /\ i <= j - 1 <=> F)`] THEN SUBGOAL_THEN `{omega_list_n V ul i | i | F} = {}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY]; ALL_TAC ] THEN REWRITE_TAC[UNION_EMPTY; EQ_SYM_EQ; CONVEX_HULL_EQ; CONVEX_VORONOI_LIST]; ALL_TAC ] THEN REPEAT STRIP_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `j <= k ==> j <= SUC k`]; ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[ARITH_RULE `SUC k - 1 = k`] THEN ABBREV_TAC `f = \vl:(real^3)list. {omega_list_n V vl i | j <= i /\ i <= k} UNION voronoi_list V vl` THEN SUBGOAL_THEN `!vl:(real^3)list. {omega_list_n V vl i | j <= i /\ i <= k} UNION voronoi_list V vl = f vl` (fun th -> REWRITE_TAC[th]) THENL [ EXPAND_TAC "f" THEN REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!P:(real^3)list->(real^3->bool). UNIONS {P vl | barV V (SUC k) vl /\ truncate_simplex j vl = ul} = UNIONS {UNIONS {P vl | vl | barV V (SUC k) vl /\ truncate_simplex k vl = wl} | wl | barV V k wl /\ truncate_simplex j wl = ul}` (fun th -> REWRITE_TAC[th]) THENL [ GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_UNIONS] THEN GEN_TAC THEN REWRITE_TAC[GSYM EXTENSION; IN_ELIM_THM; IN_UNIONS] THEN EQ_TAC THEN STRIP_TAC THENL [ POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `UNIONS {(P vl'):(real^3->bool) | vl' | barV V (SUC k) vl' /\ truncate_simplex k vl' = truncate_simplex k vl}` THEN CONJ_TAC THENL [ EXISTS_TAC `truncate_simplex k vl:(real^3)list` THEN REWRITE_TAC[] THEN CONJ_TAC THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[ARITH_RULE `k <= SUC k`]; ALL_TAC ] THEN MP_TAC (ISPECL [`vl:(real^3)list`; `j:num`; `k:num`] TRUNCATE_TRUNCATE_SIMPLEX) THEN UNDISCH_TAC `barV V (SUC k) vl` THEN SIMP_TAC[BARV] THEN DISCH_TAC THEN ASM_SIMP_TAC[ARITH_RULE `k + 1 <= SUC k + 1`]; ALL_TAC ] THEN REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN EXISTS_TAC `(P (vl:(real^3)list)):real^3->bool` THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `(P (vl:(real^3)list)):real^3->bool` THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `truncate_simplex j wl = ul:(real^3)list` THEN MP_TAC (ISPECL [`vl:(real^3)list`; `j:num`; `k:num`] TRUNCATE_TRUNCATE_SIMPLEX) THEN UNDISCH_TAC `barV V (SUC k) vl` THEN SIMP_TAC[BARV] THEN DISCH_TAC THEN ASM_SIMP_TAC[ARITH_RULE `k + 1 <= SUC k + 1`]; ALL_TAC ] THEN ABBREV_TAC `g = \vl:(real^3)list. convex hull (omega_list_n V vl k INSERT voronoi_list V vl)` THEN SUBGOAL_THEN `!vl:(real^3)list. convex hull (f vl):real^3->bool = convex hull ({omega_list_n V vl i | j <= i /\ i <= k - 1} UNION g vl)` (fun th -> REWRITE_TAC[th]) THENL [ GEN_TAC THEN EXPAND_TAC "g" THEN ONCE_REWRITE_TAC[GSYM CONV_UNION_lemma] THEN ONCE_REWRITE_TAC[GSYM SING_UNION_EQ_INSERT] THEN REWRITE_TAC[GSYM UNION_ASSOC] THEN SUBGOAL_THEN `{omega_list_n V vl i | j <= i /\ i <= k - 1} UNION {omega_list_n V vl k} = {omega_list_n V vl i | j <= i /\ i <= k}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_UNION; IN_ELIM_THM; IN_SING] THEN GEN_TAC THEN EQ_TAC THENL [ STRIP_TAC THENL [ EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[ARITH_RULE `i <= k - 1 ==> i <= k`]; ALL_TAC ] THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[LE_REFL]; ALL_TAC ] THEN STRIP_TAC THEN ASM_CASES_TAC `i = k:num` THENL [ ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ1_TAC THEN EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[ARITH_RULE `i <= k /\ ~(i = k) ==> i <= k - 1`]; ALL_TAC ] THEN EXPAND_TAC "f" THEN REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!wl. barV V k wl ==> UNIONS {g vl | vl | barV V (SUC k) vl /\ truncate_simplex k vl = wl} = voronoi_list V wl` (LABEL_TAC "wl") THENL [ REPEAT STRIP_TAC THEN ABBREV_TAC `p = omega_list_n V wl k` THEN SUBGOAL_THEN `UNIONS {g vl | barV V (SUC k) vl /\ truncate_simplex k vl = wl} = UNIONS {convex hull ((p:real^3) INSERT voronoi_list V vl) | vl | barV V (SUC k) vl /\ truncate_simplex k vl = wl}` (fun th -> REWRITE_TAC[th]) THENL [ AP_TERM_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN GEN_TAC THEN REWRITE_TAC[GSYM EXTENSION] THEN SUBGOAL_THEN `!vl. barV V (SUC k) vl /\ truncate_simplex k vl = wl ==> omega_list_n V vl k = p` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `k:num`; `0:num`] OMEGA_LIST_N_LEMMA) THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = k + 2 /\ LENGTH (wl:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k wl` THEN UNDISCH_TAC `barV V (SUC k) vl` THEN SIMP_TAC[BARV; ARITH_RULE `k + 2 = SUC k + 1`]; ALL_TAC ] THEN ASM_REWRITE_TAC[ARITH_RULE `k + 0 + 1 <= k + 2`] THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[th; ADD_0]); ALL_TAC ] THEN EQ_TAC THENL [ STRIP_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[ADD1] THEN MATCH_MP_TAC (GSYM VORONOI_LIST_EQ_UNION_CONVEX_HULL_FACETS) THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k < 3`] THEN EXPAND_TAC "p" THEN SUBGOAL_THEN `voronoi_list V wl = voronoi_list V (truncate_simplex k wl):real^3->bool` (fun th -> ONCE_REWRITE_TAC[th]) THENL [ SUBGOAL_THEN `truncate_simplex k wl = wl:(real^3)list` (fun th -> REWRITE_TAC[th]) THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_REFL THEN UNDISCH_TAC `barV V k wl` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN MATCH_MP_TAC OMEGA_LIST_N_IN_VORONOI_LIST THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[LE_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN SUBGOAL_THEN `!wl. barV V k wl ==> UNIONS {convex hull ({omega_list_n V vl i | j <= i /\ i <= k - 1} UNION g vl) | vl | barV V (SUC k) vl /\ truncate_simplex k vl = wl} = convex hull ({omega_list_n V wl i | j <= i /\ i <= k - 1} UNION voronoi_list V wl)` (LABEL_TAC "wl2") THENL [ REPEAT STRIP_TAC THEN SUBGOAL_THEN `LENGTH (wl:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k wl` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN ABBREV_TAC `S = {omega_list_n V wl i | j <= i /\ i <= k - 1}` THEN SUBGOAL_THEN `!vl. barV V (SUC k) vl /\ truncate_simplex k vl = wl ==> {omega_list_n V vl i | j <= i /\ i <= k - 1} = S` (LABEL_TAC "vl") THENL [ REPEAT STRIP_TAC THEN SUBGOAL_THEN `!i. j <= i /\ i <= k - 1 ==> omega_list_n V wl i = omega_list_n V vl i` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = k + 2` ASSUME_TAC THENL [ UNDISCH_TAC `barV V (SUC k) vl` THEN SIMP_TAC[BARV; ARITH_RULE `k + 2 = SUC k + 1`]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `i:num`; `k - i:num`] OMEGA_LIST_N_LEMMA) THEN ASM_SIMP_TAC[ARITH_RULE `i <= k - 1 ==> i + k - i + 1 = k + 1 /\ i + k - i = k`; ARITH_RULE `k + 1 <= k + 2`]; ALL_TAC ] THEN EXPAND_TAC "S" THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL [ EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[]; EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[] ]; ALL_TAC ] THEN MP_TAC (ISPECL [`{(g vl):real^3->bool | vl | barV V (SUC k) vl /\ truncate_simplex k vl = wl}`; `S:real^3->bool`] CONVEX_HULL_UNION_UNIONS) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[CONVEX_VORONOI_LIST] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MP_TAC (SPEC_ALL BARV_EXISTS) THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k < 3`] THEN STRIP_TAC THEN EXISTS_TAC `(g (vl:(real^3)list)):real^3->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN DISCH_THEN (fun th -> ALL_TAC) THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION] THEN GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN EQ_TAC THENL [ STRIP_TAC THEN EXISTS_TAC `(g (vl:(real^3)list)):real^3->bool` THEN ASM_SIMP_TAC[] THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[EXTENSION] THEN GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN EQ_TAC THENL [ STRIP_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_SIMP_TAC[]; STRIP_TAC THEN EXISTS_TAC `wl:(real^3)list` THEN ASM_SIMP_TAC[] ]);;
(* GLTVHUM *)
let GLTVHUM = 
prove(`!V (u0:real^3) p. packing V /\ saturated V /\ (u0 IN V) ==> (p IN voronoi_closed V u0 <=> (?vl. vl IN barV V 3 /\ p IN rogers V vl /\ (truncate_simplex 0 vl = [u0])))`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `[u0:real^3]`; `0`] GLTVHUM_lemma1) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[ARITH_RULE `0 < 3`] THEN ASM_SIMP_TAC[BARV_0]; ALL_TAC ] THEN REWRITE_TAC[EXTENSION] THEN DISCH_THEN (MP_TAC o SPEC `3`) THEN REWRITE_TAC[IN_NUMSEG; LE_REFL; LE_0; IN_ELIM_THM] THEN SUBGOAL_THEN `voronoi_list V [u0:real^3] = voronoi_closed V u0` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[VORONOI_LIST; set_of_list; VORONOI_SET; IN_SING; SING_GSPEC_APP; INTERS_1]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN SUBGOAL_THEN `!vl. barV V 3 vl ==> convex hull ({omega_list_n V vl i | i <= 2} UNION voronoi_list V vl) = rogers V vl` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[ROGERS; IMAGE_LEMMA] THEN AP_TERM_TAC THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = 4` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN SIMP_TAC[BARV; ARITH_RULE `3 + 1 = 4`]; ALL_TAC ] THEN SUBGOAL_THEN `voronoi_list V vl = {omega_list_n V vl 3}` (fun th -> REWRITE_TAC[th]) THENL [ SUBGOAL_THEN `aff_dim (voronoi_list V vl:real^3->bool) = &0` MP_TAC THENL [ ONCE_REWRITE_TAC[INT_ARITH `&0 = int_of_num 3 - &3`] THEN MATCH_MP_TAC AFF_DIM_VORONOI_LIST THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[AFF_DIM_EQ_0] THEN STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `3`; `3`] OMEGA_LIST_N_IN_VORONOI_LIST) THEN ASM_REWRITE_TAC[LE_REFL] THEN SUBGOAL_THEN `truncate_simplex 3 vl = vl:(real^3)list` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_REFL THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[IN_SING]; ALL_TAC ] THEN ASM_REWRITE_TAC[EXTENSION; IN_UNION] THEN GEN_TAC THEN REWRITE_TAC[IN_SING; IN_ELIM_THM] THEN EQ_TAC THENL [ STRIP_TAC THENL [ EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[ARITH_RULE `i <= 2 ==> i < 4`]; ALL_TAC ] THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[ARITH_RULE `3 < 4`]; ALL_TAC ] THEN STRIP_TAC THEN ASM_CASES_TAC `x' = 3` THENL [ UNDISCH_TAC `x = omega_list_n V vl x'` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN DISJ1_TAC THEN EXISTS_TAC `x':num` THEN ASM_SIMP_TAC[ARITH_RULE `x' < 4 /\ ~(x' = 3) ==> x' <= 2`]; ALL_TAC ] THEN REWRITE_TAC[ARITH_RULE `3 - 1 = 2`] THEN EQ_TAC THEN STRIP_TAC THENL [ POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN UNDISCH_TAC `vl IN barV V 3` THEN DISCH_THEN (ASSUME_TAC o REWRITE_RULE[IN]) THEN EXISTS_TAC `rogers V vl` THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `vl:(real^3)list` THEN ASM_SIMP_TAC[]);;
(***************************************************) (* DUUNHOR *) (*************************)
let VORONOI_CLOSED_EQ_LEMMA = 
prove(`!V u v. packing V /\ u IN V /\ v IN V /\ voronoi_closed V u = voronoi_closed V v ==> u = v`,
REWRITE_TAC[voronoi_closed; EXTENSION] THEN REPEAT STRIP_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `v : real^3`) THEN REWRITE_TAC[IN_ELIM_THM] THEN REWRITE_TAC[DIST_REFL; DIST_POS_LE] THEN DISCH_THEN (MP_TAC o SPEC `v : real^3`) THEN UNDISCH_TAC `v : real^3 IN V` THEN REWRITE_TAC[IN] THEN DISCH_TAC THEN ANTS_TAC THEN ASM_REWRITE_TAC[DIST_REFL; DIST_LE_0; EQ_SYM_EQ]);;
let ODIGPXU_lemma = 
prove(`!P f f' p0 p (q : real^N) t s. polyhedron P /\ p0 IN P /\ ~(p0 IN f UNION f') /\ f facet_of P /\ f' facet_of P /\ p IN f /\ q IN f' /\ &0 < t /\ &0 < s /\ (&1 - t) % p0 + t % p = (&1 - s) % p0 + s % q ==> s <= t`,
REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[VECTOR_SUB_RDISTRIB] THEN REWRITE_TAC[VECTOR_ARITH `a - t % (p0 : real^N) + t % p = a - s % p0 + s % q <=> t % (p - p0) = s % (q - p0)`] THEN MP_TAC (REAL_ARITH `s <= t \/ t < s`) THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o AP_TERM `\x : real^N. inv t % x`) THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_ARITH `&0 < t ==> ~(t = &0)`; REAL_MUL_LINV; VECTOR_MUL_LID] THEN ABBREV_TAC `r = inv t * s` THEN SUBGOAL_THEN `&1 < r` ASSUME_TAC THENL [ MP_TAC (SPECL [`&1`; `r : real`; `t : real`] REAL_LT_LMUL_EQ) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_RID; REAL_ARITH `&0 < t ==> ~(t = &0)`; REAL_MUL_RINV; REAL_MUL_LID]; ALL_TAC ] THEN MP_TAC (SPECL[`P : real^N -> bool`; `f' : real^N -> bool`] FACET_OF_POLYHEDRON) THEN ASM_REWRITE_TAC[] THEN REPEAT (DISCH_THEN (CHOOSE_THEN MP_TAC)) THEN REWRITE_TAC[SUBSET] THEN STRIP_TAC THEN SUBGOAL_THEN `(a : real^N) dot p0 < b` ASSUME_TAC THENL [ REWRITE_TAC[REAL_ARITH `x < y <=> x <= y /\ ~(x = y)`] THEN FIRST_X_ASSUM (MP_TAC o SPEC `p0 : real^N`) THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN SIMP_TAC[] THEN DISCH_THEN (fun th -> ALL_TAC) THEN UNDISCH_TAC `~(p0 : real^N IN f UNION f')` THEN ASM_REWRITE_TAC[CONTRAPOS_THM; IN_UNION] THEN DISCH_TAC THEN DISJ2_TAC THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]; ALL_TAC ] THEN REWRITE_TAC[VECTOR_ARITH `p - p0 = x <=> p = p0 + x : real^N`] THEN DISCH_TAC THEN MP_TAC (ISPECL[`f : real^N -> bool`; `P : real^N -> bool`] FACET_OF_IMP_SUBSET) THEN ASM_REWRITE_TAC[SUBSET] THEN DISCH_THEN (MP_TAC o SPEC `p : real^N`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> FIRST_X_ASSUM (MP_TAC o (fun th2 -> MATCH_MP th2 th))) THEN REWRITE_TAC[IN_ELIM_THM; DOT_RADD; DOT_RMUL; DOT_RSUB] THEN REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN REWRITE_TAC[EXTENSION] THEN DISCH_THEN (MP_TAC o SPEC `q : real^N`) THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN DISCH_THEN (fun th -> ALL_TAC) THEN REWRITE_TAC[REAL_ARITH `x + r * (b - x) <= b <=> (r - &1) * b <= (r - &1) * x`] THEN ASM_SIMP_TAC[REAL_ARITH `&1 < r ==> &0 < r - &1`; REAL_LE_LMUL_EQ] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
(* ODIGPXU *)
let ODIGPXU = 
prove(`!P f f' p0 p (q : real^N) t s. polyhedron P /\ p0 IN P /\ ~(p0 IN f UNION f') /\ f facet_of P /\ f' facet_of P /\ p IN f /\ q IN f' /\ &0 < t /\ &0 < s /\ (&1 - t) % p0 + t % p = (&1 - s) % p0 + s % q ==> s = t`,
REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ARITH `s = t <=> s <= t /\ t <= s`] THEN STRIP_TAC THEN MATCH_MP_TAC ODIGPXU_lemma THENL [ MAP_EVERY EXISTS_TAC [`P : real^N -> bool`; `f : real^N -> bool`; `f' : real^N -> bool`] THEN MAP_EVERY EXISTS_TAC [`p0 : real^N`; `p : real^N`; `q : real^N`] THEN ASM_REWRITE_TAC[]; MAP_EVERY EXISTS_TAC [`P : real^N -> bool`; `f' : real^N -> bool`; `f : real^N -> bool`] THEN MAP_EVERY EXISTS_TAC [`p0 : real^N`; `q : real^N`; `p : real^N`] THEN ASM_REWRITE_TAC[UNION_COMM] ]);;
let OMEGA_LIST_N_EQ = 
prove(`!V ul i j. omega_list_n V ul i IN voronoi_list V (truncate_simplex (SUC i) ul) ==> omega_list_n V ul (SUC i) = omega_list_n V ul i`,
REPEAT GEN_TAC THEN ABBREV_TAC `X = voronoi_list V (truncate_simplex (SUC i) ul)` THEN ASM_REWRITE_TAC[OMEGA_LIST_N] THEN DISCH_TAC THEN MP_TAC (ISPECL[`X:real^3 -> bool`; `omega_list_n V ul i`] CLOSEST_POINT_EXISTS) THEN ANTS_TAC THENL [ REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXPAND_TAC "X" THEN REWRITE_TAC[CLOSED_VORONOI_LIST] THEN EXISTS_TAC `omega_list_n V ul i` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN POP_ASSUM (MP_TAC o SPEC `omega_list_n V ul i`) THEN ASM_REWRITE_TAC[DIST_REFL; DIST_LE_0] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]));;
let OMEGA_LIST_N_IN_FACET = 
prove(`!V ul k i. packing V /\ saturated V /\ barV V k ul /\ i < k ==> ?F. F facet_of voronoi_list V (truncate_simplex i ul) /\ voronoi_list V (truncate_simplex (i + 1) ul) = F /\ (!j. i < j /\ j <= k ==> omega_list_n V ul j IN F)`,
REPEAT STRIP_TAC THEN ABBREV_TAC `FF = voronoi_list V (truncate_simplex (i + 1) ul)` THEN EXISTS_TAC `FF : real^3 -> bool` THEN REWRITE_TAC[] THEN CONJ_TAC THENL [ MP_TAC (SPECL[`V:real^3->bool`; `truncate_simplex i ul : (real^3)list`; `i:num`; `FF:real^3->bool`] IDBEZAL) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MP_TAC (SPEC_ALL BARV_IMP_K_LE_3) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i < 3`) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[LT_IMP_LE]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN EXISTS_TAC `truncate_simplex (i + 1) ul : (real^3)list` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[ARITH_RULE `i < k ==> i + 1 <= k`]; MP_TAC (ISPECL[`ul:(real^3)list`; `i:num`; `i + 1`] TRUNCATE_TRUNCATE_SIMPLEX) THEN DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[ARITH_RULE `i <= i + 1`] THEN UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV] THEN DISCH_TAC THEN ASM_SIMP_TAC[ARITH_RULE `i < k ==> (i + 1) + 1 <= k + 1`] ]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL[`V:real^3->bool`; `ul:(real^3)list`; `k:num`; `j:num`] OMEGA_LIST_N_IN_VORONOI_LIST) THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `voronoi_list V (truncate_simplex j ul) SUBSET FF` ASSUME_TAC THENL [ EXPAND_TAC "FF" THEN REWRITE_TAC[VORONOI_LIST; VORONOI_SET] THEN REWRITE_TAC[SUBSET; IN_INTERS; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `v:real^3` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[IN_SET_OF_LIST; MEM_EXISTS_EL] THEN UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV] THEN DISCH_TAC THEN MP_TAC (ISPECL[`i + 1`; `ul:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN MP_TAC (ISPECL[`j:num`; `ul:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[ARITH_RULE `j + 1 <= k + 1 <=> j <= k`] THEN ASM_SIMP_TAC[ARITH_RULE `i < k ==> i + 1 <= k`] THEN REPLICATE_TAC 2 (DISCH_THEN (fun th -> REWRITE_TAC[th])) THEN DISCH_THEN (X_CHOOSE_THEN `r:num` MP_TAC) THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN MP_TAC (ISPECL[`ul:(real^3)list`; `i + 1`; `r:num`] EL_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[ARITH_RULE `i < k ==> (i + 1) + 1 <= k + 1`] THEN ASM_SIMP_TAC[ARITH_RULE `r < (i + 1) + 1 ==> r <= i + 1`] THEN REPEAT DISCH_TAC THEN EXISTS_TAC `r:num` THEN MP_TAC (ARITH_RULE `j <= k /\ i < j /\ r < (i + 1) + 1 ==> r < j + 1`) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL[`ul:(real^3)list`; `j:num`; `r:num`] EL_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[ARITH_RULE `j + 1 <= k + 1 <=> j <= k`] THEN ASM_SIMP_TAC[ARITH_RULE `r < j + 1 ==> r <= j`]; ALL_TAC ] THEN DISCH_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `voronoi_list V (truncate_simplex j ul)` THEN ASM_REWRITE_TAC[]);;
let OMEGA_LIST_N_IN_VORONOI_LIST_GEN = 
prove(`!V ul k i j. packing V /\ saturated V /\ barV V k ul /\ i <= j /\ j <= k ==> omega_list_n V ul j IN voronoi_list V (truncate_simplex i ul)`,
REPEAT STRIP_TAC THEN UNDISCH_TAC `i <= j:num` THEN REWRITE_TAC[LE_LT] THEN STRIP_TAC THENL [ MP_TAC (SPEC_ALL OMEGA_LIST_N_IN_FACET) THEN ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ MATCH_MP_TAC (ARITH_RULE `i < j /\ j <= k ==> i < k : num`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `F':real^3->bool` THEN CONJ_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC FACET_OF_IMP_SUBSET THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC OMEGA_LIST_N_IN_VORONOI_LIST THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]);;
let VORONOI_SET_SUBSET = 
prove(`!V s t. s SUBSET t ==> voronoi_set V t SUBSET voronoi_set V s`,
REWRITE_TAC[VORONOI_SET] THEN SET_TAC[]);;
let TRUNCATE_SIMPLEX_SUBSET = 
prove(`!(ul:(A)list) i j. j <= i /\ i + 1 <= LENGTH ul ==> set_of_list (truncate_simplex j ul) SUBSET set_of_list (truncate_simplex i ul)`,
REWRITE_TAC[SUBSET; IN_SET_OF_LIST; MEM_EXISTS_EL] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `i':num` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN MP_TAC (SPECL[`i:num`; `ul:(A)list`] LENGTH_TRUNCATE_SIMPLEX) THEN MP_TAC (SPECL[`j:num`; `ul:(A)list`] LENGTH_TRUNCATE_SIMPLEX) THEN MP_TAC (ARITH_RULE `!x. j <= i /\ i + 1 <= x ==> j + 1 <= x`) THEN MP_TAC (ARITH_RULE `i' < j + 1 /\ j <= i ==> i' < i + 1`) THEN ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN MP_TAC (SPECL[`ul:(A)list`; `i:num`; `i':num`] EL_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[ARITH_RULE `i' < i + 1 ==> i' <= i`] THEN DISCH_TAC THEN MP_TAC (SPECL[`ul:(A)list`; `j:num`; `i':num`] EL_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[ARITH_RULE `i' < j + 1 ==> i' <= j`]);;
let OMEGA_LIST_N_EQ_GEN = 
prove(`!V ul k i j. packing V /\ saturated V /\ barV V k ul /\ i < j /\ j <= k /\ omega_list_n V ul i IN voronoi_list V (truncate_simplex j ul) ==> omega_list_n V ul (SUC i) = omega_list_n V ul i`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC OMEGA_LIST_N_EQ THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `voronoi_list V (truncate_simplex j ul)` THEN ASM_REWRITE_TAC[VORONOI_LIST] THEN MATCH_MP_TAC VORONOI_SET_SUBSET THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_SUBSET THEN ASM_SIMP_TAC[ARITH_RULE `i < j ==> SUC i <= j`] THEN UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV] THEN ASM_SIMP_TAC[ARITH_RULE `j <= k ==> j + 1 <= k + 1`]);;
let CARD_LE_3 = 
prove(`!s. ~(s = {}) /\ FINITE s /\ CARD s <= 3 ==> ?x y z : A. s = {x, y, z}`,
REPEAT STRIP_TAC THEN MP_TAC (ARITH_RULE `!n. n <= 3 ==> n = 0 \/ n = 1 \/ n = 2 \/ n = 3`) THEN DISCH_THEN (MP_TAC o SPEC `CARD (s:A->bool)`) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN UNDISCH_TAC `FINITE (s:A->bool)` THEN REWRITE_TAC[IMP_IMP; GSYM HAS_SIZE; num_CONV `3`; num_CONV `2`; num_CONV `1`; HAS_SIZE_CLAUSES] THENL [ DISCH_TAC THEN UNDISCH_TAC `~((s:A->bool) = {})` THEN ASM_REWRITE_TAC[]; STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN REPLICATE_TAC 3 (EXISTS_TAC `a:A`) THEN SET_TAC[]; REPEAT (DISCH_THEN (CHOOSE_THEN MP_TAC)) THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC (LABEL_TAC "A")) THEN STRIP_TAC THEN REMOVE_THEN "A" MP_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `a:A` THEN EXISTS_TAC `a':A` THEN EXISTS_TAC `a':A` THEN SET_TAC[]; REPEAT (DISCH_THEN (CHOOSE_THEN MP_TAC)) THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC (LABEL_TAC "A")) THEN REPEAT (DISCH_THEN (CHOOSE_THEN MP_TAC)) THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN STRIP_TAC THEN REMOVE_THEN "A" MP_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `a:A` THEN EXISTS_TAC `a':A` THEN EXISTS_TAC `a'':A` THEN REWRITE_TAC[] ]);;
let AFF_DIM_LE_2_IMP_COPLANAR = 
prove(`!s : real^N -> bool. aff_dim s <= &2 ==> coplanar s`,
REPEAT STRIP_TAC THEN REWRITE_TAC[coplanar] THEN MP_TAC (ISPEC `s:real^N->bool` AFF_DIM) THEN STRIP_TAC THEN SUBGOAL_THEN `CARD (b:real^N -> bool) <= 3` ASSUME_TAC THENL [ REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN REWRITE_TAC[INT_ARITH `a <= int_of_num 3 <=> a - &1 <= &2`] THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN ASM_CASES_TAC `(b:real^N -> bool) = {}` THENL [ REPLICATE_TAC 3 (EXISTS_TAC `vec 0 : real^N`) THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull b : real^N -> bool` THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN POP_ASSUM (fun th -> REWRITE_TAC[th; AFFINE_HULL_EMPTY; EMPTY_SUBSET]); ALL_TAC ] THEN MP_TAC (ISPEC `b:real^N->bool` CARD_LE_3) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`x:real^N`; `y:real^N`; `z:real^N`] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull b : real^N -> bool` THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN POP_ASSUM (fun th -> REWRITE_TAC[th; SUBSET_REFL]));;
let SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET = 
prove(`!(ul:(A)list) k. k + 1 <= LENGTH ul ==> set_of_list (truncate_simplex k ul) SUBSET set_of_list ul`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_OF_LIST_INITIAL_SUBLIST_SUBSET THEN MP_TAC (SPECL [`k:num`; `truncate_simplex k (ul:(A)list)`; `ul:(A)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[]);;
let ROGERS_AFF_DIM_FULL = 
prove(`!V ul. barV V 3 ul /\ aff_dim (rogers V ul) = &3 ==> !i j. i < 4 /\ j < 4 /\ ~(i = j) ==> ~(omega_list_n V ul i = omega_list_n V ul j)`,
REWRITE_TAC[ROGERS; AFF_DIM_CONVEX_HULL; BARV; ARITH] THEN REPEAT GEN_TAC THEN REWRITE_TAC[GSYM IMP_IMP] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_THEN (fun th -> ALL_TAC) THEN REPEAT STRIP_TAC THEN ABBREV_TAC `S = IMAGE (omega_list_n V ul) {j | j < 4}` THEN ABBREV_TAC `a = omega_list_n V ul i` THEN ABBREV_TAC `b = omega_list_n V ul j` THEN SUBGOAL_THEN `S DELETE a DELETE b SUBSET IMAGE (omega_list_n V ul) {k | k < 4 /\ ~(k = i) /\ ~(k = j)}` MP_TAC THENL [ REPLICATE_TAC 3 (POP_ASSUM (fun th -> REWRITE_TAC[SYM th])) THEN REWRITE_TAC[SUBSET; IN_DELETE; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[CONTRAPOS_THM]; POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[CONTRAPOS_THM] ]; ALL_TAC ] THEN SUBGOAL_THEN `FINITE (S:real^3->bool)` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LT]; ALL_TAC ] THEN DISCH_TAC THEN SUBGOAL_THEN `CARD (S DELETE a DELETE (b:real^3)) <= 2` MP_TAC THENL [ MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD (IMAGE (omega_list_n V ul) {k | k < 4 /\ ~(k = i) /\ ~(k = j)})` THEN SUBGOAL_THEN `{k | k < 4 /\ ~(k = i) /\ ~(k = j)} HAS_SIZE 2` MP_TAC THENL [ SUBGOAL_THEN `{k | k < 4 /\ ~(k = i) /\ ~(k = j)} = {k | k < 4} DELETE i DELETE j` ASSUME_TAC THENL [ REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_DELETE; CONJ_ACI]; ALL_TAC ] THEN ASM_REWRITE_TAC[HAS_SIZE; FINITE_DELETE; FINITE_NUMSEG_LT] THEN MP_TAC (ISPECL[`j:num`; `{k | k < 4} DELETE i`] CARD_DELETE) THEN ASM_REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG_LT; IN_DELETE; IN_ELIM_THM] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MP_TAC (ISPECL[`i:num`; `{k | k < 4}`] CARD_DELETE) THEN ASM_REWRITE_TAC[FINITE_NUMSEG_LT; IN_ELIM_THM] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[CARD_NUMSEG_LT] THEN ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN CONJ_TAC THENL [ MATCH_MP_TAC CARD_SUBSET THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FINITE_IMAGE THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC CARD_IMAGE_LE THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPECL[`S:real^3->bool`; `a:real^3`] FINITE_DELETE) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[CARD_DELETE; IN_DELETE] THEN SUBGOAL_THEN `b:real^3 IN S` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN EXPAND_TAC "b" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `j:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPECL[`S:real^3->bool`; `b:real^3`] Hypermap.CARD_ATLEAST_1) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_SUB] THEN MP_TAC (ISPEC `S:real^3->bool` AFF_DIM_LE_CARD) THEN ASM_REWRITE_TAC[] THEN INT_ARITH_TAC);;
let VORONOI_LIST_AFF_DIM = 
prove(`!V ul k i. barV V k ul /\ i <= k ==> aff_dim (voronoi_list V (truncate_simplex i ul)) = &3 - &i`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `barV V i (truncate_simplex i ul)` MP_TAC THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `truncate_simplex i ul : (real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < i + 1`] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC);;
let AFF_DIM_FINITE_UNION_LE = 
prove(`!s (t:real^N->bool). FINITE s ==> aff_dim (s UNION t) <= &(CARD s) + aff_dim t`,
REPEAT STRIP_TAC THEN ABBREV_TAC `n = CARD (s:real^N->bool)` THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN SPEC_TAC (`s:real^N->bool`, `s:real^N->bool`) THEN SPEC_TAC (`n:num`, `n:num`) THEN INDUCT_TAC THEN REPEAT STRIP_TAC THENL [ MP_TAC (ISPEC `s:real^N->bool` CARD_EQ_0) THEN ASM_SIMP_TAC[UNION_EMPTY; INT_ADD_LID; INT_LE_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `s:real^N->bool HAS_SIZE (SUC n)` MP_TAC THENL [ ASM_REWRITE_TAC[HAS_SIZE]; ALL_TAC ] THEN REWRITE_TAC[HAS_SIZE_CLAUSES; HAS_SIZE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[INSERT_UNION_EQ; AFF_DIM_INSERT] THEN FIRST_X_ASSUM (MP_TAC o SPEC `t':real^N->bool`) THEN ASM_REWRITE_TAC[ARITH_RULE `SUC n = n + 1`; GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC);;
(* DUUNHOR *)
let DUUNHOR = 
prove(`!V ul vl. packing V /\ saturated V /\ ul IN barV V 3 /\ vl IN barV V 3 /\ ~(rogers V ul = rogers V vl) ==> coplanar (rogers V ul INTER rogers V vl)`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `LENGTH (ul : (real^3)list) = 4 /\ LENGTH (vl : (real^3)list) = 4` ASSUME_TAC THENL [ REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN SIMP_TAC[BARV; ARITH]; ALL_TAC ] THEN ASM_CASES_TAC `~(aff_dim (rogers V ul) = &3)` THENL [ MATCH_MP_TAC COPLANAR_SUBSET THEN EXISTS_TAC `rogers V ul` THEN REWRITE_TAC[INTER_SUBSET] THEN MATCH_MP_TAC AFF_DIM_LE_2_IMP_COPLANAR THEN MP_TAC (ISPEC `rogers V ul` AFF_DIM_LE_UNIV) THEN REWRITE_TAC[DIMINDEX_3] THEN POP_ASSUM MP_TAC THEN INT_ARITH_TAC; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_CLAUSES] THEN ASM_CASES_TAC `~(aff_dim (rogers V vl) = &3)` THENL [ DISCH_THEN (fun th -> ALL_TAC) THEN MATCH_MP_TAC COPLANAR_SUBSET THEN EXISTS_TAC `rogers V vl` THEN REWRITE_TAC[INTER_SUBSET] THEN MATCH_MP_TAC AFF_DIM_LE_2_IMP_COPLANAR THEN MP_TAC (ISPEC `rogers V vl` AFF_DIM_LE_UNIV) THEN REWRITE_TAC[DIMINDEX_3] THEN POP_ASSUM MP_TAC THEN INT_ARITH_TAC; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_CLAUSES] THEN SUBGOAL_THEN `?k. k <= 3 /\ (!i. i < k ==> omega_list_n V ul i = omega_list_n V vl i /\ voronoi_list V (truncate_simplex i ul) = voronoi_list V (truncate_simplex i vl)) /\ ~(voronoi_list V (truncate_simplex k ul) = voronoi_list V (truncate_simplex k vl))` MP_TAC THENL [ ONCE_REWRITE_TAC[GSYM NOT_CLAUSES] THEN UNDISCH_TAC `~(rogers V ul = rogers V vl)` THEN REWRITE_TAC[CONTRAPOS_THM; NOT_EXISTS_THM; DE_MORGAN_THM; NOT_FORALL_THM; NOT_IMP] THEN REWRITE_TAC[ROGERS] THEN DISCH_TAC THEN AP_TERM_TAC THEN SUBGOAL_THEN `!i. i < 4 ==> omega_list_n V ul i = omega_list_n V vl i /\ voronoi_list V (truncate_simplex i ul) = voronoi_list V (truncate_simplex i vl)` ASSUME_TAC THENL [ MATCH_MP_TAC num_WF THEN INDUCT_TAC THEN ASM_REWRITE_TAC[OMEGA_LIST_N] THENL [ REPLICATE_TAC 2 (DISCH_THEN (fun th -> ALL_TAC)) THEN POP_ASSUM (MP_TAC o SPEC `0`) THEN REWRITE_TAC[ARITH_RULE `~(0 <= 3) <=> F`; ARITH_RULE `i < 0 <=> F`; ARITH_RULE `0 < 4`] THEN REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN DISCH_THEN (LABEL_TAC "A") THEN DISCH_THEN (LABEL_TAC "B") THEN DISCH_TAC THEN USE_THEN "A" (MP_TAC o MATCH_MP BARV_SUBSET) THEN USE_THEN "B" (MP_TAC o MATCH_MP BARV_SUBSET) THEN REWRITE_TAC[SUBSET] THEN USE_THEN "A" (MP_TAC o MATCH_MP BARV_IMP_HD_IN_SET_OF_LIST) THEN DISCH_TAC THEN USE_THEN "B" (MP_TAC o MATCH_MP BARV_IMP_HD_IN_SET_OF_LIST) THEN DISCH_TAC THEN DISCH_THEN (MP_TAC o SPEC `HD vl : real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISCH_THEN (MP_TAC o SPEC `HD ul : real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPEC `ul:(real^3)list` TRUNCATE_0_EQ_HEAD) THEN MP_TAC (ISPEC `vl:(real^3)list` TRUNCATE_0_EQ_HEAD) THEN ASM_REWRITE_TAC[ARITH] THEN REPLICATE_TAC 2 (DISCH_THEN (fun th -> REWRITE_TAC[th])) THEN REWRITE_TAC[VORONOI_LIST_SING] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC VORONOI_CLOSED_EQ_LEMMA THEN EXISTS_TAC `V : real^3 -> bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM (fun th -> ALL_TAC) THEN DISCH_THEN (LABEL_TAC "A") THEN DISCH_TAC THEN REMOVE_THEN "A" MP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `SUC i`) THEN ASM_SIMP_TAC[ARITH_RULE `SUC i < 4 ==> SUC i <= 3`] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL [ DISCH_THEN (MP_TAC o SPEC `i':num`) THEN MP_TAC (ARITH_RULE `SUC i < 4 /\ i' < SUC i ==> i' < 4`) THEN ASM_SIMP_TAC[]; DISCH_THEN (MP_TAC o SPEC `i':num`) THEN MP_TAC (ARITH_RULE `SUC i < 4 /\ i' < SUC i ==> i' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPEC `i:num`) THEN ASM_SIMP_TAC[ARITH_RULE `i < SUC i`; ARITH_RULE `SUC i < 4 ==> i < 4`]; ALL_TAC ] THEN ASM_REWRITE_TAC[EXTENSION] THEN GEN_TAC THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EQ_TAC THENL [ DISCH_THEN (CHOOSE_THEN ASSUME_TAC) THEN EXISTS_TAC `x' : num` THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN ASM_SIMP_TAC[]; DISCH_THEN (CHOOSE_THEN ASSUME_TAC) THEN EXISTS_TAC `x' : num` THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN ASM_SIMP_TAC[]; ]; ALL_TAC ] THEN DISCH_THEN (CHOOSE_THEN STRIP_ASSUME_TAC) THEN DISCH_TAC THEN DISCH_TAC THEN ABBREV_TAC `X = voronoi_list V (truncate_simplex k ul) INTER voronoi_list V (truncate_simplex k vl)` THEN ABBREV_TAC `Y = IMAGE (omega_list_n V ul) {j | j < k}` THEN SUBGOAL_THEN `rogers V ul INTER rogers V vl SUBSET convex hull (Y UNION X)` MP_TAC THENL [ REWRITE_TAC[SUBSET; IN_INTER] THEN X_GEN_TAC `w:real^3` THEN ABBREV_TAC `YX = convex hull (Y UNION X) : real^3->bool` THEN ASM_REWRITE_TAC[ROGERS; CONVEX_HULL_FINITE] THEN ABBREV_TAC `L1 = IMAGE (omega_list_n V ul) {j | j < 4}` THEN ABBREV_TAC `L2 = IMAGE (omega_list_n V vl) {j | j < 4}` THEN REWRITE_TAC[GSYM IMP_IMP; IN_ELIM_THM] THEN DISCH_THEN (X_CHOOSE_THEN `ss : real^3 -> real` STRIP_ASSUME_TAC) THEN DISCH_THEN (X_CHOOSE_THEN `tt : real^3 -> real` STRIP_ASSUME_TAC) THEN SUBGOAL_THEN `FINITE (L1:real^3->bool) /\ FINITE (L2:real^3->bool)` ASSUME_TAC THENL [ CONJ_TAC THEN EXPAND_TAC "L1" THEN EXPAND_TAC "L2" THEN MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LT]; ALL_TAC ] THEN SUBGOAL_THEN `Y SUBSET (L1 : real^3->bool) /\ Y SUBSET (L2 : real^3->bool)` ASSUME_TAC THENL [ MAP_EVERY EXPAND_TAC ["L1";
"Y"; "L2"] THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `?i. i < k /\ (sum (IMAGE (omega_list_n V ul) {j | j <= i}) ss = &1 \/ sum (IMAGE (omega_list_n V vl) {j | j <= i}) tt = &1)` THENL [ EXPAND_TAC "YX" THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `convex hull Y UNION convex hull X : real^3->bool` THEN REWRITE_TAC[HULL_UNION_SUBSET; IN_UNION] THEN DISJ1_TAC THEN REWRITE_TAC[CONVEX_HULL_FINITE; IN_ELIM_THM] THEN POP_ASSUM MP_TAC THEN STRIP_TAC THENL [ ABBREV_TAC `Li = IMAGE (omega_list_n V ul) {j | j <= i}` THEN EXISTS_TAC `ss : real^3->real` THEN MP_TAC (ISPECL[`ss:real^3->real`; `Li:real^3->bool`; `L1 DIFF Li:real^3->bool`; `L1:real^3->bool`] (GEN_ALL SUM_UNION_EQ)) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ REWRITE_TAC[EXTENSION; IN_INTER; IN_DIFF] THEN REPEAT STRIP_TAC THEN SET_TAC[]; EXPAND_TAC "L1" THEN EXPAND_TAC "Li" THEN REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_IMAGE; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; REWRITE_TAC[TAUT `A \/ B /\ ~A <=> A \/ B`] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[] ]; ]; ALL_TAC ] THEN ASM_REWRITE_TAC[REAL_ARITH `&1 + a = &1 <=> a = &0`] THEN DISCH_TAC THEN MP_TAC (ISPECL[`ss:real^3->real`; `L1 DIFF Li:real^3->bool`] SUM_POS_EQ_0) THEN ANTS_TAC THENL [ REPEAT CONJ_TAC THENL [ MATCH_MP_TAC FINITE_DIFF THEN ASM_REWRITE_TAC[]; REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL [ EXPAND_TAC "Y" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "L1" THEN ASM_REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; UNDISCH_TAC `sum Li (ss:real^3->real) = &1` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC SUM_SUPERSET THEN CONJ_TAC THENL [ EXPAND_TAC "Li" THEN EXPAND_TAC "Y" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k:num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN EXPAND_TAC "Y" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF] THEN EXPAND_TAC "L1" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN UNDISCH_TAC `vsum L1 (\x:real^3. ss x % x) = w` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC EQ_SYM THEN MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "Y" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF; CONTRAPOS_THM] THEN EXPAND_TAC "Li" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN (* The second case *) ABBREV_TAC `Li = IMAGE (omega_list_n V vl) {j | j <= i}` THEN EXISTS_TAC `tt : real^3->real` THEN MP_TAC (ISPECL[`tt:real^3->real`; `Li:real^3->bool`; `L2 DIFF Li:real^3->bool`; `L2:real^3->bool`] (GEN_ALL SUM_UNION_EQ)) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ REWRITE_TAC[EXTENSION; IN_INTER; IN_DIFF] THEN REPEAT STRIP_TAC THEN SET_TAC[]; EXPAND_TAC "L2" THEN EXPAND_TAC "Li" THEN REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_IMAGE; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; REWRITE_TAC[TAUT `A \/ B /\ ~A <=> A \/ B`] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[] ]; ]; ALL_TAC ] THEN ASM_REWRITE_TAC[REAL_ARITH `&1 + a = &1 <=> a = &0`] THEN DISCH_TAC THEN MP_TAC (ISPECL[`tt:real^3->real`; `L2 DIFF Li:real^3->bool`] SUM_POS_EQ_0) THEN ANTS_TAC THENL [ REPEAT CONJ_TAC THENL [ MATCH_MP_TAC FINITE_DIFF THEN ASM_REWRITE_TAC[]; REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN SUBGOAL_THEN `Li SUBSET (Y : real^3->bool)` ASSUME_TAC THENL [ EXPAND_TAC "Li" THEN EXPAND_TAC "Y" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k:num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REPEAT CONJ_TAC THENL [ REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `Y:real^3->bool` THEN ASM_REWRITE_TAC[]; UNDISCH_TAC `sum Li (tt:real^3->real) = &1` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC SUM_SUPERSET THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `Y:real^3->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN UNDISCH_TAC `vsum L2(\x:real^3. tt x % x) = w` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC EQ_SYM THEN MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF; CONTRAPOS_THM] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN SIMP_TAC[SUBSET]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_EXISTS_THM; DE_MORGAN_THM] THEN DISCH_THEN (LABEL_TAC "not1") THEN (* ss i = tt i for i < k *) SUBGOAL_THEN `!i. i < k ==> ss (omega_list_n V ul i) : real = tt (omega_list_n V vl i : real^3)` MP_TAC THENL [ MATCH_MP_TAC num_WF THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN REMOVE_THEN "not1" (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ABBREV_TAC `a = sum (IMAGE (omega_list_n V ul) {j | j <= i}) ss` THEN ABBREV_TAC `b = sum (IMAGE (omega_list_n V vl) {j | j <= i}) tt` THEN ABBREV_TAC `Lu = IMAGE (omega_list_n V ul) {j | i < j /\ j < 4}` THEN ABBREV_TAC `Lv = IMAGE (omega_list_n V vl) {j | i < j /\ j < 4}` THEN (* sum Lu ss = 1 - a *) SUBGOAL_THEN `sum Lu (ss:real^3->real) = &1 - a` ASSUME_TAC THENL [ UNDISCH_TAC `sum (L1:real^3->bool) ss = &1` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[REAL_ARITH `a = b - c <=> a + c = b : real`] THEN EXPAND_TAC "a" THEN MATCH_MP_TAC SUM_UNION_EQ THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "Lu" THEN REWRITE_TAC[EXTENSION; IN_INTER; IN_UNION; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL [ REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL [`x':num`; `x'':num`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x'' <= i /\ i < k /\ k <= 3 ==> x'' < 4`) THEN MP_TAC (ARITH_RULE `x'' <= i /\ i < x' ==> ~(x' = x'':num)`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN EXPAND_TAC "L1" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EQ_TAC THEN STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `x' <= i : num` THENL [ DISJ2_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ1_TAC THEN EXISTS_TAC `x':num` THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[NOT_LE]; ALL_TAC ] THEN (* sum Lv tt = 1 - b *) SUBGOAL_THEN `sum Lv (tt:real^3->real) = &1 - b` ASSUME_TAC THENL [ UNDISCH_TAC `sum (L2:real^3->bool) tt = &1` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[REAL_ARITH `a = b - c <=> a + c = b : real`] THEN EXPAND_TAC "b" THEN MATCH_MP_TAC SUM_UNION_EQ THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "Lv" THEN REWRITE_TAC[EXTENSION; IN_INTER; IN_UNION; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL [ REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL [`x':num`; `x'':num`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x'' <= i /\ i < k /\ k <= 3 ==> x'' < 4`) THEN MP_TAC (ARITH_RULE `x'' <= i /\ i < x' ==> ~(x' = x'':num)`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN EXPAND_TAC "L2" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EQ_TAC THEN STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `x' <= i : num` THENL [ DISJ2_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ1_TAC THEN EXISTS_TAC `x':num` THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[NOT_LE]; ALL_TAC ] THEN (* a < 1 /\ b < 1 *) SUBGOAL_THEN `&0 < &1 - a /\ &0 < &1 - b` ASSUME_TAC THENL [ ASM_REWRITE_TAC[REAL_ARITH `&0 < &1 - a <=> a <= &1 /\ ~(a = &1)`] THEN REPLICATE_TAC 6 (POP_ASSUM (fun th -> REWRITE_TAC[SYM th])) THEN CONJ_TAC THENL [ UNDISCH_TAC `sum (L1:real^3->bool) ss = &1` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ EXPAND_TAC "L1" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN UNDISCH_TAC `sum (L2:real^3->bool) tt = &1` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ EXPAND_TAC "L2" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN (* Abbreviations *) ABBREV_TAC `p0 = omega_list_n V vl i` THEN ABBREV_TAC `p = inv (&1 - a) % vsum Lu (\x : real^3. ss x % x)` THEN ABBREV_TAC `p' = inv (&1 - b) % vsum Lv (\x : real^3. tt x % x)` THEN ABBREV_TAC `Lu_le = IMAGE (omega_list_n V ul) {j | j <= i}` THEN ABBREV_TAC `Lv_le = IMAGE (omega_list_n V vl) {j | j <= i}` THEN (* a = sum {j < i} ss + ss p0 *) SUBGOAL_THEN `a = sum (Lu_le DELETE p0 : real^3) ss + ss p0` ASSUME_TAC THENL [ MP_TAC (ISPECL[`ss:real^3->real`; `Lu_le:real^3->bool`; `p0:real^3`] SUM_DELETE) THEN ANTS_TAC THEN EXPAND_TAC "Lu_le" THENL [ CONJ_TAC THENL [ MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LE]; ALL_TAC ] THEN EXPAND_TAC "p0" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LE_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; ALL_TAC ] THEN (* b = sum {j < i} tt + tt p0 *) SUBGOAL_THEN `b = sum (Lv_le DELETE p0 : real^3) tt + tt p0` ASSUME_TAC THENL [ MP_TAC (ISPECL[`tt:real^3->real`; `Lv_le:real^3->bool`; `p0:real^3`] SUM_DELETE) THEN ANTS_TAC THEN EXPAND_TAC "Lv_le" THENL [ CONJ_TAC THENL [ MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LE]; ALL_TAC ] THEN EXPAND_TAC "p0" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LE_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; ALL_TAC ] THEN (* Lu_le = Lv_le *) SUBGOAL_THEN `Lu_le = Lv_le : real^3->bool` (LABEL_TAC "L_eq") THENL [ EXPAND_TAC "Lu_le" THEN EXPAND_TAC "Lv_le" THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[] THENL [ MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN (* sum {j < i} ss = sum {j < i} tt *) SUBGOAL_THEN `sum (Lv_le DELETE p0 : real^3) ss = sum (Lv_le DELETE p0) tt` ASSUME_TAC THENL [ MATCH_MP_TAC SUM_EQ THEN POP_ASSUM (fun th -> ALL_TAC) THEN EXPAND_TAC "Lv_le" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM; IN_DELETE] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN SUBGOAL_THEN `~(x' = i:num)` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN REWRITE_TAC[CONTRAPOS_THM] THEN EXPAND_TAC "p0" THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[LT_LE] THEN REWRITE_TAC[GSYM LT_LE] THEN ANTS_TAC THENL [ MATCH_MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `&1 - a = &1 - b ==> (ss:real^3->real) p0 = tt p0` MATCH_MP_TAC THENL [ ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC (ISPEC `voronoi_list V (truncate_simplex i ul)` ODIGPXU) THEN EXISTS_TAC `voronoi_list V (truncate_simplex (i + 1) vl)` THEN EXISTS_TAC `voronoi_list V (truncate_simplex (i + 1) ul)` THEN MAP_EVERY EXISTS_TAC [`p0:real^3`; `p':real^3`; `p:real^3`] THEN REPEAT STRIP_TAC THENL [ (* polyhedron *) MATCH_MP_TAC POLYHEDRON_VORONOI_LIST THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `set_of_list ul : real^3->bool` THEN CONJ_TAC THENL [ MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[] THEN MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i + 1 <= 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[]; (* p0 IN polyhedron *) ASM_SIMP_TAC[] THEN EXPAND_TAC "p0" THEN MATCH_MP_TAC OMEGA_LIST_N_IN_VORONOI_LIST THEN EXISTS_TAC `3` THEN MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i <= 3`) THEN ASM_SIMP_TAC[]; (* ~(p0 IN F UNION F') *) POP_ASSUM MP_TAC THEN REWRITE_TAC[IN_UNION] THEN STRIP_TAC THENL [ POP_ASSUM MP_TAC THEN EXPAND_TAC "p0" THEN REWRITE_TAC[ARITH_RULE `i + 1 = SUC i`] THEN DISCH_THEN (MP_TAC o MATCH_MP OMEGA_LIST_N_EQ) THEN REWRITE_TAC[] THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "p0" THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[ARITH_RULE `~(SUC i = i)`] THEN MATCH_MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> SUC i < 4 /\ i < 4`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REPLICATE_TAC 2 (FIRST_X_ASSUM (MP_TAC o SPEC `i:num`)) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN DISCH_TAC THEN REWRITE_TAC[ARITH_RULE `i + 1 = SUC i`] THEN DISCH_THEN (MP_TAC o MATCH_MP OMEGA_LIST_N_EQ) THEN REWRITE_TAC[] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "p0" THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[ARITH_RULE `~(SUC i = i)`] THEN MATCH_MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> SUC i < 4 /\ i < 4`) THEN ASM_REWRITE_TAC[]; (* F facet_of polyhedron *) MP_TAC (SPECL[`V:real^3->bool`; `vl:(real^3)list`; `3`; `i:num`] OMEGA_LIST_N_IN_FACET) THEN ASM_SIMP_TAC[] THEN MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i < 3`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; (* F' facet_of polyhedron *) MP_TAC (SPECL[`V:real^3->bool`; `ul:(real^3)list`; `3`; `i:num`] OMEGA_LIST_N_IN_FACET) THEN ASM_REWRITE_TAC[] THEN MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i < 3`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; (* p' IN F *) MP_TAC (ISPEC `voronoi_list V (truncate_simplex (i + 1) vl)` CONVEX_HULL_EQ) THEN REWRITE_TAC[CONVEX_VORONOI_LIST] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[SYM th]) THEN REWRITE_TAC[CONVEX_HULL_EXPLICIT; IN_ELIM_THM] THEN EXISTS_TAC `Lv : real^3->bool` THEN EXISTS_TAC `\x:real^3. inv (&1 - b) * tt x` THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "Lv" THEN MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j < 4}` THEN REWRITE_TAC[FINITE_NUMSEG_LT] THEN SIMP_TAC[SUBSET; IN_ELIM_THM]; EXPAND_TAC "Lv" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL[`V:real^3->bool`; `vl:(real^3)list`; `3`; `i:num`] OMEGA_LIST_N_IN_FACET) THEN ANTS_TAC THEN ASM_REWRITE_TAC[] THENL [ MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i < 3`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[ARITH_RULE `x' <= 3 <=> x' < 4`]; REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[REAL_LE_INV_EQ; REAL_LE_LT] THEN REWRITE_TAC[GSYM REAL_LE_LT] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "Lv" THEN EXPAND_TAC "L2" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ASM_REWRITE_TAC[SUM_LMUL] THEN MP_TAC (REAL_ARITH `~(b = &1) ==> ~(&1 - b = &0)`) THEN ASM_SIMP_TAC[REAL_MUL_LINV]; ALL_TAC ] THEN REPLICATE_TAC 4 (POP_ASSUM (fun th -> ALL_TAC)) THEN ASM_REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL]; (* p IN F' *) REPLICATE_TAC 4 (POP_ASSUM (fun th -> ALL_TAC)) THEN MP_TAC (ISPEC `voronoi_list V (truncate_simplex (i + 1) ul)` CONVEX_HULL_EQ) THEN REWRITE_TAC[CONVEX_VORONOI_LIST] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[SYM th]) THEN REWRITE_TAC[CONVEX_HULL_EXPLICIT; IN_ELIM_THM] THEN EXISTS_TAC `Lu : real^3->bool` THEN EXISTS_TAC `\x:real^3. inv (&1 - a) * ss x` THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "Lu" THEN MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j < 4}` THEN REWRITE_TAC[FINITE_NUMSEG_LT] THEN SIMP_TAC[SUBSET; IN_ELIM_THM]; EXPAND_TAC "Lu" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL[`V:real^3->bool`; `ul:(real^3)list`; `3`; `i:num`] OMEGA_LIST_N_IN_FACET) THEN ANTS_TAC THEN ASM_REWRITE_TAC[] THENL [ MP_TAC (ARITH_RULE `i < k /\ k <= 3 ==> i < 3`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[ARITH_RULE `x' <= 3 <=> x' < 4`]; REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[REAL_LE_INV_EQ; REAL_LE_LT] THEN REWRITE_TAC[GSYM REAL_LE_LT] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "Lu" THEN EXPAND_TAC "L1" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ASM_REWRITE_TAC[SUM_LMUL] THEN ASM_SIMP_TAC[REAL_ARITH `~(a = &1) ==> ~(&1 - a = &0)`; REAL_MUL_LINV]; ALL_TAC ] THEN ASM_REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL]; (* &0 < &1 - b *) ASM_REWRITE_TAC[]; (* &0 < &1 - a *) ASM_REWRITE_TAC[]; ALL_TAC ] THEN (* b * p0 + (1 - b) * p' = a * p0 + (1 - a) * p *) REWRITE_TAC[REAL_ARITH `&1 - (&1 - b) = b`] THEN EXPAND_TAC "p" THEN EXPAND_TAC "p'" THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN SUBGOAL_THEN `(&1 - b) * inv (&1 - b) = &1 /\ (&1 - a) * inv (&1 - a) = &1` (fun th -> REWRITE_TAC[th]) THENL [ CONJ_TAC THEN MATCH_MP_TAC REAL_MUL_RINV THEN ASM_REWRITE_TAC[REAL_ARITH `~(&1 - b = &0) <=> ~(b = &1)`]; ALL_TAC ] THEN ASM_REWRITE_TAC[VECTOR_MUL_LID; VECTOR_ADD_RDISTRIB] THEN REWRITE_TAC[VECTOR_ARITH `(a + b) + c = (a + d) + e <=> b + c = d + e : real^3`] THEN (* vsum (Lv_le DELETE p0) ss = vsum (Lv_le DELETE p0) tt *) SUBGOAL_THEN `vsum (Lv_le DELETE p0) (\x:real^3. tt x % x) = vsum (Lv_le DELETE p0) (\x. ss x % x)` ASSUME_TAC THENL [ MATCH_MP_TAC VSUM_EQ THEN UNDISCH_TAC `Lu_le = Lv_le : real^3->bool` THEN DISCH_THEN (fun th -> ALL_TAC) THEN EXPAND_TAC "Lv_le" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM; IN_DELETE] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RCANCEL] THEN DISJ1_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN SUBGOAL_THEN `~(x' = i:num)` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN REWRITE_TAC[CONTRAPOS_THM] THEN EXPAND_TAC "p0" THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[LT_LE] THEN REWRITE_TAC[GSYM LT_LE] THEN ANTS_TAC THENL [ MATCH_MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k : num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ONCE_REWRITE_TAC[SPEC `vsum (Lv_le DELETE p0:real^3) (\x. tt x % x)` (VECTOR_ARITH `!x y z:real^3. y = z <=> x + y = x + z`)] THEN ONCE_REWRITE_TAC[VECTOR_ADD_ASSOC] THEN (* vsum {j < i} + vsum i = vsum {j <= i} *) SUBGOAL_THEN `vsum (Lv_le DELETE p0) (\x:real^3. tt x % x) + tt p0 % p0 = vsum Lv_le (\x. tt x % x)` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL[`\x:real^3. tt x % x`; `Lv_le:real^3->bool`; `p0:real^3`] VSUM_DELETE) THEN ANTS_TAC THEN EXPAND_TAC "Lv_le" THEN EXPAND_TAC "Lu_le" THENL [ CONJ_TAC THENL [ MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LE]; ALL_TAC ] THEN EXPAND_TAC "p0" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LE_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN (* vsum {j < i} + vsum i = vsum {j <= i} *) SUBGOAL_THEN `vsum (Lv_le DELETE p0) (\x:real^3. tt x % x) + ss p0 % p0 = vsum Lv_le (\x. ss x % x)` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL[`\x:real^3. ss x % x`; `Lv_le:real^3->bool`; `p0:real^3`] VSUM_DELETE) THEN ANTS_TAC THEN EXPAND_TAC "Lv_le" THEN EXPAND_TAC "Lu_le" THENL [ CONJ_TAC THENL [ MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LE]; ALL_TAC ] THEN EXPAND_TAC "p0" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LE_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `FINITE (Lv_le:real^3->bool) /\ FINITE (Lv:real^3->bool) /\ FINITE (Lu:real^3->bool)` ASSUME_TAC THENL [ MAP_EVERY EXPAND_TAC ["Lv_le"; "Lu_le"; "Lv"; "Lu"] THEN REPEAT CONJ_TAC THEN MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LE] THENL [ MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j < 4}` THEN SIMP_TAC[FINITE_NUMSEG_LT; SUBSET; IN_ELIM_THM]; MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j < 4}` THEN SIMP_TAC[FINITE_NUMSEG_LT; SUBSET; IN_ELIM_THM]; ]; ALL_TAC ] THEN SUBGOAL_THEN `DISJOINT (Lv_le:real^3->bool) Lv /\ DISJOINT (Lu_le:real^3->bool) Lu` ASSUME_TAC THENL [ MAP_EVERY EXPAND_TAC ["Lv_le"; "Lu_le"; "Lv"; "Lu"] THEN REWRITE_TAC[DISJOINT; EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL [`x':num`; `x'':num`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN MP_TAC (ARITH_RULE `x' <= i /\ i < x'' ==> ~(x' = x'':num)`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k ==> x' < k:num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL [`x':num`; `x'':num`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN MP_TAC (ARITH_RULE `x' <= i /\ i < x'' ==> ~(x' = x'':num)`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPECL[`\x:real^3. tt x % x`; `Lv_le:real^3->bool`; `Lv:real^3->bool`] VSUM_UNION) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL[`\x:real^3. ss x % x`; `Lv_le:real^3->bool`; `Lu:real^3->bool`] VSUM_UNION) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN (* Lv_le UNION Lv = L2 *) SUBGOAL_THEN `Lv_le UNION Lv = L2 /\ Lv_le UNION Lu = L1 : real^3->bool` (fun th -> REWRITE_TAC[th]) THENL [ CONJ_TAC THENL [ REMOVE_THEN "L_eq" (fun th -> ALL_TAC) THEN EXPAND_TAC "Lv_le" THEN EXPAND_TAC "L2" THEN EXPAND_TAC "Lv" THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `x' <= i : num` THENL [ DISJ1_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[NOT_LE]; ALL_TAC ] THEN EXPAND_TAC "Lv_le" THEN EXPAND_TAC "L1" THEN EXPAND_TAC "Lu" THEN EXPAND_TAC "Lu_le" THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' <= i /\ i < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `x' <= i : num` THENL [ DISJ1_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[NOT_LE]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (LABEL_TAC "ss_tt") THEN (* Continue the second step *) ABBREV_TAC `Lu_lt = IMAGE (omega_list_n V ul) {j | j < k}` THEN ABBREV_TAC `Lv_lt = IMAGE (omega_list_n V vl) {j | j < k}` THEN ABBREV_TAC `Lu_ge = IMAGE (omega_list_n V ul) {j | k <= j /\ j < 4}` THEN ABBREV_TAC `Lv_ge = IMAGE (omega_list_n V vl) {j | k <= j /\ j < 4}` THEN ABBREV_TAC `a = sum Lv_lt (ss:real^3->real)` THEN (* Lu_lt = Lv_lt *) SUBGOAL_THEN `Lu_lt = Lv_lt : real^3->bool` (LABEL_TAC "l_eq") THENL [ EXPAND_TAC "Lu_lt" THEN EXPAND_TAC "Lv_lt" THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN (* Unions *) SUBGOAL_THEN `Lv_lt UNION Lv_ge = L2 : real^3->bool /\ Lv_lt UNION Lu_ge = L1` ASSUME_TAC THENL [ CONJ_TAC THENL [ REMOVE_THEN "l_eq" (fun th -> ALL_TAC) THEN EXPAND_TAC "Lv_lt" THEN EXPAND_TAC "L2" THEN EXPAND_TAC "Lv_ge" THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `x' < k : num` THENL [ DISJ1_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[NOT_LT]; ALL_TAC ] THEN EXPAND_TAC "Lv_lt" THEN EXPAND_TAC "L1" THEN EXPAND_TAC "Lu_ge" THEN EXPAND_TAC "Lu_lt" THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `x' < k : num` THENL [ DISJ1_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[NOT_LT]; ALL_TAC ] THEN (* Disjoint sets *) SUBGOAL_THEN `DISJOINT (Lv_lt:real^3->bool) Lv_ge /\ DISJOINT (Lv_lt:real^3->bool) Lu_ge` ASSUME_TAC THENL [ MAP_EVERY EXPAND_TAC ["Lv_lt"; "Lu_lt"; "Lv_ge"; "Lu_ge"] THEN REWRITE_TAC[DISJOINT; EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL [`x':num`; `x'':num`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN MP_TAC (ARITH_RULE `x' < k /\ k <= x'' ==> ~(x' = x'':num)`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL [`x':num`; `x'':num`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN MP_TAC (ARITH_RULE `x' < k /\ k <= x'' ==> ~(x' = x'':num)`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN (* Finite sets *) SUBGOAL_THEN `FINITE (Lv_lt:real^3->bool) /\ FINITE (Lv_ge:real^3->bool) /\ FINITE (Lu_ge:real^3->bool)` ASSUME_TAC THENL [ MAP_EVERY EXPAND_TAC ["Lv_lt"; "Lv_ge"; "Lu_ge"; "Lu_lt"] THEN REPEAT CONJ_TAC THEN MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LT] THENL [ MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j < 4}` THEN SIMP_TAC[FINITE_NUMSEG_LT; SUBSET; IN_ELIM_THM]; ALL_TAC ] THEN MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j < 4}` THEN SIMP_TAC[FINITE_NUMSEG_LT; SUBSET; IN_ELIM_THM]; ALL_TAC ] THEN (* vsum Lv_lt ss = vsum Lv_lt tt *) SUBGOAL_THEN `vsum Lv_lt (\x:real^3. ss x % x) = vsum Lv_lt (\x:real^3. tt x % x)` ASSUME_TAC THENL [ MATCH_MP_TAC VSUM_EQ THEN EXPAND_TAC "Lv_lt" THEN EXPAND_TAC "Lu_lt" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_RCANCEL] THEN DISJ1_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN (* sum Lv_lt tt = a *) SUBGOAL_THEN `sum Lv_lt (tt:real^3->real) = a` ASSUME_TAC THENL [ EXPAND_TAC "a" THEN EXPAND_TAC "Lv_lt" THEN EXPAND_TAC "Lu_lt" THEN MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN (* w = w_lt + w_ge *) MP_TAC (ISPECL[`\x:real^3. ss x % x`; `Lv_lt:real^3->bool`; `Lu_ge:real^3->bool`] VSUM_UNION) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "wu" o SYM) THEN MP_TAC (ISPECL[`\x:real^3. tt x % x`; `Lv_lt:real^3->bool`; `Lv_ge:real^3->bool`] VSUM_UNION) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "wv" o SYM) THEN (* 1 = a + (1 - a) *) MP_TAC (ISPECL[`ss:real^3->real`; `Lv_lt:real^3->bool`; `Lu_ge:real^3->bool`] SUM_UNION) THEN MP_TAC (ISPECL[`tt:real^3->real`; `Lv_lt:real^3->bool`; `Lv_ge:real^3->bool`] SUM_UNION) THEN ASM_REWRITE_TAC[REAL_ARITH `&1 = a + x <=> x = &1 - a`] THEN DISCH_TAC THEN DISCH_TAC THEN (* &1 - a != 0 *) SUBGOAL_THEN `~(&1 - a = &0)` ASSUME_TAC THENL [ ASM_CASES_TAC `?p:real^3. p IN Lv_lt` THENL [ POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "Lv_lt" THEN EXPAND_TAC "Lu_lt" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN REMOVE_THEN "not1" (MP_TAC o SPEC `k - 1`) THEN MP_TAC (ARITH_RULE `x < k ==> k - 1 < k`) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[ARITH_RULE `k - 1 < k ==> (j <= k - 1 <=> j < k)`] THEN SIMP_TAC[ARITH_RULE `~(a = &1) ==> ~(&1 - a = &0)`]; ALL_TAC ] THEN EXPAND_TAC "a" THEN SUBGOAL_THEN `Lv_lt = {} : real^3->bool` (fun th -> REWRITE_TAC[th]) THENL [ ASM_REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; GSYM NOT_EXISTS_THM]; ALL_TAC ] THEN REWRITE_TAC[SUM_CLAUSES; REAL_SUB_RZERO] THEN REAL_ARITH_TAC; ALL_TAC ] THEN (* &0 < &1 - a *) SUBGOAL_THEN `&0 < &1 - a` ASSUME_TAC THENL [ ASM_REWRITE_TAC[REAL_LT_LE] THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC SUM_POS_LE THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "Lu_ge" THEN EXPAND_TAC "L1" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `p:real^3 = inv (&1 - a) % vsum Lv_ge (\x. tt x % x)` THEN EXPAND_TAC "YX" THEN REWRITE_TAC[CONVEX_HULL_EXPLICIT; IN_ELIM_THM] THEN EXISTS_TAC `Lv_lt UNION {p:real^3}` THEN EXISTS_TAC `\x:real^3. if x = p then (&1 - a) else tt x` THEN (* p IN X *) SUBGOAL_THEN `p:real^3 IN X` ASSUME_TAC THENL [ EXPAND_TAC "X" THEN REWRITE_TAC[IN_INTER] THEN MP_TAC (ISPEC `voronoi_list V (truncate_simplex k vl)` CONVEX_HULL_EQ) THEN MP_TAC (ISPEC `voronoi_list V (truncate_simplex k ul)` CONVEX_HULL_EQ) THEN REWRITE_TAC[CONVEX_VORONOI_LIST] THEN REPEAT (DISCH_THEN (fun th -> ONCE_REWRITE_TAC[SYM th])) THEN REWRITE_TAC[CONVEX_HULL_EXPLICIT; IN_ELIM_THM] THEN CONJ_TAC THENL [ EXISTS_TAC `Lu_ge : real^3->bool` THEN EXISTS_TAC `\x:real^3. inv (&1 - a) * ss x` THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "Lu_ge" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC OMEGA_LIST_N_IN_VORONOI_LIST_GEN THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[ARITH_RULE `x' <= 3 <=> x' < 4`]; MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[REAL_LE_INV_EQ; REAL_LE_LT] THEN REWRITE_TAC[GSYM REAL_LE_LT] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "Lu_ge" THEN EXPAND_TAC "L1" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ASM_SIMP_TAC[SUM_LMUL; REAL_MUL_LINV]; ALL_TAC ] THEN REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL] THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[VECTOR_MUL_LCANCEL] THEN DISJ2_TAC THEN REMOVE_THEN "wu" MP_TAC THEN REMOVE_THEN "wv" (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[VECTOR_ARITH `x + a = x + b <=> a = b:real^3`]; ALL_TAC ] THEN EXISTS_TAC `Lv_ge : real^3->bool` THEN EXISTS_TAC `\x:real^3. inv (&1 - a) * tt x` THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "Lv_ge" THEN REWRITE_TAC[SUBSET; IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC OMEGA_LIST_N_IN_VORONOI_LIST_GEN THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[ARITH_RULE `x' <= 3 <=> x' < 4`]; MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[REAL_LE_INV_EQ; REAL_LE_LT] THEN REWRITE_TAC[GSYM REAL_LE_LT] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "Lv_ge" THEN EXPAND_TAC "L2" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN ASM_REWRITE_TAC[]; ASM_SIMP_TAC[SUM_LMUL; REAL_MUL_LINV]; ALL_TAC ] THEN ASM_REWRITE_TAC[GSYM VECTOR_MUL_ASSOC; VSUM_LMUL]; ALL_TAC ] THEN (* ~(p IN Lv_lt) *) SUBGOAL_THEN `~(p:real^3 IN Lv_lt)` ASSUME_TAC THENL [ EXPAND_TAC "Lv_lt" THEN EXPAND_TAC "Lu_lt" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL[`V:real^3->bool`; `ul:(real^3)list`] ROGERS_AFF_DIM_FULL) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPECL[`x:num`; `SUC x`]) THEN ANTS_TAC THENL [ MP_TAC (ARITH_RULE `x < k /\ k <= 3 ==> x < 4 /\ SUC x < 4`) THEN ASM_SIMP_TAC[ARITH_RULE `~(x = SUC x)`]; ALL_TAC ] THEN REWRITE_TAC[] THEN MATCH_MP_TAC EQ_SYM THEN MATCH_MP_TAC OMEGA_LIST_N_EQ_GEN THEN EXISTS_TAC `3` THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM (fun th -> ALL_TAC) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "X" THEN SIMP_TAC[IN_INTER]; ALL_TAC ] THEN REPEAT CONJ_TAC THENL [ (* FINITE (Lv_lt UNION {p}) *) ASM_REWRITE_TAC[FINITE_UNION; FINITE_SING]; (* Lv_lt UNION {p} SUBSET Y UNION X *) EXPAND_TAC "Y" THEN REMOVE_THEN "l_eq" (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[SUBSET; IN_UNION; IN_SING] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[]; (* &0 <= f x *) REWRITE_TAC[IN_UNION; IN_SING] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL [ COND_CASES_TAC THENL [ UNDISCH_TAC `~(p:real^3 IN Lv_lt)` THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "L2" THEN REMOVE_THEN "l_eq" (fun th -> ALL_TAC) THEN EXPAND_TAC "Lv_lt" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < k /\ k <= 3 ==> x' < 4`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[REAL_LE_LT]; (* sum = &1 *) MP_TAC (ISPECL[`\x:real^3. if x = p then &1 - a else tt x`; `Lv_lt:real^3->bool`; `{p:real^3}`] SUM_UNION) THEN ASM_REWRITE_TAC[FINITE_SING; DISJOINT; EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_SING] THEN ANTS_TAC THENL [ GEN_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN ASM_CASES_TAC `x = p:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th; SUM_SING]) THEN SUBGOAL_THEN `sum Lv_lt (\x:real^3. if x = p then &1 - a else tt x) = sum Lv_lt tt` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC SUM_EQ THEN REPEAT STRIP_TAC THEN BETA_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `~(p:real^3 IN Lv_lt)` THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC; ALL_TAC ] THEN (* vsum = w *) REWRITE_TAC[] THEN MP_TAC (ISPECL[`\v:real^3. (if v = p then &1 - a else tt v) % v`; `Lv_lt:real^3->bool`; `{p:real^3}`] VSUM_UNION) THEN ASM_REWRITE_TAC[FINITE_SING; DISJOINT; EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_SING] THEN ANTS_TAC THENL [ GEN_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN ASM_CASES_TAC `x = p:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th; VSUM_SING]) THEN SUBGOAL_THEN `vsum Lv_lt (\v:real^3. (if v = p then &1 - a else tt v) % v) = vsum Lv_lt (\v. tt v % v)` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC VSUM_EQ THEN REPEAT STRIP_TAC THEN BETA_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `~(p:real^3 IN Lv_lt)` THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN EXPAND_TAC "p" THEN REMOVE_THEN "wv" (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID]; ALL_TAC ] THEN (* The third step *) DISCH_THEN (LABEL_TAC "conv") THEN MATCH_MP_TAC AFF_DIM_LE_2_IMP_COPLANAR THEN MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim (convex hull (Y UNION X:real^3->bool))` THEN POP_ASSUM (fun th -> SIMP_TAC[MATCH_MP AFF_DIM_SUBSET th]) THEN REWRITE_TAC[AFF_DIM_CONVEX_HULL] THEN SUBGOAL_THEN `FINITE (Y:real^3->bool)` ASSUME_TAC THENL [ EXPAND_TAC "Y" THEN MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG_LT]; ALL_TAC ] THEN (* CARD Y <= k *) SUBGOAL_THEN `CARD (Y:real^3->bool) <= k` ASSUME_TAC THENL [ MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD {j | j < k : num}` THEN CONJ_TAC THENL [ EXPAND_TAC "Y" THEN MP_TAC (ISPECL[`omega_list_n V ul`; `{j | j < k : num}`] CARD_IMAGE_LE) THEN SIMP_TAC[FINITE_NUMSEG_LT]; ALL_TAC ] THEN REWRITE_TAC[CARD_NUMSEG_LT; LE_REFL]; ALL_TAC ] THEN MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `&(CARD (Y:real^3->bool)) + aff_dim (X:real^3->bool)` THEN CONJ_TAC THENL [ MATCH_MP_TAC AFF_DIM_FINITE_UNION_LE THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN (* aff dim X <= 2 - k *) SUBGOAL_THEN `aff_dim (X:real^3->bool) <= &2 - &k` MP_TAC THENL [ ABBREV_TAC `Fu = voronoi_list V (truncate_simplex k ul)` THEN ABBREV_TAC `Fv = voronoi_list V (truncate_simplex k vl)` THEN (* k = 0 \/ 0 < k *) DISJ_CASES_TAC (ARITH_RULE `k = 0 \/ 0 < k`) THENL [ UNDISCH_TAC `~(Fu = Fv : real^3->bool)` THEN MP_TAC (ISPEC `ul:(real^3)list` TRUNCATE_0_EQ_HEAD) THEN MP_TAC (ISPEC `vl:(real^3)list` TRUNCATE_0_EQ_HEAD) THEN ASM_REWRITE_TAC[ARITH] THEN MAP_EVERY EXPAND_TAC ["X"; "Fu"; "Fv"] THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REPLICATE_TAC 2 (DISCH_THEN (fun th -> REWRITE_TAC[th])) THEN REWRITE_TAC[VORONOI_LIST_SING] THEN DISCH_TAC THEN MATCH_MP_TAC INT_LE_TRANS THEN EXISTS_TAC `aff_dim ({x : real^3 | &2 % (HD ul - HD vl) dot x = norm (HD ul) pow 2 - norm (HD vl) pow 2})` THEN SUBGOAL_THEN `!l:(real^3)list. barV V 3 l ==> HD l IN V` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `set_of_list l : real^3->bool` THEN CONJ_TAC THENL [ MATCH_MP_TAC BARV_IMP_HD_IN_SET_OF_LIST THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `3`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN FIRST_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN CONJ_TAC THENL [ MATCH_MP_TAC AFF_DIM_SUBSET THEN MATCH_MP_TAC Pack2.INTER_VORONOI_SUBSET_BISECTOR THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `int_of_num 2 - &0 = &(dimindex (:3)) - &1` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[DIMINDEX_3] THEN INT_ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC (INT_ARITH `a = b ==> a <= b : int`) THEN MATCH_MP_TAC AFF_DIM_HYPERPLANE THEN REWRITE_TAC[VECTOR_MUL_EQ_0; INT_ARITH `~(&2 = &0)`; VECTOR_SUB_EQ] THEN DISCH_TAC THEN UNDISCH_TAC `~(voronoi_closed V (HD ul) = voronoi_closed V (HD vl):real^3->bool)` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN (* 0 < k *) ABBREV_TAC `P = voronoi_list V (truncate_simplex (k - 1) vl) : real^3->bool` THEN (* Fu facet_of P /\ Fv facet_of P *) SUBGOAL_THEN `Fu facet_of P /\ Fv facet_of P : real^3->bool` STRIP_ASSUME_TAC THENL [ CONJ_TAC THENL [ MP_TAC (SPECL[`V:real^3->bool`; `truncate_simplex (k - 1) ul:(real^3)list`; `k - 1`; `Fu:real^3->bool`] IDBEZAL) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `k <= 3 ==> k - 1 < 3`] THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `3` THEN ASM_SIMP_TAC[ARITH_RULE `k <= 3 ==> k - 1 <= 3`]; ALL_TAC ] THEN SUBGOAL_THEN `voronoi_list V (truncate_simplex (k - 1) ul) = P : real^3->bool` MP_TAC THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `k - 1`) THEN ASM_SIMP_TAC[ARITH_RULE `0 < k ==> k - 1 < k`]; ALL_TAC ] THEN REPEAT (DISCH_THEN (fun th -> REWRITE_TAC[th])) THEN EXISTS_TAC `truncate_simplex k ul:(real^3)list` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `0 < k ==> k - 1 + 1 = k`] THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC TRUNCATE_TRUNCATE_SIMPLEX THEN ASM_SIMP_TAC[ARITH_RULE `k <= 3 ==> k + 1 <= 4`; ARITH_RULE `k - 1 <= k`]; ALL_TAC ] THEN MP_TAC (SPECL[`V:real^3->bool`; `truncate_simplex (k - 1) vl:(real^3)list`; `k - 1`; `Fv:real^3->bool`] IDBEZAL) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `k <= 3 ==> k - 1 < 3`] THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `3` THEN ASM_SIMP_TAC[ARITH_RULE `k <= 3 ==> k - 1 <= 3`]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN EXISTS_TAC `truncate_simplex k vl:(real^3)list` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `0 < k ==> k - 1 + 1 = k`] THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC TRUNCATE_TRUNCATE_SIMPLEX THEN ASM_SIMP_TAC[ARITH_RULE `k <= 3 ==> k + 1 <= 4`; ARITH_RULE `k - 1 <= k`]; ALL_TAC ] THEN FIRST_ASSUM (MP_TAC o MATCH_MP FACET_OF_IMP_FACE_OF) THEN POP_ASSUM MP_TAC THEN FIRST_ASSUM (MP_TAC o MATCH_MP FACET_OF_IMP_FACE_OF) THEN POP_ASSUM (LABEL_TAC "Fu_facet") THEN MAP_EVERY (fun s -> DISCH_THEN (LABEL_TAC s)) ["Fu_face"; "Fv_facet"; "Fv_face"] THEN MP_TAC (ISPECL[`Fu:real^3->bool`; `P:real^3->bool`; `Fv:real^3->bool`; `P:real^3->bool`] FACE_OF_INTER_INTER) THEN ASM_REWRITE_TAC[INTER_ACI] THEN DISCH_TAC THEN REMOVE_THEN "Fu_face" (MP_TAC o SPEC `X:real^3->bool` o MATCH_MP FACE_OF_FACE) THEN REMOVE_THEN "Fv_face" (MP_TAC o SPEC `X:real^3->bool` o MATCH_MP FACE_OF_FACE) THEN SUBGOAL_THEN `X SUBSET Fv /\ X SUBSET Fu:real^3->bool` (fun th -> ASM_REWRITE_TAC[th]) THENL [ MAP_EVERY EXPAND_TAC ["X"; "Fv"; "Fu"] THEN REWRITE_TAC[INTER_SUBSET]; ALL_TAC ] THEN ASM_CASES_TAC `X = Fv : real^3->bool /\ X = Fu : real^3->bool` THENL [ UNDISCH_TAC `~(Fu = Fv:real^3->bool)` THEN POP_ASSUM (fun th -> REWRITE_TAC[GSYM th]); ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN REPEAT STRIP_TAC THENL [ MP_TAC (ISPECL[`X:real^3->bool`; `Fv:real^3->bool`] FACE_OF_AFF_DIM_LT) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "Fv" THEN REWRITE_TAC[CONVEX_VORONOI_LIST]; ALL_TAC ] THEN MP_TAC (SPECL[`V:real^3->bool`; `vl:(real^3)list`; `3`; `k:num`] VORONOI_LIST_AFF_DIM) THEN ASM_SIMP_TAC[] THEN INT_ARITH_TAC; ALL_TAC ] THEN MP_TAC (ISPECL[`X:real^3->bool`; `Fu:real^3->bool`] FACE_OF_AFF_DIM_LT) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "Fu" THEN REWRITE_TAC[CONVEX_VORONOI_LIST]; ALL_TAC ] THEN MP_TAC (SPECL[`V:real^3->bool`; `ul:(real^3)list`; `3`; `k:num`] VORONOI_LIST_AFF_DIM) THEN ASM_SIMP_TAC[] THEN INT_ARITH_TAC; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN INT_ARITH_TAC);; (***************************************************) (****************) (* Circumcenter *) (****************) (* QXSKIIT *)
let AFFINE_INDEPENDENT_IMP_INDEPENDENT = 
prove(`!S:real^N->bool. ~affine_dependent S ==> (!x. x IN S ==> independent {y - x | y | y IN (S DELETE x)})`,
REPEAT STRIP_TAC THEN REWRITE_TAC[independent; DEPENDENT_AFFINE_DEPENDENT_CASES; DE_MORGAN_THM] THEN CONJ_TAC THENL [ MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `IMAGE (\y:real^N. --x + y) S` THEN ASM_REWRITE_TAC[AFFINE_DEPENDENT_TRANSLATION_EQ] THEN REWRITE_TAC[IMAGE_LEMMA; VECTOR_ARITH `--x + y:real^N = y - x`] THEN REWRITE_TAC[IN_DELETE; SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `u:real^N` THEN STRIP_TAC THEN EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `{y - x | y | y IN S DELETE x} = IMAGE (\y:real^N. --x + y) (S DELETE x)` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[IMAGE_LEMMA; VECTOR_ARITH `--x + y:real^N = y - x`]; ALL_TAC ] THEN REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN REWRITE_TAC[VECTOR_ARITH `vec 0 = --x + x' <=> x' = x:real^N`] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN UNDISCH_TAC `~affine_dependent (S:real^N->bool)` THEN ASM_REWRITE_TAC[CONTRAPOS_THM; affine_dependent] THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[]);;
let ORTHOGONAL_TO_SPAN_EXISTS = 
prove(`!(s:real^N->bool) t. s SUBSET span t /\ dim s < dim t ==> ?v. ~(v = vec 0) /\ v IN span t /\ (!x. x IN s ==> x dot v = &0)`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `span s SUBSET span (t:real^N->bool)` ASSUME_TAC THENL [ GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM SPAN_SPAN] THEN MATCH_MP_TAC SPAN_MONO THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `?y:real^N. y IN span t /\ ~(y IN span s)` CHOOSE_TAC THENL [ UNDISCH_TAC `dim (s:real^N->bool) < dim (t:real^N->bool)` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(A /\ ~B) <=> (A ==> B)`; GSYM SUBSET] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP; SUBSET_ANTISYM_EQ] THEN DISCH_TAC THEN MATCH_MP_TAC (ARITH_RULE `a:num = b ==> ~(a < b)`) THEN MATCH_MP_TAC SPAN_EQ_DIM THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (SPEC `span (s:real^N->bool)` ORTHOGONAL_BASIS_SUBSPACE) THEN REWRITE_TAC[SUBSPACE_SPAN; DIM_SPAN] THEN STRIP_TAC THEN ABBREV_TAC `v:real^N = (y - vsum b (\v. (v dot y) / (v dot v) % v))` THEN EXISTS_TAC `v:real^N` THEN REPEAT CONJ_TAC THENL [ POP_ASSUM (LABEL_TAC "A") THEN DISCH_TAC THEN REMOVE_THEN "A" MP_TAC THEN ASM_REWRITE_TAC[VECTOR_SUB_EQ] THEN DISCH_TAC THEN SUBGOAL_THEN `y:real^N IN span b` MP_TAC THENL [ REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC [`b:real^N->bool`; `\v:real^N. (v dot y) / (v dot v)`] THEN ASM_REWRITE_TAC[EQ_SYM_EQ; SUBSET_REFL] THEN CONJ_TAC THENL [ UNDISCH_TAC `b:real^N->bool HAS_SIZE dim (s:real^N->bool)` THEN SIMP_TAC[HAS_SIZE]; ALL_TAC ] THEN POP_ASSUM ACCEPT_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[]; EXPAND_TAC "v" THEN MATCH_MP_TAC SPAN_SUB THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `span (s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_VSUM THEN UNDISCH_TAC `b:real^N->bool HAS_SIZE dim (s:real^N->bool)` THEN SIMP_TAC[HAS_SIZE] THEN DISCH_TAC THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `b:real^N->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL [`b:real^N->bool`; `y:real^N`; `x:real^N`] GRAM_SCHMIDT_STEP) THEN ASM_REWRITE_TAC[orthogonal] THEN ANTS_TAC THEN REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SPAN_INC]);;
let INDEPENDENT_EXPLICIT_NUMSEG = 
prove(`!(v:num->real^N) f n. (!i j. i IN (1..n) /\ j IN (1..n) /\ v i = v j ==> i = j) /\ independent (IMAGE v (1..n)) /\ vsum (1..n) (\i. f i % v i) = vec 0 ==> (!i. i IN 1..n ==> f i = &0)`,
REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`v:num->real^N`; `1..n`] INJECTIVE_ON_LEFT_INVERSE) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN SUBGOAL_THEN `vsum (1..n) (\i. f i % v i) = vsum (IMAGE v (1..n)) (\x:real^N. f (g x) % x)` MP_TAC THENL [ MP_TAC (ISPECL [`\i:num. f i % v i:real^N`; `1..n`] VSUM_RESTRICT) THEN REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN SUBGOAL_THEN `(\x:num. if x IN 1..n then f x % v x else vec 0) = (\i:num. if i IN 1..n then ((\x:real^N. f (g x) % x) o v) i else vec 0)` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[FUN_EQ_THM; o_THM] THEN GEN_TAC THEN COND_CASES_TAC THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `x:num`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]); ALL_TAC ] THEN REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPECL [`(\x:real^N. f ((g:real^N->num) x) % x) o (v:num->real^N)`; `1..n`] VSUM_RESTRICT) THEN REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MATCH_MP_TAC (GSYM VSUM_IMAGE) THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN UNDISCH_TAC `vsum (1..n) (\i. f i % v i) = vec 0:real^N` THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN MP_TAC (ISPEC `IMAGE (v:num->real^N) (1..n)` INDEPENDENT_EXPLICIT) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN DISCH_THEN (fun th -> (FIRST_X_ASSUM (MP_TAC o (fun th2 -> MATCH_MP th2 th)))) THEN DISCH_THEN (MP_TAC o SPEC `(v:num->real^N) i`) THEN REWRITE_TAC[IN_IMAGE] THEN ANTS_TAC THENL [ EXISTS_TAC `i:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[]);;
let ORTHOGONAL_TO_ALL_IMP_ZERO = 
prove(`!(v:real^N) s. v IN span s /\ (!x. x IN s ==> v dot x = &0) ==> v = vec 0`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`span (s:real^N->bool)`; `span {v:real^N}`; `v:real^N`; `vec 0:real^N`; `vec 0:real^N`; `v:real^N`] ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE) THEN ANTS_TAC THENL [ REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[SPAN_SPAN; SPAN_0] THENL [ MP_TAC (ISPECL [`s:real^N->bool`; `b:real^N`] ORTHOGONAL_TO_SPAN) THEN ANTS_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[orthogonal] THEN UNDISCH_TAC `b IN span {v:real^N}` THEN REWRITE_TAC[SPAN_SING; IN_ELIM_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[DOT_LMUL; REAL_ENTIRE] THEN DISJ2_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPEC `a:real^N`) THEN ASM_SIMP_TAC[ORTHOGONAL_SYM]; MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `{v:real^N}` THEN REWRITE_TAC[SPAN_INC; IN_SING]; VECTOR_ARITH_TAC ]; ALL_TAC ] THEN STRIP_TAC);;
let UNIQUE_SOLUTION_lemma = 
prove(`!(S:real^N->bool) b. independent S ==> ?!p. p IN span S /\ (!x. x IN S ==> p dot x = b x)`,
REPEAT STRIP_TAC THEN ABBREV_TAC `n = dim (span (S:real^N->bool))` THEN SUBGOAL_THEN `?w:num->real^N. S = IMAGE w (1..n) /\ (!i j. i IN (1..n) /\ j IN (1..n) /\ w i = w j ==> i = j)` MP_TAC THENL [ SUBGOAL_THEN `FINITE S /\ CARD (S:real^N->bool) = dim (span S)` ASSUME_TAC THENL [ REWRITE_TAC[GSYM HAS_SIZE] THEN MATCH_MP_TAC BASIS_HAS_SIZE_DIM THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPEC `S:real^N->bool` FINITE_INDEX_NUMSEG) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `f:num->real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN ABBREV_TAC `f:real^N->real^N = (\p:real^N. (lambda i. if i <= n then p dot (w i) else &0))` THEN ABBREV_TAC `P:real^N->bool = IMAGE f (span (S:real^N->bool))` THEN ABBREV_TAC `t:real^N->bool = IMAGE basis (1..n)` THEN SUBGOAL_THEN `P:real^N->bool SUBSET span t` ASSUME_TAC THENL [ REPLICATE_TAC 2 (POP_ASSUM (fun th -> REWRITE_TAC[SYM th])) THEN REWRITE_TAC[SUBSET; IN_SPAN_IMAGE_BASIS] THEN GEN_TAC THEN EXPAND_TAC "f" THEN REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (is_forall o concl)) THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[DE_MORGAN_THM]; ALL_TAC ] THEN SUBGOAL_THEN `subspace (P:real^N->bool)` ASSUME_TAC THENL [ REWRITE_TAC[subspace] THEN EXPAND_TAC "P" THEN REWRITE_TAC[IN_IMAGE] THEN REPEAT CONJ_TAC THENL [ EXISTS_TAC `vec 0:real^N` THEN REWRITE_TAC[SPAN_0] THEN EXPAND_TAC "f" THEN REWRITE_TAC[DOT_LZERO] THEN VECTOR_ARITH_TAC; REPEAT STRIP_TAC THEN EXISTS_TAC `x' + x'':real^N` THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "f" THEN REWRITE_TAC[DOT_LADD] THEN SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; LAMBDA_BETA] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[]; REPEAT STRIP_TAC THEN EXISTS_TAC `c % x':real^N` THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "f" THEN SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; LAMBDA_BETA; DOT_LMUL] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] ]; ALL_TAC ] THEN SUBGOAL_THEN `P:real^N->bool = span t` ASSUME_TAC THENL [ ASM_CASES_TAC `P:real^N->bool = span t` THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPECL [`P:real^N->bool`; `t:real^N->bool`] ORTHOGONAL_TO_SPAN_EXISTS) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC DIM_PSUBSET THEN REWRITE_TAC[PSUBSET] THEN SUBGOAL_THEN `span P = P:real^N->bool` (fun th -> REWRITE_TAC[th]) THENL [ ASM_REWRITE_TAC[SPAN_EQ_SELF]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN ABBREV_TAC `p:real^N = vsum (1..n) (\i. (v:real^N)$i % w i)` THEN POP_ASSUM (LABEL_TAC "p") THEN SUBGOAL_THEN `(f:real^N->real^N) p IN P` ASSUME_TAC THENL [ EXPAND_TAC "P" THEN REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `p:real^N` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "p" THEN MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `IMAGE (w:num->real^N) (1..n)` THEN REWRITE_TAC[SPAN_INC; IN_IMAGE] THEN EXISTS_TAC `x:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `p:real^N dot p = &0` MP_TAC THENL [ REMOVE_THEN "p" (fun th -> GEN_REWRITE_TAC (PAT_CONV `\p:real^N. a dot p = &0`) [SYM th]) THEN SIMP_TAC[FINITE_NUMSEG; DOT_RSUM] THEN REWRITE_TAC[DOT_RMUL] THEN SUBGOAL_THEN `sum (1..n) (\y. v$y * (p dot w y)) = (v:real^N) dot ((f:real^N->real^N) p)` (fun th -> REWRITE_TAC[th]) THENL [ GEN_REWRITE_TAC RAND_CONV[dot] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `sum (1..dimindex (:N)) (\i. (v:real^N)$i * (p:real^N dot w i))` THEN CONJ_TAC THENL [ SUBGOAL_THEN `1..dimindex (:N) = (1..n) UNION (n + 1..dimindex (:N))` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC (GSYM NUMSEG_COMBINE_R) THEN EXPAND_TAC "n" THEN REWRITE_TAC[DIM_SUBSET_UNIV; ARITH_RULE `1 <= a + 1`]; ALL_TAC ] THEN MATCH_MP_TAC (GSYM SUM_UNION_RZERO) THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC EQ_SYM THEN REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN UNDISCH_TAC `v:real^N IN span t` THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN MATCH_MP_TAC (ARITH_RULE `n + 1 <= x ==> 1 <= x`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN REPEAT (FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (is_forall o concl))) THEN EXPAND_TAC "f" THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN REWRITE_TAC[REAL_MUL_RZERO; REAL_ENTIRE] THEN DISJ1_TAC THEN UNDISCH_TAC `v:real^N IN span t` THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_NUMSEG]; ALL_TAC ] THEN REWRITE_TAC[DOT_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[DOT_EQ_0] THEN DISCH_TAC THEN SUBGOAL_THEN `!i. i IN 1..n ==> (v:real^N)$i = &0` ASSUME_TAC THENL [ MATCH_MP_TAC INDEPENDENT_EXPLICIT_NUMSEG THEN EXISTS_TAC `w:num->real^N` THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `S:real^N->bool = IMAGE w (1..n)` THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN SUBGOAL_THEN `v:real^N = vec 0` MP_TAC THENL [ REWRITE_TAC[CART_EQ; VEC_COMPONENT] THEN REPEAT STRIP_TAC THEN ASM_CASES_TAC `i <= n:num` THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_NUMSEG]; ALL_TAC ] THEN UNDISCH_TAC `v:real^N IN span t` THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN DISCH_THEN (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[IN_NUMSEG; DE_MORGAN_THM]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `r:real^N = lambda i. if i <= n then b ((w:num->real^N) i) else &0` THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (is_forall o concl)) THEN SUBGOAL_THEN `?p. p IN span S /\ f (p:real^N) = r:real^N` MP_TAC THENL [ SUBGOAL_THEN `r:real^N IN P` MP_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN REWRITE_TAC[IN_NUMSEG; DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "r" THEN ASM_SIMP_TAC[LAMBDA_BETA]; ALL_TAC ] THEN EXPAND_TAC "P" THEN REWRITE_TAC[IN_IMAGE] THEN STRIP_TAC THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE] THEN EXISTS_TAC `p:real^N` THEN SUBGOAL_THEN `p:real^N IN span S /\ (!x. x IN S ==> p dot x = b x)` ASSUME_TAC THENL [ ASM_REWRITE_TAC[] THEN GEN_TAC THEN REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN DISCH_THEN (X_CHOOSE_THEN `i:num` ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `f (p:real^N) = r:real^N` THEN DISCH_THEN (MP_TAC o AP_TERM `(\v:real^N. v$i)`) THEN BETA_TAC THEN EXPAND_TAC "f" THEN EXPAND_TAC "r" THEN SUBGOAL_THEN `1 <= i /\ i <= dimindex (:N)` MP_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "n" THEN REWRITE_TAC[DIM_SUBSET_UNIV]; ALL_TAC ] THEN SIMP_TAC[LAMBDA_BETA] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN FIRST_ASSUM (fun th -> REWRITE_TAC[th]) THEN REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN MATCH_MP_TAC ORTHOGONAL_TO_ALL_IMP_ZERO THEN EXISTS_TAC `S:real^N->bool` THEN CONJ_TAC THENL [ MATCH_MP_TAC SPAN_SUB THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[DOT_LSUB; REAL_SUB_REFL]);;
let UNIQUE_SOLUTION_AFFINE_INDEPENDENT = 
prove(`!(S:real^N->bool) b. ~(S = {}) /\ ~affine_dependent S ==> (?!p. p IN affine hull S /\ (!x y. x IN S /\ y IN S ==> p dot (x - y) = b x - b y))`,
REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT GEN_TAC THEN DISCH_THEN (CONJUNCTS_THEN2 (X_CHOOSE_THEN `v0:real^N` ASSUME_TAC) ASSUME_TAC) THEN ABBREV_TAC `R:real^N->bool = {y - v0 | y | y IN S DELETE v0}` THEN MP_TAC (SPECL [`R:real^N->bool`; `\v:real^N. (b:real^N->real) (v + v0) - b v0 - v0 dot v`] UNIQUE_SOLUTION_lemma) THEN ANTS_TAC THENL [ MP_TAC (SPEC `S:real^N->bool` AFFINE_INDEPENDENT_IMP_INDEPENDENT) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `v0:real^N`) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[EXISTS_UNIQUE] THEN STRIP_TAC THEN EXISTS_TAC `p + v0:real^N` THEN SUBGOAL_THEN `span (R:real^N->bool) = affine hull IMAGE (\x. --v0 + x) S` ASSUME_TAC THENL [ MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `span ((v0 - v0:real^N) INSERT R)` THEN CONJ_TAC THENL [ REWRITE_TAC[VECTOR_SUB_REFL; SPAN_INSERT_0]; ALL_TAC ] THEN SUBGOAL_THEN `(v0 - v0) INSERT R = IMAGE (\x:real^N. --v0 + x) S` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_INSERT; IN_IMAGE; VECTOR_ARITH `--v0 + x = x - v0:real^N`] THEN EXPAND_TAC "R" THEN REWRITE_TAC[IN_ELIM_THM; IN_DELETE] THEN ASM SET_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC (GSYM AFFINE_HULL_EQ_SPAN) THEN MATCH_MP_TAC HULL_INC THEN REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `v0:real^N` THEN ASM_REWRITE_TAC[VECTOR_ARITH `--v0 + v0 = vec 0:real^N`]; ALL_TAC ] THEN CONJ_TAC THENL [ CONJ_TAC THENL [ UNDISCH_TAC `p:real^N IN span R` THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN REWRITE_TAC[VECTOR_ARITH `p = --v0 + x <=> p + v0:real^N = x`] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!x:real^N. x IN S ==> (p + v0) dot (x - v0) = b x - b v0` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = v0:real^N` THENL [ ASM_REWRITE_TAC[VECTOR_SUB_REFL; DOT_RZERO; REAL_SUB_REFL]; ALL_TAC ] THEN REWRITE_TAC[DOT_LADD] THEN SUBGOAL_THEN `p:real^N dot (x - v0) = b ((x - v0) + v0) - b v0 - v0 dot (x - v0)` (fun th -> REWRITE_TAC[th]) THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "R" THEN REWRITE_TAC[IN_ELIM_THM; IN_DELETE] THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[VECTOR_ARITH `x - v0 + v0 = x:real^N`] THEN REAL_ARITH_TAC; ALL_TAC ] THEN REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[VECTOR_ARITH `a - b = (a - v0:real^N) - (b - v0)`] THEN ONCE_REWRITE_TAC[DOT_RSUB] THEN FIRST_ASSUM (MP_TAC o SPEC `x:real^N`) THEN FIRST_ASSUM (MP_TAC o SPEC `y:real^N`) THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REPEAT (DISCH_THEN (fun th -> REWRITE_TAC[th])) THEN REAL_ARITH_TAC; ALL_TAC ] THEN GEN_TAC THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `y - v0:real^N`) THEN POP_ASSUM STRIP_ASSUME_TAC THEN ANTS_TAC THENL [ CONJ_TAC THENL [ ASM_REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN EXPAND_TAC "R" THEN REWRITE_TAC[IN_IMAGE; IN_DELETE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[DOT_LSUB; VECTOR_ARITH `y - v0 + v0:real^N = y`] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`y':real^N`; `v0:real^N`]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]); ALL_TAC ] THEN VECTOR_ARITH_TAC);;
(* QXSKIIT *)
let QXSKIIT = 
prove(`!(vf:A->real^N) b . FINITE (IMAGE vf (:A)) /\ ~affine_dependent (IMAGE vf (:A)) /\ (!i j. (vf i = vf j) ==> (b i = b j)) ==> (?!p. p IN affine hull (IMAGE vf (:A)) /\ (!i j. (p dot (vf i - vf j) = (b i - b j))))`,
REPEAT STRIP_TAC THEN ABBREV_TAC `S = IMAGE (vf:A->real^N) (:A)` THEN SUBGOAL_THEN `?h:real^N->real. !i:A. h (vf i) = b i` CHOOSE_TAC THENL [ EXISTS_TAC `\x:real^N. if x IN S then b (inverse (vf:A->real^N) x) else &0` THEN EXPAND_TAC "S" THEN REWRITE_TAC[IN_IMAGE; IN_UNIV] THEN GEN_TAC THEN SUBGOAL_THEN `?x:A. vf i = (vf x):real^N` (fun th -> REWRITE_TAC[th]) THENL [ EXISTS_TAC `i:A` THEN REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[inverse] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN MESON_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`S:real^N->bool`; `\x:real^N. (h:real^N->real) x`] UNIQUE_SOLUTION_AFFINE_INDEPENDENT) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXPAND_TAC "S" THEN REWRITE_TAC[IN_IMAGE] THEN MP_TAC UNIV_NOT_EMPTY THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`(vf:A->real^N) x`; `x:A`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[] THEN SUBGOAL_THEN `!p. (!x y:real^N. x IN S /\ y IN S ==> p dot (x - y) = h x - h y) <=> (!i j:A. p dot (vf i - vf j) = b i - b j)` MP_TAC THENL [ GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ POP_ASSUM (MP_TAC o SPECL [`(vf:A->real^N) i`; `(vf:A->real^N) j`]) THEN EXPAND_TAC "S" THEN ASM_REWRITE_TAC[IN_IMAGE; IN_UNIV] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL [ EXISTS_TAC `i:A`; EXISTS_TAC `j:A` ] THEN REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "S" THEN REWRITE_TAC[IN_IMAGE; IN_UNIV] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) );;
(*******************************************) (***********) (* OAPVION *) (***********)
let CIRCUMCENTER_lemma = 
prove(`!S:real^N->bool. ~(S = {}) /\ ~affine_dependent S ==> ?!p. p IN affine hull S /\ (!x y. x IN S /\ y IN S ==> dist (p,x) = dist (p,y))`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`S:real^N->bool`; `\v:real^N. (v dot v) / &2`] UNIQUE_SOLUTION_AFFINE_INDEPENDENT) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN REWRITE_TAC[DIST_EQ; dist; NORM_POW_2] THEN REWRITE_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REWRITE_TAC[REAL_ARITH `p2 - px - (px - x2) = p2 - py - (py - y2) <=> px - py = x2 / &2 - y2 / &2`] THEN ONCE_REWRITE_TAC[GSYM DOT_RSUB] THEN ASM_REWRITE_TAC[]);;
let CIRCUMCENTER_LEMMA = 
prove(`!S:real^N->bool. ~(S = {}) /\ ~affine_dependent S ==> ?!p. p IN affine hull S /\ (?c. !w. w IN S ==> c = dist (p,w))`,
GEN_TAC THEN DISCH_THEN (MP_TAC o MATCH_MP CIRCUMCENTER_lemma) THEN SUBGOAL_THEN `!p. (!x y:real^N. x IN S /\ y IN S ==> dist (p,x) = dist (p,y)) <=> (?c. !w. w IN S ==> c = dist (p,w))` ASSUME_TAC THENL [ GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ ASM_CASES_TAC `S:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN EXISTS_TAC `dist (p,x:real^N)` THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `c:real` THEN REWRITE_TAC[EQ_SYM_EQ] THEN CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[]);;
let OAPVION1 = 
prove(`!(S:real^N->bool). ~(S = {}) /\ ~affine_dependent S ==> (circumcenter S) IN (affine hull S)`,
GEN_TAC THEN DISCH_THEN (MP_TAC o MATCH_MP CIRCUMCENTER_LEMMA) THEN REWRITE_TAC[circumcenter; IN] THEN MESON_TAC[]);;
let OAPVION2 = 
prove(`!(S:real^N->bool). ~affine_dependent S ==> (!w. w IN S ==> (radV S = dist(circumcenter S, w)))`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `~(S:real^N->bool = {})` ASSUME_TAC THENL [ REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `w:real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (SPEC `S:real^N->bool` CIRCUMCENTER_LEMMA) THEN ASM_REWRITE_TAC[IN; radV; EXISTS_UNIQUE] THEN STRIP_TAC THEN SUBGOAL_THEN `circumcenter S = p:real^N` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[circumcenter] THEN MATCH_MP_TAC SELECT_UNIQUE THEN ASM_MESON_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC SELECT_UNIQUE THEN X_GEN_TAC `r:real` THEN EQ_TAC THENL [ REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `w:real^N`) THEN UNDISCH_TAC `w:real^N IN S` THEN SIMP_TAC[IN]; ALL_TAC ] THEN BETA_TAC THEN REMOVE_ASSUM THEN FIRST_ASSUM (MP_TAC o SPEC `w:real^N`) THEN UNDISCH_TAC `w:real^N IN S` THEN SIMP_TAC[IN] THEN DISCH_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN DISCH_TAC THEN ASM_REWRITE_TAC[]);;
let OAPVION3 = 
prove(`!(S:real^N->bool). ~affine_dependent S ==> (!p. (p IN affine hull S) /\ (?c. !w. (w IN S) ==> (dist(p,w) = c)) ==> (p = circumcenter S))`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `~(S:real^N->bool = {})` ASSUME_TAC THENL [ DISCH_TAC THEN UNDISCH_TAC `p:real^N IN affine hull S` THEN ASM_REWRITE_TAC[AFFINE_HULL_EMPTY; NOT_IN_EMPTY]; ALL_TAC ] THEN MP_TAC (SPEC `S:real^N->bool` CIRCUMCENTER_LEMMA) THEN ASM_REWRITE_TAC[EXISTS_UNIQUE; circumcenter] THEN REPEAT STRIP_TAC THEN REPEAT (POP_ASSUM MP_TAC) THEN REWRITE_TAC[IN] THEN REPEAT DISCH_TAC THEN MATCH_MP_TAC (GSYM SELECT_UNIQUE) THEN BETA_TAC THEN GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL [ ASM_REWRITE_TAC[] THEN EXISTS_TAC `c:real` THEN UNDISCH_TAC `!w:real^N. S w ==> dist (p,w) = c` THEN SIMP_TAC[EQ_SYM_EQ]; ALL_TAC ] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `p':real^N` THEN CONJ_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC EQ_SYM THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `c:real` THEN UNDISCH_TAC `!w:real^N. S w ==> dist (p,w) = c` THEN SIMP_TAC[EQ_SYM_EQ]);;
let CIRCUMCENTER_1 = 
prove(`!x:real^N. circumcenter {x} = x`,
GEN_TAC THEN MP_TAC (SPEC `{x:real^N}` OAPVION3) THEN REWRITE_TAC[AFFINE_INDEPENDENT_1; AFFINE_HULL_SING; IN_SING] THEN DISCH_THEN (fun th -> MATCH_MP_TAC (GSYM th)) THEN REWRITE_TAC[] THEN EXISTS_TAC `&0` THEN SIMP_TAC[DIST_REFL]);;
let CIRCUMCENTER_NOT_EQ = 
prove(`!S:real^N->bool. ~affine_dependent S /\ 1 < CARD S ==> !x. x IN S ==> ~(circumcenter S = x)`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `?y. y IN S DELETE (x:real^N)` MP_TAC THENL [ REWRITE_TAC[MEMBER_NOT_EMPTY] THEN DISCH_THEN (MP_TAC o AP_TERM `\s:real^N->bool. CARD s`) THEN REWRITE_TAC[CARD_CLAUSES] THEN MP_TAC (ISPECL [`x:real^N`; `S:real^N->bool`] CARD_DELETE) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN UNDISCH_TAC `1 < CARD (S:real^N->bool)` THEN ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN MP_TAC (SPEC `S:real^N->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `x:real^N`) THEN REWRITE_TAC[DIST_REFL] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[EQ_SYM_EQ; DIST_EQ_0]);;
let CIRCUMCENTER_TRANSLATION = 
prove(`!s (a:real^N). ~(s = {}) /\ ~affine_dependent s ==> circumcenter (IMAGE (\x. a + x) s) = a + circumcenter s`,
REPEAT STRIP_TAC THEN MP_TAC (SPEC `IMAGE (\x:real^N. a + x) s` OAPVION3) THEN ASM_REWRITE_TAC[AFFINE_DEPENDENT_TRANSLATION_EQ] THEN DISCH_THEN (fun th -> MATCH_MP_TAC (GSYM th)) THEN CONJ_TAC THENL [ REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN EXISTS_TAC `circumcenter (s:real^N->bool)` THEN MP_TAC (SPEC `s:real^N->bool` OAPVION1) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN EXISTS_TAC `radV (s:real^N->bool)` THEN REWRITE_TAC[IN_IMAGE] THEN REPEAT STRIP_TAC THEN MP_TAC (SPEC `s:real^N->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[dist] THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC);;
let RADV_TRANSLATION = 
prove(`!s (a:real^N). ~affine_dependent s ==> radV (IMAGE (\x. a + x) s) = radV s`,
REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL [ ASM_REWRITE_TAC[IMAGE_CLAUSES]; ALL_TAC ] THEN MP_TAC (SPEC `IMAGE (\x:real^N. a + x) s` OAPVION2) THEN ASM_REWRITE_TAC[AFFINE_DEPENDENT_TRANSLATION_EQ] THEN FIRST_ASSUM MP_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN DISCH_THEN (MP_TAC o SPEC `a + x:real^N`) THEN ANTS_TAC THENL [ REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ASM_SIMP_TAC[CIRCUMCENTER_TRANSLATION; dist; VECTOR_ARITH `(a + b) - (a + x) = b - x:real^N`] THEN REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC EQ_SYM THEN MP_TAC (SPEC `s:real^N->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[]);;
(**************************************) (***********) (* MHFTTZN *) (***********)
let AFF_INTER_SUBSET_INTER_AFF = 
prove(`!s t:real^N->bool. affine hull (s INTER t) SUBSET affine hull s INTER affine hull t`,
REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[INTER_SUBSET]);;
let MHFTTZN_lemma = 
prove(`!V ul k. packing V /\ barV V k ul ==> affine hull voronoi_list V ul = INTERS {bis (HD ul) u | u | u IN set_of_list ul}`,
REPEAT GEN_TAC THEN SPEC_TAC (`ul:(real^3)list`, `ul:(real^3)list`) THEN SPEC_TAC (`k:num`, `k:num`) THEN INDUCT_TAC THENL [ REWRITE_TAC[BARV; VORONOI_NONDG; ARITH] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `UNIV:real^3->bool` THEN REWRITE_TAC[VORONOI_LIST; VORONOI_SET] THEN MP_TAC (ISPEC `ul:(real^3)list` LENGTH_1_LEMMA) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN REWRITE_TAC[set_of_list; IN_SING; HD] THEN CONJ_TAC THENL [ MATCH_MP_TAC CONTAINS_BALL_AFFINE_HULL THEN SUBGOAL_THEN `INTERS {voronoi_closed V v | v:real^3 = HD ul} = voronoi_closed V (HD ul)` (fun th -> REWRITE_TAC[th]) THENL [ SET_TAC[]; ALL_TAC ] THEN EXISTS_TAC `(HD ul):real^3` THEN MATCH_MP_TAC VORONOI_CLOSED_CONTAINS_BALL THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `INTERS {bis (HD ul) u | u | u:real^3 = HD ul} = bis (HD ul) (HD ul)` (fun th -> REWRITE_TAC[th]) THENL [ SET_TAC[]; ALL_TAC ] THEN REWRITE_TAC[bis] THEN SET_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `SUC k <= 3` ASSUME_TAC THENL [ MATCH_MP_TAC BARV_IMP_K_LE_3 THEN EXISTS_TAC `V:real^3->bool` THEN EXISTS_TAC `ul:(real^3)list` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `vl:(real^3)list = BUTLAST ul` THEN POP_ASSUM (LABEL_TAC "vl") THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 2` ASSUME_TAC THENL [ UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `truncate_simplex k (ul:(real^3)list) = vl` (LABEL_TAC "vl2") THENL [ MP_TAC (ISPEC `ul:(real^3)list` TRUNCATE_SIMPLEX_EQ_BUTLAST) THEN ASM_REWRITE_TAC[ARITH_RULE `2 <= k + 2`; ARITH_RULE `(k + 2) - 2 = k`]; ALL_TAC ] THEN SUBGOAL_THEN `barV V k vl` ASSUME_TAC THENL [ REMOVE_THEN "vl2" (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `SUC k` THEN ASM_SIMP_TAC[ARITH_RULE `k <= SUC k`]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `HD vl = (HD ul):real^3` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ABBREV_TAC `A0 = INTERS {bis (HD ul) u | u | u:real^3 IN set_of_list vl}` THEN ABBREV_TAC `A1 = INTERS {bis (HD ul) u | u | u:real^3 IN set_of_list ul}` THEN SUBGOAL_THEN `voronoi_list V ul = voronoi_list V vl INTER bis (HD ul) (LAST ul)` (LABEL_TAC "B1") THENL [ MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `LAST ul:real^3`; `HD vl:real^3`; `TL vl:(real^3)list`] VORONOI_LIST_INTER_BIS) THEN SUBGOAL_THEN `APPEND vl [LAST ul:real^3] = ul` (fun th -> REWRITE_TAC[th]) THENL [ REMOVE_THEN "vl" (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC APPEND_BUTLAST_LAST THEN ASM_REWRITE_TAC[GSYM LENGTH_EQ_NIL] THEN ARITH_TAC; ALL_TAC ] THEN UNDISCH_TAC `HD vl = HD ul:real^3` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN DISCH_THEN (fun th -> MATCH_MP_TAC (GSYM th)) THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `vl:(real^3)list`] BARV_SUBSET) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN CONJ_TAC THENL [ MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `set_of_list (ul:(real^3)list)` THEN MP_TAC (SPECL [`V:real^3->bool`; `SUC k`; `ul:(real^3)list`] BARV_SUBSET) THEN ASM_SIMP_TAC[] THEN DISCH_THEN (fun th -> ALL_TAC) THEN REWRITE_TAC[IN_SET_OF_LIST] THEN MP_TAC (ISPEC `ul:(real^3)list` LAST_EL) THEN ASM_REWRITE_TAC[GSYM LENGTH_EQ_NIL; ARITH_RULE `~(k + 2 = 0)`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MATCH_MP_TAC MEM_EL THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN MP_TAC (ISPEC `vl:(real^3)list` LENGTH_IMP_CONS) THEN ANTS_TAC THENL [ UNDISCH_TAC `barV V k vl` THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THEN ASM_REWRITE_TAC[HD; TL]; ALL_TAC ] THEN SUBGOAL_THEN `A0 INTER bis ((HD ul):real^3) (LAST ul) = A1` (LABEL_TAC "A1") THENL [ EXPAND_TAC "A0" THEN EXPAND_TAC "A1" THEN SUBGOAL_THEN `set_of_list ul = set_of_list vl UNION {LAST ul:real^3}` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPEC `ul:(real^3)list` APPEND_BUTLAST_LAST) THEN ASM_REWRITE_TAC[GSYM LENGTH_EQ_NIL; ARITH_RULE `~(k + 2 = 0)`] THEN DISCH_THEN (fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SYM th]) THEN REWRITE_TAC[SET_OF_LIST_APPEND; set_of_list]; ALL_TAC ] THEN SET_TAC[]; ALL_TAC ] THEN ASM_CASES_TAC `A1 = A0:real^3->bool` THENL [ SUBGOAL_THEN `voronoi_list V ul = voronoi_list V vl` (fun th -> ASM_REWRITE_TAC[th]) THEN SUBGOAL_THEN `voronoi_list V vl = voronoi_list V vl INTER A0` MP_TAC THENL [ MATCH_MP_TAC (SET_RULE `A SUBSET B ==> A = A INTER B:A->bool`) THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull voronoi_list V vl` THEN ASM_REWRITE_TAC[HULL_SUBSET; SUBSET_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[INTER_ASSOC]; ALL_TAC ] THEN SUBGOAL_THEN `affine (A1:real^3->bool)` ASSUME_TAC THENL [ REMOVE_THEN "A1" (fun th -> ALL_TAC) THEN EXPAND_TAC "A1" THEN MATCH_MP_TAC AFFINE_INTERS THEN REWRITE_TAC[IN_ELIM_THM; BIS_EQ_HYPERPLANE] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[AFFINE_HYPERPLANE]; ALL_TAC ] THEN SUBGOAL_THEN `A1:real^3->bool = affine hull A1` (fun th -> ONCE_REWRITE_TAC[th]) THENL [ MATCH_MP_TAC EQ_SYM THEN ASM_REWRITE_TAC[AFFINE_HULL_EQ]; ALL_TAC ] THEN MATCH_MP_TAC AFF_DIM_EQ_AFFINE_HULL THEN CONJ_TAC THENL [ MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull voronoi_list V ul` THEN ASM_REWRITE_TAC[HULL_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull (voronoi_list V vl) INTER affine hull (bis (HD ul) (LAST ul))` THEN ASM_REWRITE_TAC[AFF_INTER_SUBSET_INTER_AFF] THEN SUBGOAL_THEN `affine hull bis ((HD ul):real^3) (LAST ul) = bis (HD ul) (LAST ul)` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[AFFINE_HULL_EQ] THEN REWRITE_TAC[BIS_EQ_HYPERPLANE; AFFINE_HYPERPLANE]; ALL_TAC ] THEN ASM_REWRITE_TAC[SUBSET_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `aff_dim (voronoi_list V ul) = &(3 - SUC k)` (fun th -> REWRITE_TAC[th]) THENL [ UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN POP_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 2`] THEN ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD; ADD1] THEN INT_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `aff_dim (A1:real^3->bool) = aff_dim (A0:real^3->bool) - &1 \/ aff_dim A1 = -- &1` MP_TAC THENL [ USE_THEN "A1" (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[BIS_EQ_HYPERPLANE] THEN ABBREV_TAC `a:real^3 = &2 % (LAST ul - HD ul)` THEN ABBREV_TAC `b = LAST ul dot LAST ul - HD ul dot HD (ul:(real^3)list)` THEN MP_TAC (ISPECL [`a:real^3`; `b:real`; `A0:real^3->bool`] AFF_DIM_AFFINE_INTER_HYPERPLANE) THEN ANTS_TAC THENL [ EXPAND_TAC "A0" THEN MATCH_MP_TAC AFFINE_INTERS THEN REWRITE_TAC[IN_ELIM_THM; BIS_EQ_HYPERPLANE] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[AFFINE_HYPERPLANE]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN EXPAND_TAC "a" THEN EXPAND_TAC "b" THEN REWRITE_TAC[GSYM BIS_EQ_HYPERPLANE] THEN DISCH_TAC THEN SUBGOAL_THEN `A0 = A1:real^3->bool` MP_TAC THENL [ REMOVE_THEN "A1" (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM MP_TAC THEN SET_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL [ UNDISCH_TAC `affine hull voronoi_list V vl = A0:real^3->bool` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN UNDISCH_TAC `barV V k vl` THEN REWRITE_TAC[BARV; VORONOI_NONDG; AFF_DIM_AFFINE_HULL] THEN STRIP_TAC THEN POP_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 1`] THEN ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB] THEN ASM_REWRITE_TAC[GSYM INT_OF_NUM_ADD; ADD1] THEN INT_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB] THEN UNDISCH_TAC `SUC k <= 3` THEN REWRITE_TAC[GSYM INT_OF_NUM_LE] THEN INT_ARITH_TAC);;
let MHFTTZN_lemma2 = 
prove(`!V ul k. packing V /\ barV V k ul ==> aff_dim (set_of_list ul) = &k /\ (!u v. u IN affine hull voronoi_list V ul /\ v IN affine hull (set_of_list ul) ==> (u - circumcenter (set_of_list ul)) dot (v - circumcenter (set_of_list ul)) = &0)`,
REPEAT GEN_TAC THEN SPEC_TAC (`ul:(real^3)list`, `ul:(real^3)list`) THEN SPEC_TAC (`k:num`, `k:num`) THEN INDUCT_TAC THENL [ REWRITE_TAC[BARV; ARITH] THEN GEN_TAC THEN STRIP_TAC THEN MP_TAC (ISPEC `ul:(real^3)list` LENGTH_1_LEMMA) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN REWRITE_TAC[set_of_list; CIRCUMCENTER_1; AFFINE_HULL_SING; IN_SING] THEN SIMP_TAC[AFF_DIM_SING; VECTOR_SUB_REFL; DOT_RZERO]; ALL_TAC ] THEN GEN_TAC THEN DISCH_THEN STRIP_ASSUME_TAC THEN SUBGOAL_THEN `SUC k <= 3` ASSUME_TAC THENL [ MATCH_MP_TAC BARV_IMP_K_LE_3 THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `ul:(real^3)list`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `vl:(real^3)list = BUTLAST ul` THEN POP_ASSUM (LABEL_TAC "vl") THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 2` ASSUME_TAC THENL [ UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `truncate_simplex k (ul:(real^3)list) = vl` (LABEL_TAC "vl2") THENL [ MP_TAC (ISPEC `ul:(real^3)list` TRUNCATE_SIMPLEX_EQ_BUTLAST) THEN ASM_REWRITE_TAC[ARITH_RULE `2 <= k + 2`; ARITH_RULE `(k + 2) - 2 = k`]; ALL_TAC ] THEN SUBGOAL_THEN `barV V k vl` ASSUME_TAC THENL [ REMOVE_THEN "vl2" (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `SUC k` THEN ASM_SIMP_TAC[ARITH_RULE `k <= SUC k`]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k <= 3`]; ALL_TAC ] THEN SUBGOAL_THEN `HD vl = (HD ul):real^3` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN DISCH_THEN STRIP_ASSUME_TAC THEN SUBGOAL_THEN `aff_dim (set_of_list (ul:(real^3)list)) = &(SUC k)` ASSUME_TAC THENL [ ASM_CASES_TAC `&(SUC k) <= aff_dim (set_of_list (ul:(real^3)list))` THENL [ MP_TAC (ISPEC `set_of_list (ul:(real^3)list)` AFF_DIM_LE_CARD) THEN REWRITE_TAC[FINITE_SET_OF_LIST] THEN MP_TAC (ISPEC `ul:(real^3)list` CARD_SET_OF_LIST_LE) THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_ADD; ADD1] THEN INT_ARITH_TAC; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[INT_NOT_LE] THEN DISCH_TAC THEN SUBGOAL_THEN `set_of_list ul = (LAST ul) INSERT (set_of_list vl):real^3->bool` ASSUME_TAC THENL [ MP_TAC (ISPEC `ul:(real^3)list` APPEND_BUTLAST_LAST) THEN ASM_REWRITE_TAC[GSYM LENGTH_EQ_NIL; ARITH_RULE `~(k + 2 = 0)`] THEN DISCH_THEN (fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SYM th]) THEN REWRITE_TAC[SET_OF_LIST_APPEND; set_of_list] THEN REWRITE_TAC[EXTENSION; IN_UNION; IN_INSERT; NOT_IN_EMPTY; DISJ_SYM]; ALL_TAC ] THEN SUBGOAL_THEN `LAST ul IN affine hull (set_of_list vl):real^3->bool` ASSUME_TAC THENL [ UNDISCH_TAC `aff_dim (set_of_list (ul:(real^3)list)) < &(SUC k)` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN MP_TAC (ISPECL [`LAST ul:real^3`; `set_of_list vl:real^3->bool`] AFF_DIM_INSERT) THEN ASM_REWRITE_TAC[ADD1; GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC; ALL_TAC ] THEN ABBREV_TAC `y:real^3 = LAST ul` THEN ABBREV_TAC `q:real^3 = circumcenter (set_of_list vl)` THEN SUBGOAL_THEN `affine hull voronoi_list V vl SUBSET affine hull voronoi_list V ul` MP_TAC THENL [ SUBGOAL_THEN `!p. p IN affine hull voronoi_list V vl ==> (p - q) dot (y - q) = &0` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!p. p IN affine hull voronoi_list V vl ==> &2 * ((y - HD ul) dot q) = &2 * ((y - HD ul) dot p:real^3)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN AP_TERM_TAC THEN ONCE_REWRITE_TAC[REAL_ARITH `a = b <=> b - a = &0`] THEN REWRITE_TAC[GSYM DOT_RSUB] THEN GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [VECTOR_ARITH `y - u0:real^3 = (y - q) - (u0 - q)`] THEN ONCE_REWRITE_TAC[DOT_LSUB] THEN ASM_SIMP_TAC[DOT_SYM; REAL_ARITH `&0 - x = &0 <=> x = &0`] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `set_of_list vl:real^3->bool` THEN REWRITE_TAC[HULL_SUBSET; IN_SET_OF_LIST] THEN UNDISCH_TAC `HD vl = HD ul:real^3` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ONCE_REWRITE_TAC[GSYM EL] THEN MATCH_MP_TAC MEM_EL THEN UNDISCH_TAC `barV V k vl` THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `?w. w IN affine hull voronoi_list V ul` CHOOSE_TAC THENL [ REWRITE_TAC[MEMBER_NOT_EMPTY; AFFINE_HULL_EQ_EMPTY] THEN DISCH_TAC THEN UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN POP_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 2`; AFF_DIM_EMPTY; DE_MORGAN_THM] THEN DISJ2_TAC THEN DISJ2_TAC THEN UNDISCH_TAC `SUC k <= 3` THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD; GSYM INT_OF_NUM_LE; ADD1] THEN INT_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `affine hull voronoi_list V ul = affine hull voronoi_list V vl INTER bis (HD ul) y` ASSUME_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] MHFTTZN_lemma) THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `k:num`] MHFTTZN_lemma) THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k <= 3`] THEN REPEAT DISCH_TAC THEN SET_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[SUBSET_INTER; SUBSET_REFL; SUBSET] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[IN_INTER] THEN REWRITE_TAC[BIS_EQ_HYPERPLANE; IN_ELIM_THM] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `&2 % ((y:real^3) - HD ul) dot q` THEN CONJ_TAC THENL [ MATCH_MP_TAC EQ_SYM THEN REWRITE_TAC[DOT_LMUL] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `&2 % ((y:real^3) - HD ul) dot w` THEN CONJ_TAC THENL [ REWRITE_TAC[DOT_LMUL] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN UNDISCH_TAC `w:real^3 IN affine hull voronoi_list V ul` THEN ASM_SIMP_TAC[IN_INTER]; ALL_TAC ] THEN UNDISCH_TAC `w:real^3 IN affine hull voronoi_list V ul` THEN ASM_SIMP_TAC[IN_INTER; BIS_EQ_HYPERPLANE; IN_ELIM_THM]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o MATCH_MP AFF_DIM_SUBSET) THEN UNDISCH_TAC `barV V (SUC k) ul` THEN UNDISCH_TAC `barV V k vl` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN POP_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 1 /\ 0 < SUC k + 1`] THEN STRIP_TAC THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN REMOVE_ASSUM THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD; ADD1] THEN REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN INT_ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ABBREV_TAC `q:real^3 = circumcenter (set_of_list ul)` THEN ABBREV_TAC `S:real^3->bool = affine hull set_of_list ul` THEN SUBGOAL_THEN `CARD (set_of_list (ul:(real^3)list)) = k + 2` ASSUME_TAC THENL [ SUBGOAL_THEN `CARD (set_of_list (ul:(real^3)list)) <= k + 2` MP_TAC THENL [ MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `LENGTH (ul:(real^3)list)` THEN REWRITE_TAC[CARD_SET_OF_LIST_LE] THEN ASM_REWRITE_TAC[LE_REFL]; ALL_TAC ] THEN MP_TAC (ISPEC `set_of_list (ul:(real^3)list)` AFF_DIM_LE_CARD) THEN ASM_REWRITE_TAC[FINITE_SET_OF_LIST] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD; ADD1; GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_EQ] THEN INT_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `~affine_dependent (set_of_list ul:real^3->bool)` ASSUME_TAC THENL [ ASM_REWRITE_TAC[AFFINE_INDEPENDENT_IFF_CARD; FINITE_SET_OF_LIST] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD; ADD1] THEN INT_ARITH_TAC; ALL_TAC ] THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` OAPVION1) THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[SET_OF_LIST_EQ_EMPTY; GSYM LENGTH_EQ_NIL] THEN ARITH_TAC; ALL_TAC ] THEN DISCH_TAC THEN SUBGOAL_THEN `IMAGE (\x:real^3. x - q) S = span {y - HD ul | y | y IN set_of_list ul}` ASSUME_TAC THENL [ MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `span {y - q | y | y:real^3 IN set_of_list ul}` THEN SUBGOAL_THEN `IMAGE (\x. x - q) S = span {y - q:real^3 | y IN set_of_list ul}` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN SUBGOAL_THEN `affine hull set_of_list ul = affine hull (q:real^3 INSERT set_of_list ul)` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC AFFINE_HULLS_EQ THEN CONJ_TAC THENL [ MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `q:real^3 INSERT set_of_list ul` THEN REWRITE_TAC[HULL_SUBSET] THEN SIMP_TAC[SUBSET; IN_INSERT]; ALL_TAC ] THEN REWRITE_TAC[SUBSET; IN_INSERT] THEN REPEAT STRIP_TAC THENL [ ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `set_of_list ul:real^3->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN SUBGOAL_THEN `span {y - q | y | y IN set_of_list ul} = span {y - q:real^3 | y | y IN (q INSERT set_of_list ul)}` (fun th -> REWRITE_TAC[th]) THENL [ SUBGOAL_THEN `{y - q:real^3 | y | y IN q INSERT set_of_list ul} = vec 0 INSERT {y - q | y IN set_of_list ul}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_INSERT; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THENL [ ASM_REWRITE_TAC[VECTOR_SUB_REFL]; ALL_TAC ] THEN DISJ2_TAC THEN EXISTS_TAC `y:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `q:real^3` THEN ASM_REWRITE_TAC[VECTOR_SUB_REFL]; ALL_TAC ] THEN EXISTS_TAC `y:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[SPAN_INSERT_0]; ALL_TAC ] THEN MP_TAC (ISPECL [`q:real^3`; `q:real^3 INSERT set_of_list ul`] DIFFS_AFFINE_HULL_SPAN) THEN ANTS_TAC THENL [ REWRITE_TAC[IN_INSERT]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; CONJ_SYM]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM SPAN_SPAN] THEN MATCH_MP_TAC EQ_SYM THEN MATCH_MP_TAC DIM_EQ_SPAN THEN CONJ_TAC THENL [ REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [VECTOR_ARITH `y - u = (y - q) - (u - q):real^3`] THEN MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `{y - q:real^3 | y IN set_of_list ul}` THEN REWRITE_TAC[span; HULL_SUBSET; IN_ELIM_THM] THENL [ EXISTS_TAC `y:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN EXISTS_TAC `HD ul:real^3` THEN REWRITE_TAC[] THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= k + 2`]; ALL_TAC ] THEN SUBGOAL_THEN `dim (span {y - q:real^3 | y IN set_of_list ul}) = k + 1` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[GSYM INT_OF_NUM_EQ] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `aff_dim (span {y - q:real^3 | y IN set_of_list ul})` THEN CONJ_TAC THENL [ MATCH_MP_TAC (GSYM AFF_DIM_DIM_0) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `IMAGE (\x:real^3. x - q) S` THEN REWRITE_TAC[HULL_SUBSET; IN_IMAGE] THEN EXISTS_TAC `q:real^3` THEN ASM_REWRITE_TAC[VECTOR_SUB_REFL]; ALL_TAC ] THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[VECTOR_ARITH `x - q = --q + x:real^3`] THEN REWRITE_TAC[AFF_DIM_TRANSLATION_EQ] THEN EXPAND_TAC "S" THEN REWRITE_TAC[AFF_DIM_AFFINE_HULL] THEN ASM_REWRITE_TAC[ADD1]; ALL_TAC ] THEN MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `dim {y - HD ul:real^3 | y | y IN set_of_list ul DELETE HD ul}` THEN CONJ_TAC THENL [ MATCH_MP_TAC (ARITH_RULE `a = k + 1 ==> k + 1 <= a`) THEN SUBGOAL_THEN `k + 1 = CARD ({y - HD ul:real^3 | y | y IN set_of_list ul DELETE HD ul})` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `CARD (set_of_list ul DELETE ((HD ul):real^3))` THEN CONJ_TAC THENL [ ASM_SIMP_TAC[FINITE_SET_OF_LIST; CARD_DELETE] THEN MP_TAC (ISPEC `ul:(real^3)list` HD_IN_SET_OF_LIST) THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= k + 2`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ARITH_TAC; ALL_TAC ] THEN ONCE_REWRITE_TAC[GSYM IMAGE_LEMMA] THEN MATCH_MP_TAC (GSYM CARD_IMAGE_INJ) THEN CONJ_TAC THENL [ BETA_TAC THEN SIMP_TAC[VECTOR_ARITH `y - u = x - u <=> y = x:real^3`]; ALL_TAC ] THEN MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `set_of_list ul:real^3->bool` THEN REWRITE_TAC[FINITE_SET_OF_LIST; DELETE_SUBSET]; ALL_TAC ] THEN MATCH_MP_TAC DIM_EQ_CARD THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` AFFINE_INDEPENDENT_IMP_INDEPENDENT) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= k + 2`]; ALL_TAC ] THEN MATCH_MP_TAC DIM_SUBSET THEN SIMP_TAC[SUBSET; IN_ELIM_THM; IN_DELETE] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `y:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `w = v - q:real^3` THEN SUBGOAL_THEN `w IN span {y - HD ul | y | y:real^3 IN set_of_list ul}` MP_TAC THENL [ POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `v:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REMOVE_ASSUM THEN SPEC_TAC (`w:real^3`, `w:real^3`) THEN REWRITE_TAC[GSYM orthogonal] THEN MATCH_MP_TAC ORTHOGONAL_TO_SPAN THEN REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[orthogonal] THEN SUBGOAL_THEN `&0 = (norm (u - HD ul:real^3) pow 2 - norm (u - y) pow 2) / &2` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[REAL_ARITH `&0 = (a - b) / &2 <=> a = b`] THEN REWRITE_TAC[GSYM dist; GSYM DIST_EQ] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] MHFTTZN_lemma) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN UNDISCH_TAC `u IN affine hull voronoi_list V ul` THEN ASM_REWRITE_TAC[IN_INTERS; IN_ELIM_THM] THEN DISCH_THEN (MP_TAC o SPEC `bis (HD ul) (y:real^3)`) THEN ANTS_TAC THENL [ EXISTS_TAC `y:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[bis; IN_ELIM_THM]; ALL_TAC ] THEN GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [VECTOR_ARITH `u - x:real^3 = (u - q) - (x - q)`] THEN REWRITE_TAC[NORM_POW_2] THEN ONCE_REWRITE_TAC[DOT_LSUB] THEN ONCE_REWRITE_TAC[DOT_RSUB] THEN REWRITE_TAC[DOT_SQUARE_NORM; DOT_SYM] THEN REWRITE_TAC[REAL_ARITH `uq - a - (a - u0q) - (uq - b - (b - yq)) = &2 * (b - a) + (u0q - yq)`] THEN SUBGOAL_THEN `norm (HD ul - q:real^3) pow 2 - norm (y - q) pow 2 = &0` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[REAL_ARITH `a - b = &0 <=> a = b`] THEN REWRITE_TAC[GSYM dist; GSYM DIST_EQ] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `radV (set_of_list ul:real^3->bool)` THEN CONJ_TAC THENL [ MATCH_MP_TAC EQ_SYM THEN REWRITE_TAC[DIST_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= k + 2`]; ALL_TAC ] THEN REWRITE_TAC[DIST_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[GSYM DOT_RSUB] THEN REWRITE_TAC[VECTOR_ARITH `y - q - (u0 - q):real^3 = y - u0`] THEN REWRITE_TAC[GSYM DOT_LSUB] THEN REAL_ARITH_TAC);;
(* MHFTTZN1 *)
let MHFTTZN1 = 
prove(`!V ul k. packing V /\ barV V k ul ==> aff_dim (set_of_list ul) = &k`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`] MHFTTZN_lemma2) THEN ASM_SIMP_TAC[]);;
(* MHFTTZN2 *)
let MHFTTZN2 = 
prove(`!V ul k. packing V /\ barV V k ul ==> (!p. p IN affine hull voronoi_list V ul <=> (!u. (u IN set_of_list ul ==> p IN bis (HD ul) u)))`,
REPEAT GEN_TAC THEN DISCH_THEN (MP_TAC o MATCH_MP MHFTTZN_lemma) THEN REWRITE_TAC[EXTENSION; IN_INTERS; IN_ELIM_THM] THEN SET_TAC[]);;
(* MHFTTZN3 *)
let MHFTTZN3 = 
prove(`!V ul k. packing V /\ barV V k ul ==> ((affine hull (voronoi_list V ul)) INTER (affine hull (set_of_list ul)) = { circumcenter (set_of_list ul) } )`,
REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o MATCH_MP MHFTTZN_lemma) THEN FIRST_ASSUM (MP_TAC o MATCH_MP MHFTTZN_lemma2) THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC (fun th -> ALL_TAC)) THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[EXTENSION; IN_SING] THEN GEN_TAC THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `HD ul:real^3 IN set_of_list ul` ASSUME_TAC THENL [ MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= k + 1`]; ALL_TAC ] THEN SUBGOAL_THEN `CARD (set_of_list (ul:(real^3)list)) = k + 1` ASSUME_TAC THENL [ SUBGOAL_THEN `CARD (set_of_list (ul:(real^3)list)) <= k + 1` MP_TAC THENL [ MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `LENGTH (ul:(real^3)list)` THEN ASM_REWRITE_TAC[CARD_SET_OF_LIST_LE; LE_REFL]; ALL_TAC ] THEN MP_TAC (ISPEC `set_of_list (ul:(real^3)list)` AFF_DIM_LE_CARD) THEN ASM_REWRITE_TAC[FINITE_SET_OF_LIST] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD; ADD1; GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_EQ] THEN INT_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `~affine_dependent (set_of_list ul:real^3->bool)` ASSUME_TAC THENL [ ASM_REWRITE_TAC[AFFINE_INDEPENDENT_IFF_CARD; FINITE_SET_OF_LIST] THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[IN_INTER; IN_INTERS; IN_ELIM_THM] THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` OAPVION3) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `dist (x, HD ul:real^3)` THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `bis (HD ul) (w:real^3)`) THEN ANTS_TAC THENL [ EXISTS_TAC `w:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SIMP_TAC[bis; IN_ELIM_THM]; ALL_TAC ] THEN SUBGOAL_THEN `~(set_of_list ul = {}:real^3->bool)` ASSUME_TAC THENL [ REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `HD ul:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[OAPVION1] THEN REPEAT STRIP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[bis; IN_ELIM_THM] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `radV (set_of_list ul:real^3->bool)` THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[DIST_SYM] THEN DISCH_TAC THEN CONJ_TAC THENL [ MATCH_MP_TAC EQ_SYM THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
(* MHFTTZN4 *)
let MHFTTZN4 = 
prove(`!V ul k u v. packing V /\ barV V k ul /\ u IN affine hull voronoi_list V ul /\ v IN affine hull (set_of_list ul) ==> ((u - circumcenter (set_of_list ul)) dot (v - circumcenter (set_of_list ul)) = &0)`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`] MHFTTZN_lemma2) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
(*****************************************) (***********) (* XYOFCGX *) (***********)
let ARCV_GT_PI2 = 
prove(`!p u v:real^N. pi / &2 < arcV p u v <=> cos(arcV p u v) < &0`,
REPEAT GEN_TAC THEN EQ_TAC THENL [ DISCH_TAC THEN REWRITE_TAC[GSYM COS_PI2] THEN MATCH_MP_TAC COS_MONO_LT THEN ASM_REWRITE_TAC[ARCV_ANGLE; ANGLE_RANGE] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC; ALL_TAC ] THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LT; REAL_NOT_LE] THEN DISCH_TAC THEN MATCH_MP_TAC COS_POS_PI_LE THEN ASM_SIMP_TAC[ARCV_ANGLE; PI_POS; ANGLE_RANGE; REAL_ARITH `&0 < pi /\ &0 <= x ==> --(pi / &2) <= x`]);;
let XYOFCGX_lemma0 = 
prove(`!V S p w. packing V /\ S SUBSET V /\ ~affine_dependent S /\ (p = circumcenter S) /\ (radV S < sqrt(&2)) /\ w IN V DIFF S /\ dist (p,w) <= radV S /\ 1 < CARD S ==> (!u. u IN S ==> pi / &2 < arcV p w u) /\ (!u v. u IN S /\ v IN S /\ ~(u = v) ==> pi / &2 < arcV p u v)`,
REPEAT GEN_TAC THEN REWRITE_TAC[packing; ARCV_GT_PI2] THEN DISCH_THEN STRIP_ASSUME_TAC THEN SUBGOAL_THEN `!p u w:real^3. ~(p = u) /\ ~(p = w) /\ dist (p,u) < sqrt(&2) /\ dist (p,w) < sqrt(&2) /\ &2 <= dist(u,w) ==> cos(arcV p u w) < &0` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[ARCV_ANGLE] THEN MP_TAC (ISPECL [`p':real^3`; `u:real^3`; `w':real^3`] LAW_OF_COSINES) THEN ABBREV_TAC `d0 = dist(u:real^3,w')` THEN ABBREV_TAC `d1 = dist(p':real^3,u)` THEN ABBREV_TAC `d2 = dist(p':real^3,w')` THEN ABBREV_TAC `x = cos(angle (u:real^3,p',w'))` THEN SUBGOAL_THEN `(d1 pow 2 + d2 pow 2) - d0 pow 2 < &0` ASSUME_TAC THENL [ REWRITE_TAC[REAL_ARITH `a - b < &0 <=> a < b`] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&4` THEN CONJ_TAC THENL [ REWRITE_TAC[REAL_ARITH `&4 = &2 + &2`] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN MP_TAC (SPEC `&2` SQRT_WORKS) THEN REWRITE_TAC[REAL_ARITH `&0 <= &2`] THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC (fun th -> ONCE_REWRITE_TAC[SYM th])) THEN REWRITE_TAC[GSYM REAL_LT_SQUARE_ABS] THEN POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_ABS_REFL] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN EXPAND_TAC "d1" THEN EXPAND_TAC "d2" THEN REWRITE_TAC[dist; REAL_ABS_NORM] THEN ASM_REWRITE_TAC[GSYM dist]; ALL_TAC ] THEN REWRITE_TAC[REAL_ARITH `&4 = &2 pow 2`] THEN REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS; REAL_ARITH `abs(&2) = &2`] THEN EXPAND_TAC "d0" THEN REWRITE_TAC[dist; REAL_ABS_NORM] THEN ASM_REWRITE_TAC[GSYM dist]; ALL_TAC ] THEN REWRITE_TAC[REAL_ARITH `d0 = d12 - x <=> x = d12 - d0:real`] THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `&2 * d1 * d2` THEN CONJ_TAC THENL [ MATCH_MP_TAC REAL_LT_MUL THEN REWRITE_TAC[REAL_ARITH `&0 < &2`] THEN MATCH_MP_TAC REAL_LT_MUL THEN EXPAND_TAC "d1" THEN EXPAND_TAC "d2" THEN ASM_REWRITE_TAC[GSYM DIST_NZ]; ALL_TAC ] THEN ASM_REWRITE_TAC[REAL_MUL_RZERO; GSYM REAL_MUL_ASSOC]; ALL_TAC ] THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN `!x. x IN S ==> dist(p:real^3,x) < sqrt(&2)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `x:real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!u:real^3. u IN S ==> V u /\ ~(u = w)` (LABEL_TAC "A") THENL [ REPEAT STRIP_TAC THENL [ ONCE_REWRITE_TAC[GSYM IN] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN UNDISCH_TAC `u:real^3 IN S` THEN UNDISCH_TAC `w:real^3 IN V DIFF S` THEN ASM_SIMP_TAC[IN_DIFF]; ALL_TAC ] THEN SUBGOAL_THEN `(V:real^3->bool) w` ASSUME_TAC THENL [ UNDISCH_TAC `w:real^3 IN V DIFF S` THEN SIMP_TAC[IN_DIFF; IN]; ALL_TAC ] THEN CONJ_TAC THEN REPEAT STRIP_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN SUBGOAL_THEN `~(circumcenter S = u:real^3)` ASSUME_TAC THENL [ MP_TAC (ISPEC `S:real^3->bool` CIRCUMCENTER_NOT_EQ) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `u:real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `u:real^3`) THEN ASM_REWRITE_TAC[REAL_NOT_LT] THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&2` THEN CONJ_TAC THENL [ MATCH_MP_TAC REAL_LE_LSQRT THEN REAL_ARITH_TAC; ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `radV (S:real^3->bool)` THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `p = circumcenter S:real^3` THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]); REMOVE_THEN "A" (fun th -> ALL_TAC) THEN FIRST_X_ASSUM (MP_TAC o SPEC `u:real^3`) THEN ASM_SIMP_TAC[]; FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[] ]; ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[CIRCUMCENTER_NOT_EQ] THEN UNDISCH_TAC `p:real^3 = circumcenter S` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[]);;
let CARD_1_IMP_SING = 
prove(`!s:A->bool. FINITE s /\ CARD s = 1 ==> ?x. s = {x}`,
REWRITE_TAC[GSYM HAS_SIZE] THEN REWRITE_TAC[HAS_SIZE_1_EXISTS; EXISTS_UNIQUE] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `x:A` THEN REWRITE_TAC[EXTENSION; IN_SING] THEN GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ASM_REWRITE_TAC[] ]);;
(* CARD S <= 1 *)
let XYOFCGX_1 = 
prove(`!V S p. packing V /\ S SUBSET V /\ ~affine_dependent S /\ p = circumcenter S /\ radV S < sqrt(&2) /\ CARD S <= 1 ==> (!u v. u IN S /\ v IN (V DIFF S) ==> dist (v,p) > dist (u,p))`,
REWRITE_TAC[ARITH_RULE `a <= 1 <=> a = 0 \/ a = 1`] THEN REPEAT STRIP_TAC THENL [ MP_TAC (ISPEC `S:real^3->bool` CARD_EQ_0) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN DISCH_TAC THEN UNDISCH_TAC `u:real^3 IN S` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY]; ALL_TAC ] THEN MP_TAC (ISPEC `S:real^3->bool` Hypermap.set_one_point) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN DISCH_THEN (MP_TAC o SPEC `u:real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[CIRCUMCENTER_1; DIST_REFL; GSYM DIST_NZ; real_gt] THEN UNDISCH_TAC `v:real^3 IN V DIFF S` THEN ASM_REWRITE_TAC[IN_DIFF; IN_SING] THEN SIMP_TAC[]);;
(* CARD S = 2 *)
let CIRCUMCENTER_2 = 
prove(`!a b:real^N. circumcenter {a, b} = midpoint (a,b)`,
REPEAT GEN_TAC THEN MATCH_MP_TAC EQ_SYM THEN MP_TAC (SPEC `{a,b:real^N}` OAPVION3) THEN REWRITE_TAC[AFFINE_INDEPENDENT_2] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL [ REWRITE_TAC[AFFINE_HULL_2; midpoint; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC [`inv(&2)`; `inv(&2)`] THEN REWRITE_TAC[VECTOR_ADD_LDISTRIB] THEN REAL_ARITH_TAC; ALL_TAC ] THEN EXISTS_TAC `dist(a:real^N,b) / &2` THEN REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[DIST_MIDPOINT]);;
let CARD_2_IMP_DOUBLE = 
prove(`!s:A->bool. FINITE s /\ CARD s = 2 ==> (?a b. s = {a, b} /\ ~(a = b))`,
REWRITE_TAC[GSYM HAS_SIZE; HAS_SIZE_2_EXISTS] THEN REPEAT STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`x:A`; `y:A`] THEN ASM_REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY]);;
let XYOFCGX_2 = 
prove(`!V S p. packing V /\ S SUBSET V /\ ~affine_dependent S /\ p = circumcenter S /\ radV S < sqrt(&2) /\ CARD S = 2 ==> (!u v. u IN S /\ v IN (V DIFF S) ==> dist (v,p) > dist (u,p))`,
REPEAT STRIP_TAC THEN ASM_CASES_TAC `dist (v,p:real^3) > dist(u,p)` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN PURE_REWRITE_TAC[real_gt; REAL_NOT_LT; DIST_SYM] THEN DISCH_TAC THEN SUBGOAL_THEN `dist (p:real^3,v) <= radV (S:real^3->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `dist (p,u:real^3)` THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[REAL_LE_LT] THEN DISJ2_TAC THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> MATCH_MP_TAC (GSYM th)) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `S:real^3->bool`; `p:real^3`; `v:real^3`] XYOFCGX_lemma0) THEN ASM_REWRITE_TAC[ARITH_RULE `1 < 2`] THEN MP_TAC (ISPEC `S:real^3->bool`CARD_2_IMP_DOUBLE) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN STRIP_TAC THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC (fun th -> ALL_TAC)) THEN FIRST_ASSUM (MP_TAC o SPEC `a:real^3`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `b:real^3`) THEN ASM_REWRITE_TAC[IN_INSERT; CIRCUMCENTER_2; ARCV_ANGLE] THEN REPEAT DISCH_TAC THEN MP_TAC (ISPECL [`a:real^3`; `b:real^3`; `midpoint (a:real^3,b)`; `v:real^3`] ANGLES_ALONG_LINE) THEN ASM_REWRITE_TAC[BETWEEN_MIDPOINT; MIDPOINT_EQ_ENDPOINT] THEN ONCE_REWRITE_TAC[ANGLE_SYM] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
(* CARD S = 3 *)
let ANGLE_GT_PI2 = 
prove(`!a b c:real^N. pi / &2 < angle (a,b,c) <=> (a - b) dot (c - b) < &0`,
REPEAT STRIP_TAC THEN REWRITE_TAC[angle; vector_angle] THEN ASM_CASES_TAC `a - b = vec 0:real^N \/ c - b = vec 0` THEN ASM_REWRITE_TAC[] THENL [ REWRITE_TAC[REAL_LT_REFL; REAL_NOT_LT; REAL_LE_LT] THEN DISJ2_TAC THEN POP_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[DOT_LZERO; DOT_RZERO]; ALL_TAC ] THEN ABBREV_TAC `x = (a - b:real^N) dot (c - b)` THEN ABBREV_TAC `y = norm (a - b:real^N) * norm (c - b)` THEN SUBGOAL_THEN `-- &1 <= x / y /\ x / y <= &1` ASSUME_TAC THENL [ EXPAND_TAC "x" THEN EXPAND_TAC "y" THEN MATCH_MP_TAC Trigonometry1.NORM_CAUCHY_SCHWARZ_FRAC THEN ASM_REWRITE_TAC[GSYM DE_MORGAN_THM]; ALL_TAC ] THEN EQ_TAC THENL [ REWRITE_TAC[GSYM ACS_0] THEN MP_TAC (SPECL [`&0`; `x / y`] ACS_MONO_LT_EQ) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[REAL_ARITH `abs a <= &1 <=> -- &1 <= a /\ a <= &1`] THEN REAL_ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LT] THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_DIV THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "y" THEN MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE]; ALL_TAC ] THEN REWRITE_TAC[GSYM ACS_0] THEN DISCH_TAC THEN MATCH_MP_TAC ACS_MONO_LT THEN ASM_REWRITE_TAC[REAL_ARITH `&0 <= &1`] THEN ONCE_REWRITE_TAC[REAL_ARITH `x / y < &0 <=> &0 < --x / y`] THEN MATCH_MP_TAC REAL_LT_DIV THEN ASM_REWRITE_TAC[REAL_NEG_GT0] THEN EXPAND_TAC "y" THEN MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[NORM_POS_LT; GSYM DE_MORGAN_THM]);;
let AZIM_COMPL_EXT = 
prove(`!v w a b. azim v w b a = if azim v w a b = &0 then &0 else &2 * pi - azim v w a b`,
REPEAT GEN_TAC THEN ASM_CASES_TAC `collinear {v, w, a:real^3}` THENL [ ASM_REWRITE_TAC[azim_def]; ALL_TAC ] THEN ASM_CASES_TAC `collinear {v, w, b:real^3}` THENL [ ASM_REWRITE_TAC[azim_def]; ALL_TAC ] THEN MATCH_MP_TAC AZIM_COMPL THEN ASM_REWRITE_TAC[]);;
let AZIM_EQ_SYM = 
prove(`!v w a b c. azim v w b a = azim v w c a <=> azim v w a b = azim v w a c`,
REPEAT GEN_TAC THEN EQ_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[AZIM_COMPL_EXT] THEN ASM_REWRITE_TAC[]);;
(* A special configuration of points is a fan *)
let STRICT_CYCLIC_IMP_FAN = 
prove(`!V p. FINITE V /\ 2 <= CARD V /\ (!v w. v IN V /\ w IN V /\ ~(v = w) ==> &0 < azim (vec 0) p v w) ==> FAN (vec 0, V UNION {p}, {{p, v} | v | v IN V})`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `?v w:real^3. v IN V /\ w IN V /\ ~(v = w)` MP_TAC THENL [ MP_TAC (ISPEC `V:real^3->bool` CHOOSE_SUBSET) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `2`) THEN ASM_REWRITE_TAC[LE_REFL; HAS_SIZE_2_EXISTS] THEN REPEAT STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`x:real^3`; `y:real^3`] THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `t:real^3->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN SUBGOAL_THEN `!v:real^3. v IN V ==> ~collinear {vec 0, p, v}` (LABEL_TAC "c") THENL [ REPEAT STRIP_TAC THEN ASM_CASES_TAC `v:real^3 = v'` THENL [ FIRST_X_ASSUM (MP_TAC o SPECL [`v:real^3`; `w:real^3`]) THEN ASM_REWRITE_TAC[azim_def; REAL_LT_REFL]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`v':real^3`; `v:real^3`]) THEN ASM_REWRITE_TAC[azim_def; REAL_LT_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `!v:real^3. v IN V ==> DISJOINT {vec 0, p} {v} /\ DISJOINT {vec 0} {p, v}` (LABEL_TAC "d") THENL [ REPEAT STRIP_TAC THENL [ MATCH_MP_TAC Collect_geom.COLLINEAR_DISJOINT3 THEN FIRST_X_ASSUM (MP_TAC o SPEC `v':real^3`) THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[Collect_geom.PER_SET3]; REWRITE_TAC[DISJOINT; INTER_ACI] THEN REWRITE_TAC[GSYM DISJOINT] THEN MATCH_MP_TAC Collect_geom.COLLINEAR_DISJOINT3 THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] ]; ALL_TAC ] THEN SUBGOAL_THEN `~(p:real^3 = vec 0) /\ ~(p IN V) /\ ~(vec 0 IN V)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THENL [ REMOVE_THEN "c" (MP_TAC o SPEC `v:real^3`) THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT]; REMOVE_THEN "c" (MP_TAC o SPEC `p:real^3`) THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT] THEN DISJ2_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[VECTOR_MUL_LID]; REMOVE_THEN "c" (MP_TAC o SPEC `vec 0:real^3`) THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT] THEN DISJ2_TAC THEN EXISTS_TAC `&0` THEN REWRITE_TAC[VECTOR_MUL_LZERO] ]; ALL_TAC ] THEN POP_ASSUM STRIP_ASSUME_TAC THEN SUBGOAL_THEN `!v:real^3. v IN V ==> ~(v = p)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN POP_ASSUM (ASSUME_TAC o SYM) THEN UNDISCH_TAC `~(p:real^3 IN V)` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[Fan_defs.FAN] THEN REPEAT STRIP_TAC THENL [ (* UNIONS E SUBSET (V UNION {p}) *) REWRITE_TAC[SUBSET; IN_UNIONS; IN_UNION; IN_ELIM_THM; IN_SING] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; (* graph E *) REWRITE_TAC[Fan_defs.graph; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[HAS_SIZE_2_EXISTS; IN_INSERT; NOT_IN_EMPTY] THEN MAP_EVERY EXISTS_TAC [`p:real^3`; `v':real^3`] THEN REWRITE_TAC[] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; (* FINITE V /\ ~(V = {}) *) ASM_REWRITE_TAC[Fan_defs.fan1; FINITE_UNION; FINITE_SING; SUBSET_EMPTY] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `p:real^3` THEN REWRITE_TAC[IN_UNION; IN_SING]; (* ~(vec 0 IN V) *) ASM_REWRITE_TAC[Fan_defs.fan2; IN_UNION; IN_SING]; (* ~collinear {vec 0, e} *) REWRITE_TAC[Fan_defs.fan6; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `{vec 0:real^3} UNION {p, v'} = {vec 0, p, v'}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_UNION; IN_INSERT; NOT_IN_EMPTY]; ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN (* fan7 *) REWRITE_TAC[Fan_defs.fan7; IN_UNION; IN_ELIM_THM; IN_SING] THEN SUBGOAL_THEN `!t1 t2 r1 r2 x y v w:real^3. v IN V /\ w IN V /\ x = t1 % p + t2 % v /\ y = r1 % p + r2 % w /\ &0 < t2 /\ &0 < r2 ==> azim (vec 0) p x y = azim (vec 0) p v w` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN FIRST_X_ASSUM ((fun th -> ALL_TAC) o SPEC `v:real^3`) THEN SUBGOAL_THEN `~collinear {vec 0, p, x:real^3} /\ ~collinear {vec 0, p, y}` ASSUME_TAC THENL [ ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT; DE_MORGAN_THM; NOT_EXISTS_THM] THEN REWRITE_TAC[VECTOR_ARITH `t1 % p + t2 % v = c % p <=> t2 % v = (c - t1) % p:real^3`] THEN CONJ_TAC THEN GEN_TAC THENL [ DISCH_THEN (MP_TAC o AP_TERM `\v:real^3. inv(t2) % v`) THEN ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_ARITH `&0 < a ==> ~(a = &0)`; REAL_MUL_LINV] THEN REMOVE_THEN "c" (MP_TAC o SPEC `v':real^3`) THEN ASM_SIMP_TAC[COLLINEAR_LEMMA_ALT; VECTOR_MUL_LID; NOT_EXISTS_THM]; DISCH_THEN (MP_TAC o AP_TERM `\v:real^3. inv(r2) % v`) THEN ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_ARITH `&0 < a ==> ~(a = &0)`; REAL_MUL_LINV] THEN REMOVE_THEN "c" (MP_TAC o SPEC `w':real^3`) THEN ASM_SIMP_TAC[COLLINEAR_LEMMA_ALT; VECTOR_MUL_LID; NOT_EXISTS_THM] ]; ALL_TAC ] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `azim (vec 0) p v' y` THEN CONJ_TAC THENL [ ONCE_REWRITE_TAC[AZIM_EQ_SYM] THEN MATCH_MP_TAC EQ_SYM THEN MP_TAC (SPECL [`vec 0:real^3`; `p:real^3`; `y:real^3`; `v':real^3`; `x:real^3`] AZIM_EQ) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[AFF_GT_2_1; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC [`&1 - t1 - t2`; `t1:real`; `t2:real`] THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN REAL_ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC EQ_SYM THEN MP_TAC (SPECL [`vec 0:real^3`; `p:real^3`; `v':real^3`; `w':real^3`; `y:real^3`] AZIM_EQ) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[AFF_GT_2_1; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC [`&1 - r1 - r2`; `r1:real`; `r2:real`] THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN REAL_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `!v w:real^3. v IN V /\ w IN V ==> aff_ge {vec 0} {p, v} INTER aff_ge {vec 0} {p, w} = if (v = w) then aff_ge {vec 0} {p, v} else aff_ge {vec 0} {p}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[INTER_ACI] THEN ASM_SIMP_TAC[Fan.AFF_GE_1_2; HALFLINE] THEN REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID; EXTENSION; IN_ELIM_THM; IN_INTER] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN ASM_CASES_TAC `t3 = &0` THENL [ EXISTS_TAC `t2:real` THEN UNDISCH_TAC `x = t2 % p + t3 % v':real^3` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN ASM_CASES_TAC `t3' = &0` THENL [ EXISTS_TAC `t2':real` THEN UNDISCH_TAC `x = t2' % p + t3' % w':real^3` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `azim (vec 0) p x x = azim (vec 0) p v' w'` MP_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN MAP_EVERY EXISTS_TAC [`t2:real`; `t3:real`; `t2':real`; `t3':real`] THEN ASM_REWRITE_TAC[REAL_LT_LE] THEN UNDISCH_TAC `x = t2 % p + t3 % v':real^3` THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`v':real^3`; `w':real^3`]) THEN ASM_REWRITE_TAC[AZIM_REFL] THEN REAL_ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THEN CONJ_TAC THEN MAP_EVERY EXISTS_TAC [`&1 - t`; `t:real`; `&0`] THEN ASM_REWRITE_TAC[REAL_LE_REFL] THENL [ CONJ_TAC THENL [ REAL_ARITH_TAC; VECTOR_ARITH_TAC ]; CONJ_TAC THENL [ REAL_ARITH_TAC; VECTOR_ARITH_TAC ] ]; ALL_TAC ] THEN SUBGOAL_THEN `!v w:real^3. v IN V /\ w IN V ==> aff_ge {vec 0} {p, v} INTER aff_ge {vec 0} {w} = if (v = w) then aff_ge {vec 0} {v} else aff_ge {vec 0} {}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN COND_CASES_TAC THENL [ ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[INTER_ACI] THEN REWRITE_TAC[GSYM SUBSET_INTER_ABSORPTION] THEN MATCH_MP_TAC AFF_GE_MONO_RIGHT THEN ASM_SIMP_TAC[SUBSET; IN_INSERT; NOT_IN_EMPTY]; ALL_TAC ] THEN REWRITE_TAC[AFF_GE_EQ_AFFINE_HULL; AFFINE_HULL_SING] THEN ASM_SIMP_TAC[Fan.AFF_GE_1_2] THEN REWRITE_TAC[EXTENSION; IN_SING; HALFLINE; IN_INTER; IN_ELIM_THM; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN ASM_CASES_TAC `t = &0` THENL [ UNDISCH_TAC `x = t % w':real^3` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO]; ALL_TAC ] THEN ASM_CASES_TAC `t3 = &0` THENL [ UNDISCH_TAC `x = t % w':real^3` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_RID] THEN REMOVE_THEN "c" (MP_TAC o SPEC `w':real^3`) THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT; NOT_EXISTS_THM] THEN DISCH_TAC THEN DISCH_THEN (MP_TAC o AP_TERM `\v:real^3. inv t % v`) THEN ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]; ALL_TAC ] THEN SUBGOAL_THEN `azim (vec 0) p x x = azim (vec 0) p v' w'` MP_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN MAP_EVERY EXISTS_TAC [`t2:real`; `t3:real`; `&0`; `t:real`] THEN ASM_REWRITE_TAC[REAL_LT_LE; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN UNDISCH_TAC `x = t % w':real^3` THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN REPLICATE_TAC 2 (FIRST_X_ASSUM (MP_TAC o SPECL [`v':real^3`; `w':real^3`])) THEN ASM_REWRITE_TAC[AZIM_REFL] THEN REAL_ARITH_TAC; ALL_TAC ] THEN DISCH_TAC THEN CONJ_TAC THENL [ MAP_EVERY EXISTS_TAC [`&1`; `&0`; `&0`] THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN REAL_ARITH_TAC; ALL_TAC ] THEN EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO; REAL_LE_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `!v:real^3. v IN V ==> aff_ge {vec 0} {p, v} INTER aff_ge {vec 0} {p} = aff_ge {vec 0} {p}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[INTER_ACI] THEN REWRITE_TAC[GSYM SUBSET_INTER_ABSORPTION] THEN MATCH_MP_TAC AFF_GE_MONO_RIGHT THEN ASM_SIMP_TAC[SUBSET; IN_INSERT; NOT_IN_EMPTY]; ALL_TAC ] THEN SUBGOAL_THEN `!v w:real^3. {p, v} INTER {p, w} = if (v = w) then {p, v} else {p}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN COND_CASES_TAC THENL [ ASM_REWRITE_TAC[INTER_ACI]; ALL_TAC ] THEN REWRITE_TAC[EXTENSION; IN_INTER; IN_INSERT; NOT_IN_EMPTY] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN UNDISCH_TAC `~(v' = w':real^3)` THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]); ALL_TAC ] THEN SIMP_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!v:real^3. {p, v} INTER {p} = {p} /\ {p} INTER {p, v} = {p}` ASSUME_TAC THENL [ REWRITE_TAC[INTER_ACI; GSYM SUBSET_INTER_ABSORPTION; SUBSET; IN_INSERT; NOT_IN_EMPTY] THEN SIMP_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!v w:real^3. w IN V ==> {p, v} INTER {w} = if (v = w) then {v} else {}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN COND_CASES_TAC THENL [ ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[INTER_ACI] THEN ASM_REWRITE_TAC[GSYM SUBSET_INTER_ABSORPTION; SUBSET] THEN SIMP_TAC[IN_INSERT]; ALL_TAC ] THEN REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_INSERT; DE_MORGAN_THM] THEN GEN_TAC THEN ASM_CASES_TAC `~(x = w':real^3)` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_CLAUSES] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!v w:real^3. v IN V /\ w IN V ==> aff_ge {vec 0} {v} INTER aff_ge {vec 0} {w} = if (v = w) then aff_ge {vec 0} {v} else aff_ge {vec 0} {}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[INTER_ACI] THEN REWRITE_TAC[AFF_GE_EQ_AFFINE_HULL; AFFINE_HULL_SING] THEN REWRITE_TAC[EXTENSION; IN_SING; HALFLINE; IN_INTER; IN_ELIM_THM; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN ASM_CASES_TAC `t = &0` THENL [ UNDISCH_TAC `x = t % v':real^3` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO]; ALL_TAC ] THEN ASM_CASES_TAC `t' = &0` THENL [ UNDISCH_TAC `x = t' % w':real^3` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO]; ALL_TAC ] THEN SUBGOAL_THEN `azim (vec 0) p x x = azim (vec 0) p v' w'` MP_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN MAP_EVERY EXISTS_TAC [`&0`; `t:real`; `&0`; `t':real`] THEN ASM_REWRITE_TAC[REAL_LT_LE; VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN UNDISCH_TAC `x = t % v':real^3` THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN SUBGOAL_THEN `&0 < azim (vec 0) p v' w'` MP_TAC THENL [ FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[AZIM_REFL] THEN REAL_ARITH_TAC; ALL_TAC ] THEN DISCH_TAC THEN CONJ_TAC THEN EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[REAL_LE_REFL; VECTOR_MUL_LZERO]; ALL_TAC ] THEN SUBGOAL_THEN `!v w:real^3. {v} INTER {w} = if (v = w) then {v} else {}` ASSUME_TAC THENL [ REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[INTER_ACI] THEN REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_SING] THEN GEN_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN ASM_CASES_TAC `x = v':real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!v:real^3. v IN V ==> aff_ge {vec 0} {v} INTER aff_ge {vec 0} {p} = aff_ge {vec 0} {}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[HALFLINE; AFF_GE_EQ_AFFINE_HULL; AFFINE_HULL_SING; IN_INTER; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN REWRITE_TAC[EXTENSION; IN_INTER; IN_SING; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN REMOVE_THEN "c" (MP_TAC o SPEC `v':real^3`) THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA_ALT; NOT_EXISTS_THM] THEN DISCH_TAC THEN ASM_CASES_TAC `t = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN UNDISCH_TAC `x = t % v':real^3` THEN DISCH_THEN (MP_TAC o AP_TERM `\v:real^3. inv t % v`) THEN ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]; ALL_TAC ] THEN DISCH_TAC THEN CONJ_TAC THEN EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[REAL_LE_REFL; VECTOR_MUL_LZERO]; ALL_TAC ] THEN SUBGOAL_THEN `!v:real^3. v IN V ==> {v} INTER {p} = {}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[IN_INTER; EXTENSION; NOT_IN_EMPTY; IN_SING; DE_MORGAN_THM] THEN GEN_TAC THEN ASM_CASES_TAC `x = p:real^3` THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (ASSUME_TAC o SYM) THEN UNDISCH_TAC `v':real^3 IN V` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[INTER_ACI] THEN ASM_SIMP_TAC[] THEN TRY (COND_CASES_TAC THEN ASM_REWRITE_TAC[]) );;
let STRICT_CYCLIC_FAN_PROPERTIES = 
prove(`!V p. let W = V UNION {p} in let E = {{p,v} | v | v IN V} in FAN (vec 0, W, E) ==> (!v. v IN V ==> (p, v) IN dart1_of_fan (W,E)) /\ set_of_edge p W E = V /\ (!v. v IN V ==> node (hypermap_of_fan (W,E)) (p,v) = {(p,w) | w | w IN V})`,
REPEAT GEN_TAC THEN CONV_TAC (DEPTH_CONV let_CONV) THEN ABBREV_TAC `W = V UNION {p:real^3}` THEN ABBREV_TAC `E = {{p, v:real^3} | v | v IN V}` THEN DISCH_TAC THEN SUBGOAL_THEN `!v:real^3. v IN V ==> (p, v) IN dart1_of_fan (W,E)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN EXPAND_TAC "E" THEN REWRITE_TAC[Fan_defs.dart1_of_fan; IN_ELIM_THM] THEN MAP_EVERY EXISTS_TAC [`p:real^3`; `v:real^3`] THEN REWRITE_TAC[] THEN EXISTS_TAC `v:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `set_of_edge p W E = V:real^3->bool` ASSUME_TAC THENL [ SUBGOAL_THEN `~(p:real^3 IN V)` MP_TAC THENL [ DISCH_TAC THEN UNDISCH_TAC `FAN (vec 0:real^3,W,E)` THEN REWRITE_TAC[Fan_defs.FAN; Fan_defs.graph] THEN DISCH_THEN (CONJUNCTS_THEN2 (fun th -> ALL_TAC) MP_TAC) THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC (fun th -> ALL_TAC)) THEN DISCH_THEN (MP_TAC o SPEC `{p:real^3, p}`) THEN EXPAND_TAC "E" THEN REWRITE_TAC[IN_ELIM_THM; NOT_IMP] THEN SUBGOAL_THEN `{p:real^3,p} = {p}` ASSUME_TAC THENL [ REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY]; ALL_TAC ] THEN ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_EMPTY; NOT_IN_EMPTY] THEN REWRITE_TAC[DE_MORGAN_THM; ARITH_RULE `~(SUC 0 = 2)`] THEN EXISTS_TAC `p:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[Fan_defs.set_of_edge] THEN EXPAND_TAC "E" THEN EXPAND_TAC "W" THEN REWRITE_TAC[EXTENSION; IN_UNION; IN_ELIM_THM; IN_SING] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `v:real^3`) THEN ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN DISCH_TAC THEN UNDISCH_TAC `v:real^3 IN V` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `x:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[Hypermap_and_fan.NODE_HYPERMAP_OF_FAN_ALT]);;
let ANGLE_SUM_lemma = 
prove(`!V p. FINITE V /\ 2 <= CARD V /\ (!v w. v IN V /\ w IN V /\ ~(v = w) ==> &0 < azim (vec 0) p v w) ==> ?f. (!x. x IN V ==> f x IN V /\ ~(x = f x)) /\ sum V (\x. azim (vec 0) p x (f x)) = &2 * pi`,
REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o MATCH_MP STRICT_CYCLIC_IMP_FAN) THEN DISCH_TAC THEN ABBREV_TAC `W = V UNION {p:real^3}` THEN ABBREV_TAC `E = {{p, v:real^3} | v | v IN V}` THEN MP_TAC (SPEC_ALL STRICT_CYCLIC_FAN_PROPERTIES) THEN CONV_TAC (DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `sigma_fan (vec 0) W E p` THEN CONJ_TAC THENL [ GEN_TAC THEN DISCH_TAC THEN MP_TAC (SPECL [`vec 0:real^3`; `W:real^3->bool`; `E:(real^3->bool)->bool`; `p:real^3`; `x:real^3`] Fan.SIGMA_FAN) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o check (is_conj o concl)) THEN ASM_SIMP_TAC[CARD_CLAUSES; FINITE_EMPTY; NOT_IN_EMPTY] THEN ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `?v:real^3. v IN V` CHOOSE_TAC THENL [ REWRITE_TAC[MEMBER_NOT_EMPTY] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o check (is_conj o concl)) THEN ASM_REWRITE_TAC[CARD_CLAUSES] THEN ARITH_TAC; ALL_TAC ] THEN MP_TAC (SPECL [`W:real^3->bool`; `E:(real^3->bool)->bool`; `(p:real^3,v:real^3)`] Hypermap_and_fan.SUM_AZIM_DART) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `dart1_of_fan (W:real^3->bool,E)` THEN ASM_SIMP_TAC[Hypermap_and_fan.DART1_OF_FAN_SUBSET_DART_OF_FAN]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[] THEN SUBGOAL_THEN `{p:real^3, w:real^3 | w IN V} = IMAGE (\v. p, v) V` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[IMAGE_LEMMA]; ALL_TAC ] THEN MP_TAC (ISPECL [`\x. azim (vec 0) p x (sigma_fan (vec 0) W E p x)`; `V:real^3->bool`] SUM_RESTRICT) THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `(\x. if x IN V then azim (vec 0) p x (sigma_fan (vec 0) W E p x) else &0) = (\x. if x IN V then ((azim_dart (W,E)) o (\v. p, v)) x else &0)` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[o_THM] THEN REWRITE_TAC[Fan_defs.azim_dart; Fan_defs.azim_fan] THEN SUBGOAL_THEN `~(p = x:real^3)` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC Hypermap_and_fan.PAIR_IN_DART1_OF_FAN_IMP_NOT_EQ THEN MAP_EVERY EXISTS_TAC [`W:real^3->bool`; `E:(real^3->bool)->bool`] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[ARITH_RULE `2 <= a ==> a > 1`]; ALL_TAC ] THEN MP_TAC (ISPECL [`azim_dart (W,E) o (\v. p,v)`; `V:real^3->bool`] SUM_RESTRICT) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC (GSYM SUM_IMAGE) THEN SIMP_TAC[PAIR_EQ]);;
let ANGLE_SUM_BOUND = 
prove(`!V (p:real^3) a. &0 <= a /\ FINITE V /\ 2 <= CARD V /\ (!v w. v IN V /\ w IN V /\ ~(v = w) ==> a < azim (vec 0) p v w) ==> a * &(CARD V) < &2 * pi`,
REPEAT STRIP_TAC THEN MP_TAC (SPEC_ALL ANGLE_SUM_lemma) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `a:real` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `sum V (\x. azim (vec 0) p x (f x))` THEN CONJ_TAC THENL [ REMOVE_ASSUM THEN SUBGOAL_THEN `!x. azim (vec 0) p x (f x) = -- (--azim (vec 0) p x (f x))` (fun th -> ONCE_REWRITE_TAC[th]) THENL [ REAL_ARITH_TAC; ALL_TAC ] THEN ONCE_REWRITE_TAC[SUM_NEG] THEN REWRITE_TAC[REAL_ARITH `a * b < --c <=> c < b * (--a)`] THEN MATCH_MP_TAC SUM_BOUND_LT THEN ASM_REWRITE_TAC[REAL_LE_NEG] THEN ASM_SIMP_TAC[REAL_LE_LT] THEN SUBGOAL_THEN `?x:real^3. x IN V` CHOOSE_TAC THENL [ REWRITE_TAC[MEMBER_NOT_EMPTY] THEN DISCH_TAC THEN UNDISCH_TAC `2 <= CARD (V:real^3->bool)` THEN ASM_REWRITE_TAC[CARD_CLAUSES; ARITH_RULE `~(2 <= 0)`]; ALL_TAC ] THEN EXISTS_TAC `x:real^3` THEN ASM_SIMP_TAC[REAL_LT_NEG]; ALL_TAC ] THEN ASM_REWRITE_TAC[REAL_LE_REFL]);;
let DIHV_LE_AZIM = 
prove(`!v w x y. ~collinear {v, w, x} /\ ~collinear {v, w, y} ==> dihV v w x y <= azim v w x y`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`v:real^3`; `w:real^3`; `x:real^3`; `y:real^3`] AZIM_DIVH) THEN ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL] THEN DISCH_TAC THEN REWRITE_TAC[REAL_ARITH `a <= &2 * b - a <=> a <= b`] THEN REWRITE_TAC[DIHV_RANGE]);;
let IN_PLANE_NOT_COLLINEAR = 
prove(`!v n:real^N. ~(v = vec 0) /\ ~(n = vec 0) /\ n dot v = &0 ==> ~collinear {vec 0, n, v}`,
REWRITE_TAC[COLLINEAR_LEMMA_ALT; DE_MORGAN_THM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN GEN_TAC THEN ASM_CASES_TAC `c = &0` THEN ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN DISCH_THEN (MP_TAC o AP_TERM `\v:real^N. n dot v`) THEN ASM_REWRITE_TAC[DOT_RMUL; EQ_SYM_EQ; REAL_ENTIRE; DOT_EQ_0]);;
let ANGLE_EQ_DIHV = 
prove(`!v w n:real^N. ~(v = vec 0) /\ ~(w = vec 0) /\ ~(n = vec 0) /\ n dot v = &0 /\ n dot w = &0 ==> angle (v, vec 0, w) = dihV (vec 0) n v w`,
REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[angle; dihV; VECTOR_SUB_RZERO; vector_angle; arcV] THEN CONV_TAC (DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[DOT_SYM; VECTOR_MUL_LZERO; VECTOR_SUB_RZERO; DOT_LMUL; DOT_RMUL; NORM_MUL] THEN AP_TERM_TAC THEN REWRITE_TAC[DOT_SQUARE_NORM; REAL_ABS_POW; REAL_ABS_NORM; real_div; REAL_INV_MUL] THEN REWRITE_TAC[REAL_ARITH `(nn * nn * vw) * (inn * iv) * inn * iw = (vw * iv * iw) * (nn * inn) * (nn * inn)`] THEN SUBGOAL_THEN `~(norm (n:real^N) pow 2 = &0)` MP_TAC THENL [ ASM_REWRITE_TAC[NORM_POW_2; DOT_EQ_0]; ALL_TAC ] THEN SIMP_TAC[REAL_MUL_RINV; REAL_MUL_RID]);;
let PYTHAGORAS_PROJECTION = 
prove(`!x y n:real^N. x dot n = &0 ==> dist (x, y) pow 2 = dist (x, projection n y) pow 2 + dist (projection n y, y) pow 2`,
REPEAT STRIP_TAC THEN MP_TAC (SPECL [`y:real^N`; `projection (n:real^N) y`; `x:real^N`] PYTHAGORAS) THEN ANTS_TAC THENL [ REWRITE_TAC[projection; VECTOR_ARITH `y - (y - a % n) = a % n:real^N`] THEN REWRITE_TAC[orthogonal; DOT_RSUB; DOT_LMUL; DOT_RMUL] THEN POP_ASSUM MP_TAC THEN SIMP_TAC[DOT_SYM] THEN DISCH_TAC THEN REWRITE_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN ASM_CASES_TAC `n dot (n:real^N) = &0` THENL [ SUBGOAL_THEN `n = vec 0:real^N` ASSUME_TAC THENL [ ASM_REWRITE_TAC[GSYM DOT_EQ_0]; ALL_TAC ] THEN ASM_REWRITE_TAC[DOT_LZERO] THEN REAL_ARITH_TAC; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD; ALL_TAC ] THEN REWRITE_TAC[dist] THEN REAL_ARITH_TAC);;
let OBTUSE_ANGLE_PROJECTION = 
prove(`!a w n:real^N. pi / &2 < angle (a,vec 0,w) /\ a dot n = &0 ==> pi / &2 < angle (a, vec 0, projection n w)`,
REWRITE_TAC[ANGLE_GT_PI2; VECTOR_SUB_RZERO; projection] THEN SIMP_TAC[DOT_RSUB; DOT_RMUL; REAL_MUL_RZERO; REAL_SUB_RZERO]);;
let XYOFCGX_3_0 = 
prove(`!V S. packing V /\ S SUBSET V /\ ~affine_dependent S /\ circumcenter S = vec 0 /\ radV S < sqrt(&2) /\ CARD S = 3 ==> (!u v. u IN S /\ v IN (V DIFF S) ==> dist (v,vec 0) > dist (u,vec 0))`,
REPEAT STRIP_TAC THEN ASM_CASES_TAC `dist (v,vec 0:real^3) > dist(u,vec 0:real^3)` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN PURE_REWRITE_TAC[real_gt; REAL_NOT_LT; DIST_SYM] THEN DISCH_TAC THEN SUBGOAL_THEN `!u:real^3. u IN S ==> dist (u, vec 0) = radV S` (LABEL_TAC "r") THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[DIST_SYM] THEN DISCH_THEN (MATCH_MP_TAC o GSYM) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `dist (v:real^3, vec 0) <= radV (S:real^3->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `dist (u:real^3, vec 0)` THEN ASM_REWRITE_TAC[REAL_LE_LT] THEN DISJ2_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `~(S = {}:real^3->bool)` ASSUME_TAC THENL [ DISCH_TAC THEN UNDISCH_TAC `CARD (S:real^3->bool) = 3` THEN ASM_REWRITE_TAC[CARD_CLAUSES; ARITH_RULE `~(0 = 3)`]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `S:real^3->bool`; `vec 0:real^3`; `v:real^3`] XYOFCGX_lemma0) THEN ASM_REWRITE_TAC[DIST_SYM; ARITH_RULE `1 < 3`; ARCV_ANGLE] THEN STRIP_TAC THEN SUBGOAL_THEN `?n:real^3. ~(n = vec 0) /\ (!u. u IN S ==> n dot u = &0)` MP_TAC THENL [ MP_TAC (ISPEC `S:real^3->bool` LOWDIM_SUBSET_HYPERPLANE) THEN ANTS_TAC THENL [ MP_TAC (ISPEC `S:real^3->bool` AFF_DIM_DIM_0) THEN ANTS_TAC THENL [ MP_TAC (ISPEC `S:real^3->bool` OAPVION1) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPEC `S:real^3->bool` AFF_DIM_LE_CARD) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN REWRITE_TAC[GSYM INT_OF_NUM_LT; DIMINDEX_3] THEN INT_ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN DISCH_TAC THEN EXISTS_TAC `a:real^3` THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[SPAN_INC]; ALL_TAC ] THEN STRIP_TAC THEN ABBREV_TAC `w:real^3 = projection n v` THEN ABBREV_TAC `W = (w:real^3) INSERT S` THEN SUBGOAL_THEN `(!u:real^3. u IN S ==> ~(u = vec 0)) /\ ~(w:real^3 = vec 0)` STRIP_ASSUME_TAC THENL [ CONJ_TAC THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPEC `S:real^3->bool` CIRCUMCENTER_NOT_EQ) THEN ASM_REWRITE_TAC[ARITH_RULE `1 < 3`] THEN DISCH_THEN (MP_TAC o SPEC `u':real^3`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN MP_TAC (ISPECL [`u:real^3`; `v:real^3`; `n:real^3`] PYTHAGORAS_PROJECTION) THEN ASM_SIMP_TAC[DOT_SYM] THEN SUBGOAL_THEN `&4 <= dist (u:real^3, v) pow 2` MP_TAC THENL [ REWRITE_TAC[REAL_ARITH `&4 = &2 pow 2`] THEN REWRITE_TAC[GSYM REAL_LE_SQUARE_ABS; dist; REAL_ABS_NORM; REAL_ARITH `abs(&2) = &2`] THEN REWRITE_TAC[GSYM dist] THEN UNDISCH_TAC `packing (V:real^3->bool)` THEN REWRITE_TAC[packing] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL [ ONCE_REWRITE_TAC[GSYM IN] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN CONJ_TAC THENL [ ONCE_REWRITE_TAC[GSYM IN] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `V DIFF S:real^3->bool` THEN ASM_REWRITE_TAC[SUBSET_DIFF]; ALL_TAC ] THEN DISCH_TAC THEN UNDISCH_TAC `v:real^3 IN V DIFF S` THEN ASM_REWRITE_TAC[IN_DIFF; DE_MORGAN_THM] THEN DISJ2_TAC THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN SUBGOAL_THEN `radV (S:real^3->bool) pow 2 + dist (vec 0, v:real^3) pow 2 < &2 + &2` MP_TAC THENL [ MATCH_MP_TAC REAL_LT_ADD2 THEN MP_TAC (SPEC `&2` SQRT_WORKS) THEN REWRITE_TAC[REAL_ARITH `&0 <= &2`] THEN DISCH_TAC THEN FIRST_ASSUM (fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN REWRITE_TAC[GSYM REAL_LT_SQUARE_ABS] THEN CONJ_TAC THENL [ SUBGOAL_THEN `abs (radV (S:real^3->bool)) = radV S` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[REAL_ABS_REFL] THEN REMOVE_THEN "r" (MP_TAC o SPEC `u:real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[dist; NORM_POS_LE]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN UNDISCH_TAC `radV (S:real^3->bool) < sqrt (&2)` THEN REAL_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[dist; REAL_ABS_NORM] THEN REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `radV (S:real^3->bool)` THEN ASM_REWRITE_TAC[DIST_SYM] THEN POP_ASSUM MP_TAC THEN UNDISCH_TAC `radV (S:real^3->bool) < sqrt (&2)` THEN REAL_ARITH_TAC; ALL_TAC ] THEN REAL_ARITH_TAC; ALL_TAC ] THEN REPEAT (FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (free_in `u:real^3` o concl))) THEN SUBGOAL_THEN `!u:real^3. u IN S ==> pi / &2 < angle (u, vec 0, w)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN EXPAND_TAC "w" THEN MATCH_MP_TAC OBTUSE_ANGLE_PROJECTION THEN CONJ_TAC THENL [ FIRST_X_ASSUM ((fun th -> ALL_TAC) o SPECL [`v:real^3`; `w:real^3`]) THEN ONCE_REWRITE_TAC[ANGLE_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[DOT_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `FINITE (W:real^3->bool) /\ CARD W = 4` ASSUME_TAC THENL [ UNDISCH_TAC `w:real^3 INSERT S = W` THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[FINITE_INSERT; AFFINE_INDEPENDENT_IMP_FINITE; CARD_CLAUSES] THEN SUBGOAL_THEN `~(w:real^3 IN S)` (fun th -> REWRITE_TAC[th]) THENL [ DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `w:real^3`) THEN ASM_SIMP_TAC[ANGLE_REFL_MID] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC; ALL_TAC ] THEN ARITH_TAC; ALL_TAC ] THEN MP_TAC (SPECL [`W:real^3->bool`; `n:real^3`; `pi / &2`] ANGLE_SUM_BOUND) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[ARITH_RULE `2 <= 4`] THEN CONJ_TAC THENL [ MP_TAC PI_POS THEN REAL_ARITH_TAC; ALL_TAC ] THEN EXPAND_TAC "W" THEN REWRITE_TAC[IN_INSERT] THEN SUBGOAL_THEN `n dot (w:real^3) = &0` ASSUME_TAC THENL [ EXPAND_TAC "w" THEN MP_TAC (ISPECL [`n:real^3`; `v:real^3`] PROJECTION_ORTHOGONAL) THEN SIMP_TAC[DOT_SYM]; ALL_TAC ] THEN REPEAT STRIP_TAC THENL [ POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[]; MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `angle (w':real^3, vec 0, w)` THEN ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[ANGLE_SYM] THEN ASM_SIMP_TAC[ANGLE_EQ_DIHV] THEN ASM_SIMP_TAC[IN_PLANE_NOT_COLLINEAR; DIHV_LE_AZIM]; MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `angle (v':real^3, vec 0, w)` THEN ASM_SIMP_TAC[ANGLE_EQ_DIHV] THEN ASM_SIMP_TAC[IN_PLANE_NOT_COLLINEAR; DIHV_LE_AZIM]; MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `angle (v':real^3, vec 0, w':real^3)` THEN ASM_SIMP_TAC[ANGLE_EQ_DIHV] THEN ASM_SIMP_TAC[IN_PLANE_NOT_COLLINEAR; DIHV_LE_AZIM] ]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
(* CARD S = 4 *)
let DIHV_GT_PI2 = 
prove(`!v w x y:real^N. pi / &2 < dihV v w x y <=> cos (dihV v w x y) < &0`,
REPEAT STRIP_TAC THEN REWRITE_TAC[dihV] THEN CONV_TAC (DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[ARCV_GT_PI2]);;
let XYOFCGX_4_0 = 
prove(`!V S. packing V /\ S SUBSET V /\ ~affine_dependent S /\ circumcenter S = vec 0 /\ radV S < sqrt (&2) /\ CARD S = 4 ==> (!u v. u IN S /\ v IN V DIFF S ==> dist (v, vec 0) > dist (u, vec 0))`,
REPEAT STRIP_TAC THEN ASM_CASES_TAC `dist (v,vec 0:real^3) > dist(u,vec 0:real^3)` THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN PURE_REWRITE_TAC[real_gt; REAL_NOT_LT; DIST_SYM] THEN DISCH_TAC THEN SUBGOAL_THEN `!u:real^3. u IN S ==> dist (u, vec 0) = radV S` (LABEL_TAC "r") THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[DIST_SYM] THEN DISCH_THEN (MATCH_MP_TAC o GSYM) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `dist (v:real^3, vec 0) <= radV (S:real^3->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `dist (u:real^3, vec 0)` THEN ASM_REWRITE_TAC[REAL_LE_LT] THEN DISJ2_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `~(S = {}:real^3->bool)` ASSUME_TAC THENL [ DISCH_TAC THEN UNDISCH_TAC `CARD (S:real^3->bool) = 4` THEN ASM_REWRITE_TAC[CARD_CLAUSES; ARITH_RULE `~(0 = 4)`]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `S:real^3->bool`; `vec 0:real^3`; `v:real^3`] XYOFCGX_lemma0) THEN ASM_REWRITE_TAC[DIST_SYM; ARITH_RULE `1 < 4`] THEN STRIP_TAC THEN REPEAT (FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (free_in `u:real^3` o concl))) THEN SUBGOAL_THEN `!u:real^3. u IN S ==> ~collinear {vec 0, v, u}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN PURE_REWRITE_TAC[CONJUNCT1 Collect_geom.PER_SET3] THEN REWRITE_TAC[COLLINEAR_LEMMA_ALT; DE_MORGAN_THM] THEN CONJ_TAC THENL [ MP_TAC (ISPEC `S:real^3->bool` CIRCUMCENTER_NOT_EQ) THEN ASM_REWRITE_TAC[ARITH_RULE `1 < 4`] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[NOT_EXISTS_THM] THEN GEN_TAC THEN DISCH_TAC THEN SUBGOAL_THEN `?w:real^3. w IN S /\ ~(u = w)` CHOOSE_TAC THENL [ SUBGOAL_THEN `~(S DELETE u:real^3 = {})` MP_TAC THENL [ DISCH_THEN (MP_TAC o AP_TERM `\s:real^3->bool. CARD s`) THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; FINITE_DELETE; CARD_DELETE; CARD_CLAUSES] THEN ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_DELETE] THEN STRIP_TAC THEN EXISTS_TAC `x:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`u:real^3`; `w:real^3`]) THEN FIRST_ASSUM (MP_TAC o SPEC `w:real^3`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `u:real^3`) THEN ASM_REWRITE_TAC[ARCV_ANGLE; ANGLE_GT_PI2; VECTOR_SUB_RZERO; DOT_LMUL] THEN DISCH_TAC THEN SUBGOAL_THEN `c < &0` MP_TAC THENL [ POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LT] THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[DOT_POS_LE]; ALL_TAC ] THEN DISCH_TAC THEN ASM_CASES_TAC `u dot w:real^3 < &0` THEN ASM_REWRITE_TAC[] THEN REWRITE_TAC[REAL_NOT_LT] THEN ONCE_REWRITE_TAC[REAL_ARITH `a * b = (--a) * (--b)`] THEN MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[REAL_NEG_GE0; REAL_LE_LT]; ALL_TAC ] THEN MP_TAC (SPECL [`S:real^3->bool`; `v:real^3`; `pi / &2`] ANGLE_SUM_BOUND) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; ARITH_RULE `2 <= 4`] THEN CONJ_TAC THENL [ MP_TAC PI_POS THEN REAL_ARITH_TAC; ALL_TAC ] THEN X_GEN_TAC `u:real^3` THEN X_GEN_TAC `w:real^3` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `dihV (vec 0:real^3) v u w` THEN CONJ_TAC THENL [ REWRITE_TAC[DIHV_GT_PI2] THEN MP_TAC (ISPECL [`vec 0:real^3`; `u:real^3`; `w:real^3`; `v:real^3`] Trigonometry.RLXWSTK) THEN ASM_SIMP_TAC[] THEN CONV_TAC (DEPTH_CONV let_CONV) THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[REAL_ARITH `(a - b) / c < &0 <=> &0 < (b + --a) / c`] THEN MATCH_MP_TAC REAL_LT_DIV THEN CONJ_TAC THENL [ MATCH_MP_TAC REAL_LT_ADD THEN CONJ_TAC THENL [ ONCE_REWRITE_TAC[REAL_ARITH `a * b = (--a) * (--b)`] THEN MATCH_MP_TAC REAL_LT_MUL THEN REWRITE_TAC[REAL_NEG_GT0; GSYM ARCV_GT_PI2] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[REAL_NEG_GT0; GSYM ARCV_GT_PI2] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC REAL_LT_MUL THEN REWRITE_TAC[ARCV_ANGLE; REAL_LT_LE; SIN_ANGLE_POS] THEN CONJ_TAC THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `w:real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`v:real^3`; `vec 0:real^3`; `w:real^3`] COLLINEAR_SIN_ANGLE) THEN ANTS_TAC THENL [ POP_ASSUM MP_TAC THEN SIMP_TAC[COLLINEAR_LEMMA; DE_MORGAN_THM]; ALL_TAC ] THEN DISCH_TAC THEN DISCH_THEN (MP_TAC o SYM) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[Collect_geom.PER_SET3]; FIRST_X_ASSUM (MP_TAC o SPEC `u:real^3`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`v:real^3`; `vec 0:real^3`; `u:real^3`] COLLINEAR_SIN_ANGLE) THEN ANTS_TAC THENL [ POP_ASSUM MP_TAC THEN SIMP_TAC[COLLINEAR_LEMMA; DE_MORGAN_THM]; ALL_TAC ] THEN DISCH_TAC THEN DISCH_THEN (MP_TAC o SYM) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[Collect_geom.PER_SET3] ]; ALL_TAC ] THEN MATCH_MP_TAC DIHV_LE_AZIM THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
(***********) (* XYOFCGX *) (***********)
let XYOFCGX = 
prove(`!V S (p:real^3). packing V /\ S SUBSET V /\ ~affine_dependent S /\ (p = circumcenter S) /\ (radV S < sqrt(&2)) ==> (!u v. u IN S /\ v IN (V DIFF S) ==> dist(v,p) > dist(u,p))`,
REPEAT GEN_TAC THEN STRIP_TAC THEN ASM_CASES_TAC `S = {}:real^3->bool` THENL [ ASM_REWRITE_TAC[NOT_IN_EMPTY]; ALL_TAC ] THEN ABBREV_TAC `W = IMAGE (\x:real^3. --p + x) V` THEN ABBREV_TAC `K = IMAGE (\x:real^3. --p + x) S` THEN SUBGOAL_THEN `(!u v:real^3. u IN K /\ v IN W DIFF K ==> dist (v,vec 0) > dist(u,vec 0)) ==> (!u v:real^3. u IN S /\ v IN V DIFF S ==> dist (v,p) > dist(u,p))` MP_TAC THENL [ POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPECL [`--p + u:real^3`; `--p + v:real^3`]) THEN REWRITE_TAC[dist; VECTOR_SUB_RZERO; VECTOR_ARITH `--a + b = b - a:real^3`] THEN DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_IMAGE; IN_DIFF] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[IN_DIFF] THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL [ EXISTS_TAC `u:real^3` THEN ASM_REWRITE_TAC[]; EXISTS_TAC `v:real^3` THEN ASM_REWRITE_TAC[]; REWRITE_TAC[VECTOR_ARITH `v - p = x - p <=> x = v:real^3`; NOT_EXISTS_THM; DE_MORGAN_THM] THEN GEN_TAC THEN ASM_CASES_TAC `x = v:real^3` THEN ASM_REWRITE_TAC[] ]; ALL_TAC ] THEN DISCH_THEN MATCH_MP_TAC THEN SUBGOAL_THEN `packing W /\ K SUBSET W /\ ~affine_dependent K /\ circumcenter K = vec 0:real^3 /\ radV K < sqrt (&2)` STRIP_ASSUME_TAC THENL [ REPEAT CONJ_TAC THENL [ UNDISCH_TAC `packing (V:real^3->bool)` THEN EXPAND_TAC "W" THEN REWRITE_TAC[packing] THEN REWRITE_TAC[IMAGE; IN_ELIM_THM; IN] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPECL [`x:real^3`; `x':real^3`]) THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[VECTOR_ARITH `--p + x = --p + x' <=> x = x':real^3`] THEN SIMP_TAC[dist; VECTOR_ARITH `(--p + x) - (--p + x') = x - x':real^3`]; EXPAND_TAC "K" THEN EXPAND_TAC "W" THEN ASM_SIMP_TAC[IMAGE_SUBSET]; EXPAND_TAC "K" THEN ASM_REWRITE_TAC[AFFINE_DEPENDENT_TRANSLATION_EQ]; EXPAND_TAC "K" THEN MP_TAC (ISPECL [`S:real^3->bool`; `--p:real^3`] CIRCUMCENTER_TRANSLATION) THEN ASM_REWRITE_TAC[VECTOR_ARITH `--p + p = vec 0:real^3`]; MP_TAC (ISPECL [`S:real^3->bool`; `--p:real^3`] RADV_TRANSLATION) THEN ASM_SIMP_TAC[] ]; ALL_TAC ] THEN REPLICATE_TAC 5 (POP_ASSUM MP_TAC) THEN REPEAT REMOVE_ASSUM THEN REPEAT DISCH_TAC THEN MP_TAC (ISPEC `K:real^3->bool` AFFINE_INDEPENDENT_CARD_LE) THEN ASM_REWRITE_TAC[DIMINDEX_3; ARITH_RULE `a <= 3 + 1 <=> a < 5`; Hypermap_and_fan.gen_NUM_CASES 5] THEN DISCH_THEN STRIP_ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE; CARD_EQ_0; NOT_IN_EMPTY]; MATCH_MP_TAC XYOFCGX_1 THEN ASM_REWRITE_TAC[LE_REFL]; MATCH_MP_TAC XYOFCGX_2 THEN ASM_REWRITE_TAC[]; MATCH_MP_TAC XYOFCGX_3_0 THEN ASM_REWRITE_TAC[]; MATCH_MP_TAC XYOFCGX_4_0 THEN ASM_REWRITE_TAC[] ]);;
(****************************************************) (*******************************************) (* XNHPWAB begins here *) (*******************************************) (* XNHPWAB1 *)
let BARV_AFFINE_INDEPENDENT = 
prove(`!V ul k. packing V /\ barV V k ul ==> ~affine_dependent (set_of_list ul)`,
REPEAT GEN_TAC THEN DISCH_THEN STRIP_ASSUME_TAC THEN REWRITE_TAC[AFFINE_INDEPENDENT_IFF_CARD] THEN ASM_REWRITE_TAC[FINITE_SET_OF_LIST] THEN MP_TAC (SPEC_ALL MHFTTZN1) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_IMP_K_LE_3 THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `ul:(real^3)list`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` AFF_DIM_LE_CARD) THEN ASM_REWRITE_TAC[FINITE_SET_OF_LIST] THEN SUBGOAL_THEN `(CARD (set_of_list ul:real^3->bool)) <= k + 1` MP_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV] THEN DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN REWRITE_TAC[CARD_SET_OF_LIST_LE]; ALL_TAC ] THEN REWRITE_TAC[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC);;
(* barV v k ul ==> LENGTH ul = CARD (set_of_list ul) *)
let BARV_IMP_LENGTH_EQ_CARD = 
prove(`!V ul k. packing V /\ barV V k ul ==> LENGTH ul = k + 1 /\ CARD (set_of_list ul) = k + 1`,
REPEAT GEN_TAC THEN STRIP_TAC THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN SIMP_TAC[BARV]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPEC_ALL BARV_AFFINE_INDEPENDENT) THEN ASM_REWRITE_TAC[AFFINE_INDEPENDENT_IFF_CARD; FINITE_SET_OF_LIST] THEN MP_TAC (SPEC_ALL MHFTTZN1) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[GSYM INT_OF_NUM_EQ; GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC);;
let AFFINE_HULL_PROJECTION_EXISTS = 
prove(`!S p:real^N. ~(S = {}) ==> ?x n. p = x + n /\ x IN affine hull S /\ (!v w. v IN S /\ w IN S ==> (v - w) dot n = &0)`,
REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT STRIP_TAC THEN ABBREV_TAC `V = IMAGE (\v:real^N. --x + v) S` THEN ABBREV_TAC `p0:real^N = --x + p` THEN SUBGOAL_THEN `?y n:real^N. p0 = y + n /\ y IN affine hull V /\ (!z. z IN V ==> z dot n = &0)` MP_TAC THENL [ MP_TAC (ISPECL [`V:real^N->bool`; `p0:real^N`] ORTHOGONAL_SUBSPACE_DECOMP_EXISTS) THEN REWRITE_TAC[orthogonal] THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`y:real^N`; `z:real^N`] THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ MP_TAC (ISPEC `V:real^N->bool` AFFINE_HULL_EQ_SPAN) THEN ANTS_TAC THENL [ EXPAND_TAC "V" THEN REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN EXISTS_TAC `x:real^N` THEN REWRITE_TAC[VECTOR_ARITH `vec 0 = --x + x:real^N`] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^N->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `z':real^N`) THEN ANTS_TAC THENL [ MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `V:real^N->bool` THEN ASM_REWRITE_TAC[SPAN_INC]; ALL_TAC ] THEN SIMP_TAC[DOT_SYM]; ALL_TAC ] THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`x + y:real^N`; `n:real^N`] THEN CONJ_TAC THENL [ UNDISCH_TAC `--x + p = p0:real^N` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN CONJ_TAC THENL [ UNDISCH_TAC `y:real^N IN affine hull V` THEN EXPAND_TAC "V" THEN REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_ARITH `x + --x + x' = x':real^N`]; ALL_TAC ] THEN SUBGOAL_THEN `!v:real^N. v IN S ==> (--x + v) dot n = &0` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "V" THEN REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `v:real^N` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[VECTOR_ARITH `v - w = (--x + v) - (--x + w):real^N`] THEN ONCE_REWRITE_TAC[DOT_LSUB] THEN ASM_SIMP_TAC[REAL_SUB_RZERO]);;
let AFFINE_HULL_PROJECTION_DIST_EQ = 
prove(`!S p v w x n:real^N. v IN S /\ w IN S /\ dist (p, v) = dist (p, w) /\ p = x + n /\ (!v w. v IN S /\ w IN S ==> (v - w) dot n = &0) ==> dist (x, v) = dist (x, w)`,
REPEAT STRIP_TAC THEN UNDISCH_TAC `p = x + n:real^N` THEN REWRITE_TAC[VECTOR_ARITH `p = x + n <=> x = p - n:real^N`] THEN DISCH_TAC THEN UNDISCH_TAC `dist (p,v) = dist(p,w:real^N)` THEN ASM_REWRITE_TAC[DIST_EQ; dist; NORM_POW_2] THEN ONCE_REWRITE_TAC[VECTOR_ARITH `p - n - v = (p - v) - n:real^N`] THEN ABBREV_TAC `a = p - v:real^N` THEN ABBREV_TAC `b = p - w:real^N` THEN DISCH_TAC THEN ASM_REWRITE_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REWRITE_TAC[REAL_ARITH `bb - an - (an - nn) = bb - bn - (bn - nn) <=> an - bn = &0`] THEN ONCE_REWRITE_TAC[GSYM DOT_LSUB] THEN EXPAND_TAC "a" THEN EXPAND_TAC "b" THEN REWRITE_TAC[VECTOR_ARITH `p - v - (p - w) = w - v:real^N`] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
let ORTHOGONAL_TO_AFFINE_HULL_EQ = 
prove(`!S n:real^N. (!v w. v IN S /\ w IN S ==> (v - w) dot n = &0) <=> (!v w. v IN affine hull S /\ w IN affine hull S ==> (v - w) dot n = &0)`,
REPEAT GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ ASM_CASES_TAC `S = {}:real^N->bool` THENL [ UNDISCH_TAC `w:real^N IN affine hull S` THEN ASM_REWRITE_TAC[AFFINE_HULL_EMPTY; NOT_IN_EMPTY]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN MP_TAC (ISPEC `(IMAGE (\v:real^N. --x + v) S)` ORTHOGONAL_TO_SPAN_EQ) THEN DISCH_THEN (MP_TAC o SPEC `n:real^N`) THEN REWRITE_TAC[orthogonal] THEN SUBGOAL_THEN `span (IMAGE (\v:real^N. --x + v) S) = affine hull (IMAGE (\v:real^N. --x + v) S)` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC (GSYM AFFINE_HULL_EQ_SPAN) THEN REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN EXISTS_TAC `x:real^N` THEN REWRITE_TAC[VECTOR_ARITH `vec 0 = --x + x:real^N`] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^N->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN ONCE_REWRITE_TAC[TAUT `(A <=> B) <=> ((B ==> A) /\ (A ==> B))`] THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC (fun th -> ALL_TAC)) THEN REWRITE_TAC[AFFINE_HULL_TRANSLATION; IN_IMAGE] THEN ANTS_TAC THENL [ REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[DOT_SYM] THEN ASM_REWRITE_TAC[VECTOR_ARITH `--x + x' = x' - x:real^N`] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN SUBGOAL_THEN `!v:real^N. v IN affine hull S ==> (v - x) dot n = &0` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[DOT_SYM] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `v':real^N` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN ONCE_REWRITE_TAC[VECTOR_ARITH `v - w = (v - x) - (w - x):real^N`] THEN ONCE_REWRITE_TAC[DOT_LSUB] THEN ASM_SIMP_TAC[REAL_SUB_RZERO]; ALL_TAC ] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^N->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]);;
let AFFINE_HULL_PROJECTION_DIST_LE = 
prove(`!S p v x n:real^N. v IN S /\ p = x + n /\ x IN affine hull S /\ (!v w. v IN S /\ w IN S ==> (v - w) dot n = &0) ==> dist (x, v) <= dist (p, v)`,
REPEAT STRIP_TAC THEN REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[GSYM REAL_ABS_NORM] THEN ASM_REWRITE_TAC[REAL_LE_SQUARE_ABS; NORM_POW_2; VECTOR_ARITH `(x + n) - v = (x - v) + n:real^N`] THEN ABBREV_TAC `a = x - v:real^N` THEN REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_SYM] THEN SUBGOAL_THEN `a dot n = &0 /\ &0 <= n dot n:real^N` MP_TAC THENL [ REWRITE_TAC[DOT_POS_LE] THEN EXPAND_TAC "a" THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_TO_AFFINE_HULL_EQ] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^N->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN REAL_ARITH_TAC);;
let AFFINE_HULL_PROJECTION_DIST_LT = 
prove(`!S p v x n:real^N. v IN S /\ ~(p IN affine hull S) /\ p = x + n /\ x IN affine hull S /\ (!v w. v IN S /\ w IN S ==> (v - w) dot n = &0) ==> dist (x, v) < dist (p, v)`,
REPEAT STRIP_TAC THEN REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[GSYM REAL_ABS_NORM] THEN ASM_REWRITE_TAC[REAL_LT_SQUARE_ABS; NORM_POW_2; VECTOR_ARITH `(x + n) - v = (x - v) + n:real^N`] THEN ABBREV_TAC `a = x - v:real^N` THEN REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_SYM] THEN SUBGOAL_THEN `a dot n = &0 /\ &0 < n dot n:real^N` MP_TAC THENL [ REWRITE_TAC[DOT_POS_LT] THEN CONJ_TAC THENL [ EXPAND_TAC "a" THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_TO_AFFINE_HULL_EQ] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^N->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]; DISCH_TAC THEN UNDISCH_TAC `p = x + n:real^N` THEN ASM_REWRITE_TAC[VECTOR_ADD_RID] THEN DISCH_TAC THEN UNDISCH_TAC `~(p:real^N IN affine hull S)` THEN ASM_REWRITE_TAC[] ]; ALL_TAC ] THEN REAL_ARITH_TAC);;
let AFFINE_HULL_CIRCUMCENTER_PROJECTION = 
prove(`!s t:real^N->bool. ~affine_dependent s /\ t SUBSET s /\ ~(t = {}) ==> ?n. circumcenter s = circumcenter t + n /\ (!v w. v IN t /\ w IN t ==> (v - w) dot n = &0)`,
REPEAT STRIP_TAC THEN ABBREV_TAC `p0:real^N = circumcenter t` THEN ABBREV_TAC `p:real^N = circumcenter s` THEN MP_TAC (SPECL [`t:real^N->bool`; `p:real^N`] AFFINE_HULL_PROJECTION_EXISTS) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `n:real^N` THEN ASM_REWRITE_TAC[VECTOR_ARITH `x + n = p0 + n <=> x = p0:real^N`] THEN EXPAND_TAC "p0" THEN MP_TAC (SPEC `t:real^N->bool` OAPVION3) THEN ANTS_TAC THENL [ MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `~(t = {}:real^N->bool)` THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN EXISTS_TAC `dist (x, x':real^N)` THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_HULL_PROJECTION_DIST_EQ THEN MAP_EVERY EXISTS_TAC [`t:real^N->bool`; `p:real^N`; `n:real^N`] THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPEC `s:real^N->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `x':real^N`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `w:real^N`) THEN UNDISCH_TAC `t SUBSET s:real^N->bool` THEN REWRITE_TAC[SUBSET] THEN DISCH_TAC THEN ASM_SIMP_TAC[]);;
let AFFINE_HULL_CIRCUMCENTER_EQ = 
prove(`!s t:real^N->bool. ~affine_dependent s /\ t SUBSET s /\ ~(t = {}) /\ circumcenter s IN affine hull t ==> circumcenter s = circumcenter t`,
REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN MP_TAC (SPEC `t:real^N->bool` OAPVION3) THEN ANTS_TAC THENL [ MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET]; ALL_TAC ] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `radV (s:real^N->bool)` THEN REPEAT STRIP_TAC THEN MP_TAC (SPEC `s:real^N->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `w:real^N`) THEN ASM_SIMP_TAC[]);;
let AFFINE_HULL_RADV = 
prove(`!s t:real^N->bool. ~affine_dependent s /\ t SUBSET s /\ ~(t = {}) ==> radV s pow 2 = radV t pow 2 + dist (circumcenter t, circumcenter s) pow 2 /\ &0 <= radV s /\ &0 <= radV t`,
REWRITE_TAC[SUBSET] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_ASSUM MP_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN SUBGOAL_THEN `~affine_dependent (t:real^N->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET]; ALL_TAC ] THEN MP_TAC (SPEC_ALL AFFINE_HULL_CIRCUMCENTER_PROJECTION) THEN ASM_REWRITE_TAC[SUBSET] THEN STRIP_TAC THEN POP_ASSUM (LABEL_TAC "vw") THEN MP_TAC (SPEC `s:real^N->bool` OAPVION2) THEN MP_TAC (SPEC `t:real^N->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISCH_THEN (MP_TAC o SPEC `x:real^N`) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN REWRITE_TAC[DIST_POS_LE] THEN REWRITE_TAC[dist; NORM_POW_2; VECTOR_ARITH `a - (a + n) = --n:real^N`; VECTOR_ARITH `(a + n) - x = (a - x) + n:real^N`] THEN REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LNEG; DOT_RNEG; DOT_SYM; REAL_NEG_NEG] THEN REWRITE_TAC[REAL_ARITH `(a + b) + b + c = a + c <=> b = &0`] THEN ONCE_REWRITE_TAC[DOT_SYM] THEN REMOVE_THEN "vw" MP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_TO_AFFINE_HULL_EQ] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL [ MP_TAC (SPEC `t:real^N->bool` OAPVION1) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]);;
let RADV_MONO = 
prove(`!s t:real^N->bool. ~affine_dependent s /\ t SUBSET s /\ ~(t = {}) ==> radV t <= radV s`,
REPEAT GEN_TAC THEN DISCH_THEN (MP_TAC o MATCH_MP AFFINE_HULL_RADV) THEN STRIP_TAC THEN SUBGOAL_THEN `radV (t:real^N->bool) = abs(radV t) /\ radV (s:real^N->bool) = abs(radV s)` (fun th -> ONCE_REWRITE_TAC[th]) THENL [ ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN ASM_REWRITE_TAC[REAL_ABS_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[REAL_LE_SQUARE_ABS] THEN REWRITE_TAC[REAL_ARITH `a <= a + b <=> &0 <= b`] THEN REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE]);;
let HL_PROPERTIES = 
prove(`!V ul k. packing V /\ barV V k ul ==> (!w. w IN set_of_list ul ==> dist (circumcenter (set_of_list ul), w) = hl ul)`,
REPEAT GEN_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN REWRITE_TAC[HL] THEN MATCH_MP_TAC OAPVION2 THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]);;
let BARV_CIRCUMCENTER_EXISTS = 
prove(`!V ul k. packing V /\ barV V k ul ==> circumcenter (set_of_list ul) IN affine hull (set_of_list ul)`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC OAPVION1 THEN CONJ_TAC THENL [ REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `HD ul:real^3` THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]);;
let HL_EQ_DIST0 = 
prove(`!V k ul. packing V /\ barV V k ul ==> hl ul = dist (circumcenter (set_of_list ul), HD ul)`,
REPEAT STRIP_TAC THEN MP_TAC (SPEC_ALL HL_PROPERTIES) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MATCH_MP_TAC o GSYM) THEN MATCH_MP_TAC BARV_IMP_HD_IN_SET_OF_LIST THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]);;
let BARV_CIRCUMCENTER_PROJECTION = 
prove(`!V ul k i. packing V /\ ul IN barV V k /\ i <= k ==> let S = set_of_list (truncate_simplex i ul) in (?n. circumcenter (set_of_list ul) = circumcenter S + n /\ (!v w. v IN S /\ w IN S ==> (v - w) dot n = &0))`,
REPEAT STRIP_TAC THEN UNDISCH_TAC `ul IN barV V k` THEN GEN_REWRITE_TAC LAND_CONV [IN] THEN DISCH_TAC THEN CONV_TAC let_CONV THEN ABBREV_TAC `S:real^3->bool = set_of_list (truncate_simplex i ul)` THEN MATCH_MP_TAC AFFINE_HULL_CIRCUMCENTER_PROJECTION THEN CONJ_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN CONJ_TAC THENL [ EXPAND_TAC "S" THEN MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`]; ALL_TAC ] THEN EXPAND_TAC "S" THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `HD (truncate_simplex i ul):real^3` THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN MP_TAC (ISPECL [`i:num`; `ul:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`; ARITH_RULE `1 <= i + 1`]);;
let HL_DECREASE = 
prove(`!V ul k i. packing V /\ ul IN barV V k /\ i <= k ==> hl (truncate_simplex i ul) <= hl ul`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN MP_TAC (SPEC_ALL HL_PROPERTIES) THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPEC_ALL HL_EQ_DIST0) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `i:num`; `truncate_simplex i (ul:(real^3)list)`] HL_EQ_DIST0) THEN SUBGOAL_THEN `barV V i (truncate_simplex i ul)` ASSUME_TAC THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ABBREV_TAC `S:real^3->bool = set_of_list (truncate_simplex i ul)` THEN ABBREV_TAC `p0:real^3 = circumcenter S` THEN ABBREV_TAC `p:real^3 = circumcenter (set_of_list ul)` THEN SUBGOAL_THEN `HD (truncate_simplex i ul):real^3 = HD ul` ASSUME_TAC THENL [ MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `k + 1` THEN ASM_REWRITE_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`] THEN UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV; LE_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC AFFINE_HULL_PROJECTION_DIST_LE THEN EXISTS_TAC `S:real^3->bool` THEN MP_TAC (SPEC_ALL BARV_CIRCUMCENTER_PROJECTION) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN CONV_TAC (DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `n:real^3` THEN MP_TAC (SPECL [`V:real^3->bool`; `i:num`; `truncate_simplex i ul:(real^3)list`] BARV_IMP_HD_IN_SET_OF_LIST) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "p0" THEN EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_CIRCUMCENTER_EXISTS THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `i:num`] THEN ASM_REWRITE_TAC[]);;
let XNHPWAB1 = 
prove(`!V ul k. packing V /\ (ul IN barV V k) /\ (hl ul < sqrt(&2)) ==> (omega_list V ul = circumcenter (set_of_list ul))`,
REWRITE_TAC[IN] THEN REPEAT GEN_TAC THEN SPEC_TAC (`ul:(real^3)list`, `ul:(real^3)list`) THEN SPEC_TAC (`k:num`, `k:num`) THEN INDUCT_TAC THENL [ GEN_TAC THEN REWRITE_TAC[BARV; ARITH] THEN REPEAT STRIP_TAC THEN MP_TAC (ISPEC `ul:(real^3)list` LENGTH_1_LEMMA) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN REWRITE_TAC[set_of_list; CIRCUMCENTER_1; OMEGA_LIST; LENGTH; ARITH; OMEGA_LIST_N; HD]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `SUC k <= 3` ASSUME_TAC THENL [ MATCH_MP_TAC BARV_IMP_K_LE_3 THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `ul:(real^3)list`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `vl:(real^3)list = truncate_simplex k ul` THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k <= 3`] THEN SUBGOAL_THEN `barV V k vl` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 2 /\ LENGTH (vl:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V (SUC k) ul` THEN UNDISCH_TAC `barV V k vl` THEN SIMP_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `SUC k`] THEN ASM_REWRITE_TAC[IN] THEN ARITH_TAC; ALL_TAC ] THEN ABBREV_TAC `p0 = circumcenter (set_of_list vl):real^3` THEN POP_ASSUM (LABEL_TAC "p0") THEN DISCH_THEN (LABEL_TAC "po") THEN SUBGOAL_THEN `p0:real^3 IN affine hull (set_of_list ul)` ASSUME_TAC THENL [ MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `affine hull (set_of_list vl):real^3->bool` THEN CONJ_TAC THENL [ REMOVE_THEN "p0" (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC BARV_CIRCUMCENTER_EXISTS THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC HULL_MONO THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN ABBREV_TAC `A:real^3->bool = affine hull (voronoi_list V ul)` THEN ABBREV_TAC `p:real^3 = closest_point A p0` THEN MP_TAC (ISPECL [`A:real^3->bool`; `p0:real^3`] CLOSEST_POINT_EXISTS) THEN ANTS_TAC THENL [ EXPAND_TAC "A" THEN REWRITE_TAC[CLOSED_AFFINE_HULL] THEN REWRITE_TAC[AFFINE_HULL_EQ_EMPTY] THEN DISCH_TAC THEN UNDISCH_TAC `barV V (SUC k) ul` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 2`; DE_MORGAN_THM] THEN DISJ2_TAC THEN DISJ2_TAC THEN REWRITE_TAC[AFF_DIM_EMPTY] THEN UNDISCH_TAC `SUC k <= 3` THEN REWRITE_TAC[ADD1; GSYM INT_OF_NUM_ADD; GSYM INT_OF_NUM_LE] THEN INT_ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN SUBGOAL_THEN `p:real^3 IN affine hull set_of_list ul` ASSUME_TAC THENL [ ASM_CASES_TAC `p:real^3 IN affine hull set_of_list ul` THEN ASM_REWRITE_TAC[] THEN MP_TAC (ISPECL [`set_of_list ul:real^3->bool`; `p:real^3`] AFFINE_HULL_PROJECTION_EXISTS) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[SET_OF_LIST_EQ_EMPTY; GSYM LENGTH_EQ_NIL] THEN ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THEN SUBGOAL_THEN `dist (x, p0) < dist (p, p0:real^3)` ASSUME_TAC THENL [ MATCH_MP_TAC AFFINE_HULL_PROJECTION_DIST_LT THEN MAP_EVERY EXISTS_TAC [`affine hull (set_of_list ul:real^3->bool)`; `n:real^3`] THEN ASM_REWRITE_TAC[HULL_HULL; GSYM ORTHOGONAL_TO_AFFINE_HULL_EQ] THEN UNDISCH_TAC `p = x + n:real^3` THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN SUBGOAL_THEN `x:real^3 IN A` ASSUME_TAC THENL [ UNDISCH_TAC `p:real^3 IN A` THEN EXPAND_TAC "A" THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] MHFTTZN2) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[];ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[bis; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_HULL_PROJECTION_DIST_EQ THEN MAP_EVERY EXISTS_TAC [`set_of_list ul:real^3->bool`; `p:real^3`; `n:real^3`] THEN ASM_SIMP_TAC[] THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= k + 2`]; ALL_TAC ] THEN UNDISCH_TAC `dist (x, p0) < dist (p,p0:real^3)` THEN POP_ASSUM MP_TAC THEN REMOVE_ASSUM THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `x:real^3`) THEN ASM_REWRITE_TAC[DIST_SYM; REAL_NOT_LT]; ALL_TAC ] THEN SUBGOAL_THEN `p = circumcenter (set_of_list ul):real^3` (LABEL_TAC "c") THENL [ MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] MHFTTZN3) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN `p:real^3 IN A INTER affine hull set_of_list ul` MP_TAC THENL [ ASM_REWRITE_TAC[IN_INTER]; ALL_TAC ] THEN ASM_REWRITE_TAC[IN_SING]; ALL_TAC ] THEN SUBGOAL_THEN `p:real^3 IN voronoi_list V ul` ASSUME_TAC THENL [ REWRITE_TAC[VORONOI_LIST; VORONOI_SET; IN_INTERS; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[voronoi_closed; IN_ELIM_THM] THEN SUBGOAL_THEN `!w:real^3. V (w:real^3) <=> w IN V` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[IN]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN ASM_CASES_TAC `w:real^3 IN set_of_list ul` THENL [ MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] HL_PROPERTIES) THEN ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[REAL_LE_REFL]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `set_of_list ul:real^3->bool`; `p:real^3`] XYOFCGX) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[GSYM HL] THEN CONJ_TAC THENL [ MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN EXISTS_TAC `V:real^3->bool` THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPECL [`v:real^3`; `w:real^3`]) THEN ASM_REWRITE_TAC[IN_DIFF; DIST_SYM; real_gt; REAL_LT_LE] THEN SIMP_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[OMEGA_LIST; OMEGA_LIST_N; ARITH_RULE `(k + 2) - 1 = SUC k`] THEN SUBGOAL_THEN `omega_list_n V ul k = p0:real^3` (fun th -> REWRITE_TAC[th]) THENL [ EXPAND_TAC "p0" THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC (GSYM OMEGA_LIST_LEMMA) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `truncate_simplex (SUC k) ul = ul:(real^3)list` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL [`SUC k`; `ul:(real^3)list`; `ul:(real^3)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[ARITH_RULE `SUC k + 1 = k + 2`; LE_REFL; INITIAL_SUBLIST_REFL]; ALL_TAC ] THEN REMOVE_THEN "c" (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC (GSYM CLOSEST_POINT_UNIQUE) THEN ASM_REWRITE_TAC[CONVEX_VORONOI_LIST; CLOSED_VORONOI_LIST] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN EXPAND_TAC "A" THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `voronoi_list V ul:real^3->bool` THEN ASM_REWRITE_TAC[HULL_SUBSET]);;
(* XNHPWAB2 *)
let AFFINE_HULL_PROJECTION_SEPARATES = 
prove(`!S p:real^N. FINITE S /\ p IN affine hull S /\ ~(p IN convex hull S) ==> ?u. u IN S /\ (!x n. p = x + n /\ x IN affine hull (S DELETE u) /\ (!v w. v IN S DELETE u /\ w IN S DELETE u ==> (v - w) dot n = &0) ==> (p - x) dot (u - x) <= &0)`,
REPEAT STRIP_TAC THEN POP_ASSUM (MP_TAC o REWRITE_RULE [CONVEX_HULL_FINITE]) THEN POP_ASSUM (MP_TAC o REWRITE_RULE [AFFINE_HULL_FINITE]) THEN REWRITE_TAC[IN_ELIM_THM; NOT_EXISTS_THM; DE_MORGAN_THM] THEN DISCH_THEN (X_CHOOSE_THEN `f:real^N->real` STRIP_ASSUME_TAC) THEN DISCH_THEN (MP_TAC o SPEC `f:real^N->real`) THEN ASM_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN DISCH_THEN (X_CHOOSE_THEN `u:real^N` ASSUME_TAC) THEN EXISTS_TAC `u:real^N` THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_TO_AFFINE_HULL_EQ] THEN DISCH_TAC THEN SUBGOAL_THEN `p - x:real^N = vsum S (\v. f v % (v - x))` (LABEL_TAC "px") THENL [ REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN ASM_SIMP_TAC[VSUM_SUB; VSUM_RMUL; VECTOR_MUL_LID]; ALL_TAC ] THEN POP_ASSUM (MP_TAC o AP_TERM `\v:real^N. v dot (p - x)`) THEN ASM_REWRITE_TAC[VECTOR_ARITH `(x + n) - x = n:real^N`] THEN ASM_SIMP_TAC[DOT_LSUM] THEN SUBGOAL_THEN `sum S (\v:real^N. f v % (v - x) dot n) = f u * (u - x) dot n` (fun th -> REWRITE_TAC[th]) THENL [ SUBGOAL_THEN `S:real^N->bool = (S DELETE u) UNION {u}` (fun th -> ONCE_REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_UNION; IN_SING; IN_DELETE] THEN GEN_TAC THEN EQ_TAC THEN SIMP_TAC[DISJ_SYM; EXCLUDED_MIDDLE] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPECL [`\v:real^N. f v % (v - x) dot n`; `u:real^N`] SUM_SING) THEN REWRITE_TAC[DOT_LMUL] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC SUM_UNION_LZERO THEN REWRITE_TAC[FINITE_SING] THEN REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S DELETE (u:real^N)` THEN ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o AP_TERM `\x. inv (f (u:real^N)) * x`) THEN REWRITE_TAC[REAL_MUL_ASSOC; DOT_SYM] THEN ASM_SIMP_TAC[REAL_ARITH `a < &0 ==> ~(a = &0)`; REAL_MUL_LINV; REAL_MUL_LID] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[REAL_ARITH `a * b <= &0 <=> &0 <= (--a) * b`] THEN MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[DOT_POS_LE; GSYM REAL_INV_NEG] THEN MATCH_MP_TAC REAL_LE_INV THEN ASM_REWRITE_TAC[REAL_NEG_GE0; REAL_LE_LT]);;
let XNHPWAB2 = 
prove(`!V ul k. packing V /\ (ul IN barV V k) /\ (hl ul < sqrt(&2)) ==> (omega_list V ul IN convex hull (set_of_list ul))`,
REPEAT STRIP_TAC THEN UNDISCH_TAC `ul IN barV V k` THEN DISCH_THEN (ASSUME_TAC o REWRITE_RULE[IN]) THEN ABBREV_TAC `p:real^3 = omega_list V ul` THEN ABBREV_TAC `S:real^3->bool = set_of_list ul` THEN ASM_CASES_TAC `p:real^3 IN convex hull S` THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `circumcenter S = p:real^3` (LABEL_TAC "c") THENL [ EXPAND_TAC "S" THEN EXPAND_TAC "p" THEN MATCH_MP_TAC (GSYM XNHPWAB1) THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN SUBGOAL_THEN `~affine_dependent (S:real^3->bool)` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPECL [`S:real^3->bool`; `p:real^3`] AFFINE_HULL_PROJECTION_SEPARATES) THEN ANTS_TAC THENL [ ASM_SIMP_TAC[AFFINE_INDEPENDENT_IMP_FINITE] THEN EXPAND_TAC "p" THEN EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_CIRCUMCENTER_EXISTS THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN ASM_CASES_TAC `S DELETE u:real^3 = {}` THENL [ SUBGOAL_THEN `S = {u:real^3}` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN REWRITE_TAC[EXTENSION; IN_DELETE; NOT_IN_EMPTY; IN_SING; DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `x:real^3`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REMOVE_THEN "c" MP_TAC THEN ASM_REWRITE_TAC[CIRCUMCENTER_1] THEN DISCH_TAC THEN UNDISCH_TAC `~(p:real^3 IN convex hull S)` THEN ASM_REWRITE_TAC[CONVEX_HULL_SING; IN_SING]; ALL_TAC ] THEN MP_TAC (ISPECL [`S:real^3->bool`; `S DELETE u:real^3`] AFFINE_HULL_CIRCUMCENTER_PROJECTION) THEN ASM_REWRITE_TAC[DELETE_SUBSET] THEN ABBREV_TAC `p0:real^3 = circumcenter (S DELETE u)` THEN STRIP_TAC THEN POP_ASSUM (LABEL_TAC "vw") THEN SUBGOAL_THEN `p0:real^3 IN affine hull (S DELETE u)` ASSUME_TAC THENL [ EXPAND_TAC "p0" THEN MP_TAC (ISPEC `S DELETE u:real^3` OAPVION1) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[DELETE_SUBSET]; ALL_TAC ] THEN SIMP_TAC[]; ALL_TAC ] THEN UNDISCH_TAC `~(S DELETE u:real^3 = {})` THEN PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN DISCH_THEN (X_CHOOSE_THEN `v:real^3` ASSUME_TAC) THEN SUBGOAL_THEN `dist (p, v) pow 2 = dist (p0, v) pow 2 + dist (p0, p:real^3) pow 2` ASSUME_TAC THENL [ ASM_REWRITE_TAC[dist; NORM_POW_2; VECTOR_ARITH `p0 - (p0 + n) = --n:real^3`; VECTOR_ARITH `(p0 + n) - v = (p0 - v) + n:real^3`] THEN REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LNEG; DOT_RNEG; REAL_NEG_NEG; DOT_SYM] THEN REWRITE_TAC[REAL_ARITH `(p0v +nv) + nv + nn = p0v + nn <=> nv = &0`] THEN REMOVE_THEN "vw" MP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_TO_AFFINE_HULL_EQ] THEN REWRITE_TAC[DOT_SYM] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S DELETE u:real^3` THEN ASM_REWRITE_TAC[HULL_SUBSET]; ALL_TAC ] THEN SUBGOAL_THEN `dist (p,u:real^3) pow 2 = dist (p0,u) pow 2 + dist (p0,p) pow 2 + &2 * (p - p0) dot (p0 - u)` ASSUME_TAC THENL [ ASM_REWRITE_TAC[dist; NORM_POW_2; VECTOR_ARITH `(p0 + n) - u = (p0 - u) + n:real^3`; VECTOR_ARITH `p0 - (p0 + n) = --n:real^3`] THEN REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LNEG; DOT_RNEG; REAL_NEG_NEG; DOT_SYM] THEN REWRITE_TAC[REAL_ARITH `(a + b) + b + c = a + c + &2 * d <=> b = d`] THEN REWRITE_TAC[VECTOR_SUB_REFL; DOT_LZERO; REAL_ADD_LID]; ALL_TAC ] THEN SUBGOAL_THEN `dist (p0, u) <= dist (p0, v:real^3)` MP_TAC THENL [ REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[GSYM REAL_ABS_NORM] THEN REWRITE_TAC[REAL_LE_SQUARE_ABS; GSYM dist] THEN SUBGOAL_THEN `dist (p0,v:real^3) pow 2 = dist (p,v) pow 2 - dist (p0,p) pow 2` (fun th -> REWRITE_TAC[th]) THENL [ REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `dist (p0,u:real^3) pow 2 = dist (p,u) pow 2 - dist (p0,p) pow 2 - &2 * ((p - p0) dot (p0 - u))` (fun th -> REWRITE_TAC[th]) THENL [ POP_ASSUM MP_TAC THEN REAL_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `dist (p, u) = dist (p, v:real^3)` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `u:real^3`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `v:real^3`) THEN UNDISCH_TAC `v IN S DELETE u:real^3` THEN ASM_SIMP_TAC[IN_DELETE]; ALL_TAC ] THEN REWRITE_TAC[REAL_ARITH `a - b - &2 * c <= a - b <=> --c <= &0`] THEN REWRITE_TAC[GSYM DOT_RNEG; VECTOR_NEG_SUB] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `n:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[REAL_NOT_LE] THEN MP_TAC (SPECL [`V:real^3->bool`; `S DELETE u:real^3`; `p0:real^3`] XYOFCGX) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `S:real^3->bool` THEN REWRITE_TAC[DELETE_SUBSET] THEN EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN CONJ_TAC THENL [ MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[DELETE_SUBSET]; ALL_TAC ] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `radV (S:real^3->bool)` THEN EXPAND_TAC "S" THEN ASM_REWRITE_TAC[GSYM HL] THEN ASM_REWRITE_TAC[HL] THEN MATCH_MP_TAC RADV_MONO THEN ASM_REWRITE_TAC[DELETE_SUBSET; GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `v:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPECL [`v:real^3`; `u:real^3`]) THEN ASM_REWRITE_TAC[DIST_SYM; real_gt] THEN DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_DIFF; IN_DELETE] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]);;
(* XNHPWAB4 *)
let XNHPWAB4 = 
prove(`!V ul k. packing V /\ (ul IN barV V k) /\ (hl ul < sqrt(&2)) ==> (!i j. (i < j) /\ (j <= k) ==> hl(truncate_simplex i ul) < hl(truncate_simplex j ul))`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN ABBREV_TAC `xl:(real^3)list = truncate_simplex j ul` THEN ABBREV_TAC `yl:(real^3)list = truncate_simplex i ul` THEN SUBGOAL_THEN `barV V i yl /\ barV V j xl` ASSUME_TAC THENL [ EXPAND_TAC "xl" THEN EXPAND_TAC "yl" THEN CONJ_TAC THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `j:num` THEN ASM_SIMP_TAC[LT_IMP_LE]; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (xl:(real^3)list) = j + 1 /\ LENGTH (yl:(real^3)list) = i + 1 /\ i + 1 <= j + 1` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN SIMP_TAC[BARV; ARITH_RULE `i + 1 <= j + 1 <=> i <= j`] THEN ASM_SIMP_TAC[LT_IMP_LE]; ALL_TAC ] THEN SUBGOAL_THEN `hl (xl:(real^3)list) < sqrt (&2) /\ hl (yl:(real^3)list) < sqrt (&2)` ASSUME_TAC THENL [ CONJ_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THENL [ EXPAND_TAC "xl";
EXPAND_TAC "yl" ] THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[IN] THEN MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `j:num` THEN ASM_SIMP_TAC[LT_IMP_LE]; ALL_TAC ] THEN SUBGOAL_THEN `truncate_simplex i xl = yl:(real^3)list` ASSUME_TAC THENL [ EXPAND_TAC "xl" THEN EXPAND_TAC "yl" THEN MATCH_MP_TAC TRUNCATE_TRUNCATE_SIMPLEX THEN ASM_SIMP_TAC[LT_IMP_LE] THEN UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV] THEN ASM_REWRITE_TAC[ARITH_RULE `j + 1 <= k + 1 <=> j <= k`]; ALL_TAC ] THEN REPEAT (FIRST_X_ASSUM ((fun th -> ALL_TAC) o check (free_in `ul:(real^3)list` o concl))) THEN SUBGOAL_THEN `set_of_list yl SUBSET ((set_of_list xl):real^3->bool) /\ ~(set_of_list yl = {})` ASSUME_TAC THENL [ CONJ_TAC THENL [ EXPAND_TAC "yl" THEN MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `HD (yl:(real^3)list)` THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC ]; ALL_TAC ] THEN SUBGOAL_THEN `~affine_dependent (set_of_list xl:real^3->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `j:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `~affine_dependent (set_of_list yl:real^3->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `i:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `?v:real^3. v IN set_of_list xl /\ ~(v IN set_of_list yl)` CHOOSE_TAC THENL [ ASM_CASES_TAC `set_of_list xl = set_of_list yl:real^3->bool` THENL [ MATCH_MP_TAC (TAUT `F ==> P`) THEN MP_TAC (SPECL [`V:real^3->bool`; `xl:(real^3)list`; `j:num`] MHFTTZN1) THEN MP_TAC (SPECL [`V:real^3->bool`; `yl:(real^3)list`; `i:num`] MHFTTZN1) THEN ASM_SIMP_TAC[] THEN REWRITE_TAC[INT_OF_NUM_EQ] THEN UNDISCH_TAC `i < j:num` THEN ARITH_TAC; ALL_TAC ] THEN MP_TAC (ISPECL [`set_of_list yl:real^3->bool`; `set_of_list xl:real^3->bool`] PSUBSET_MEMBER) THEN ASM_REWRITE_TAC[PSUBSET]; ALL_TAC ] THEN REWRITE_TAC[HL] THEN MP_TAC (ISPECL [`set_of_list xl:real^3->bool`; `set_of_list yl:real^3->bool`] AFFINE_HULL_RADV) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN SUBGOAL_THEN `!s:real^3->bool. &0 <= radV s ==> radV s = abs (radV s)` MP_TAC THENL [ SIMP_TAC[GSYM REAL_ABS_REFL]; ALL_TAC ] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `set_of_list yl:real^3->bool`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `set_of_list xl:real^3->bool`) THEN ASM_REWRITE_TAC[] THEN REPLICATE_TAC 2 (DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th])) THEN ASM_REWRITE_TAC[REAL_LT_SQUARE_ABS] THEN REWRITE_TAC[REAL_ARITH `a < a + b <=> &0 < b`] THEN REWRITE_TAC[dist; NORM_POW_2; DOT_POS_LT; VECTOR_SUB_EQ] THEN DISCH_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `set_of_list yl:real^3->bool`; `circumcenter (set_of_list xl):real^3`] XYOFCGX) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[GSYM HL] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `i:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPECL [`HD yl:real^3`; `v:real^3`]) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[IN_DIFF] THEN CONJ_TAC THENL [ MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `set_of_list xl:real^3->bool` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `j:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[] THEN MATCH_MP_TAC (REAL_ARITH `a = b ==> ~(a > b:real)`) THEN MP_TAC (ISPEC `set_of_list xl:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `v:real^3`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `HD yl:real^3`) THEN ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ SUBGOAL_THEN `HD yl = HD xl:real^3` (fun th -> REWRITE_TAC[th]) THENL [ EXPAND_TAC "yl" THEN MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN SIMP_TAC[DIST_SYM]);; (* XNHPWAB3 *)
let OMEGA_LIST_N_IN_CONVEX_HULL = 
prove(`!V ul k i. packing V /\ barV V k ul /\ i <= k /\ hl ul < sqrt (&2) ==> omega_list_n V ul i IN convex hull set_of_list ul`,
REPEAT STRIP_TAC THEN ABBREV_TAC `vl:(real^3)list = truncate_simplex i ul` THEN SUBGOAL_THEN `barV V i vl` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = i + 1 /\ LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN POP_ASSUM MP_TAC THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `omega_list_n V ul i = omega_list V vl` (fun th -> REWRITE_TAC[th]) THENL [ ASM_REWRITE_TAC[OMEGA_LIST; ARITH_RULE `(i + 1) - 1 = i`] THEN EXPAND_TAC "vl" THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `i:num`; `0`] OMEGA_LIST_N_LEMMA) THEN REWRITE_TAC[ARITH_RULE `i + 0 = i`] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[ARITH_RULE `i + 0 + 1 <= k + 1 <=> i <= k`]; ALL_TAC ] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `convex hull set_of_list vl:real^3->bool` THEN CONJ_TAC THENL [ MATCH_MP_TAC XNHPWAB2 THEN EXISTS_TAC `i:num` THEN ASM_REWRITE_TAC[IN] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN MATCH_MP_TAC HULL_MONO THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`]);;
let XNHPWAB3 = 
prove(`!V ul k. packing V /\ (ul IN barV V k) /\ (hl ul < sqrt(&2)) ==> (aff_dim { omega_list_n V ul j | j IN (0..k)} = &k)`,
REWRITE_TAC[IN_NUMSEG; IN] THEN REPEAT GEN_TAC THEN SPEC_TAC (`ul:(real^3)list`, `ul:(real^3)list`) THEN SPEC_TAC (`k:num`, `k:num`) THEN INDUCT_TAC THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[IN_NUMSEG; LE_ANTISYM; EQ_SYM_EQ] THEN SUBGOAL_THEN `{omega_list_n V ul j | j = 0} = {omega_list_n V ul 0}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN GEN_TAC THEN EQ_TAC THENL [ STRIP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_TAC THEN EXISTS_TAC `0` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[AFF_DIM_SING]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN ABBREV_TAC `vl:(real^3)list = truncate_simplex k ul` THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN SUBGOAL_THEN `barV V k vl` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[ARITH_RULE `k <= SUC k`]; ALL_TAC ] THEN SUBGOAL_THEN `hl (vl:(real^3)list) < sqrt (&2)` ASSUME_TAC THENL [ MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `SUC k`] THEN ASM_REWRITE_TAC[ARITH_RULE `k <= SUC k`; IN]; ALL_TAC ] THEN ASM_SIMP_TAC[ARITH_RULE `SUC k <= 3 ==> k <= 3`] THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 2 /\ LENGTH (vl:(real^3)list) = k + 1` ASSUME_TAC THENL [ REPEAT (FIRST_X_ASSUM (MP_TAC o check (free_in `barV` o concl))) THEN SIMP_TAC[BARV; ADD1; ARITH_RULE `(k + 1) + 1 = k + 2`]; ALL_TAC ] THEN SUBGOAL_THEN `{omega_list_n V ul j | 0 <= j /\ j <= SUC k} = omega_list_n V ul (SUC k) INSERT {omega_list_n V vl j | 0 <= j /\ j <= k}` MP_TAC THENL [ SUBGOAL_THEN `!j. 0 <= j /\ j <= k ==> omega_list_n V vl j = omega_list_n V ul j` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN EXPAND_TAC "vl" THEN SUBGOAL_THEN `k = j + (k - j:num)` MP_TAC THENL [ POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN MATCH_MP_TAC (GSYM OMEGA_LIST_N_LEMMA) THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INSERT] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN ASM_CASES_TAC `j = SUC k` THEN ASM_REWRITE_TAC[] THEN DISJ2_TAC THEN EXISTS_TAC `j:num` THEN MP_TAC (ARITH_RULE `j <= SUC k /\ ~(j = SUC k) ==> j <= k`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REPEAT STRIP_TAC THENL [ EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[LE_0; LE_REFL]; ALL_TAC ] THEN EXISTS_TAC `j:num` THEN ASM_SIMP_TAC[ARITH_RULE `j <= k ==> j <= SUC k`]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN ASM_REWRITE_TAC[AFF_DIM_INSERT] THEN SUBGOAL_THEN `~(omega_list_n V ul (SUC k) IN affine hull {omega_list_n V vl j | 0 <= j /\ j <= k})` (fun th -> REWRITE_TAC[th; ADD1; INT_OF_NUM_ADD]) THEN SUBGOAL_THEN `omega_list_n V ul (SUC k) = circumcenter (set_of_list ul)` (fun th -> REWRITE_TAC[th]) THENL [ SUBGOAL_THEN `omega_list_n V ul (SUC k) = omega_list V ul` (fun th -> REWRITE_TAC[th]) THENL [ ASM_REWRITE_TAC[OMEGA_LIST; ARITH_RULE `(k + 2) - 1 = SUC k`]; ALL_TAC ] THEN MATCH_MP_TAC XNHPWAB1 THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN DISCH_TAC THEN SUBGOAL_THEN `~affine_dependent ((set_of_list ul):real^3->bool)` ASSUME_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `SUC k`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `set_of_list vl SUBSET ((set_of_list ul):real^3->bool) /\ ~(set_of_list vl = {})` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN CONJ_TAC THENL [ MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `HD (vl:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC ]; ALL_TAC ] THEN SUBGOAL_THEN `circumcenter (set_of_list ul) = circumcenter (set_of_list vl):real^3` ASSUME_TAC THENL [ MATCH_MP_TAC AFFINE_HULL_CIRCUMCENTER_EQ THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `affine hull {omega_list_n V vl j | 0 <= j /\ j <= k}` THEN ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM HULL_HULL] THEN MATCH_MP_TAC HULL_MONO THEN REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `convex hull set_of_list (vl:(real^3)list)` THEN ASM_REWRITE_TAC[CONVEX_HULL_SUBSET_AFFINE_HULL] THEN MATCH_MP_TAC OMEGA_LIST_N_IN_CONVEX_HULL THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] XNHPWAB4) THEN ASM_REWRITE_TAC[IN] THEN DISCH_THEN (MP_TAC o SPECL [`k:num`; `SUC k`]) THEN ANTS_TAC THENL [ ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC (REAL_ARITH `a = b ==> ~(a < b:real)`) THEN SUBGOAL_THEN `truncate_simplex (SUC k) ul = ul:(real^3)list` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL [`SUC k`; `ul:(real^3)list`; `ul:(real^3)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[ARITH_RULE `SUC k + 1 <= k + 2`; ARITH_RULE `k + 2 = SUC k + 1`; INITIAL_SUBLIST_REFL] THEN SIMP_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] HL_PROPERTIES) THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `k:num`] HL_PROPERTIES) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `HD vl:real^3`) THEN ANTS_TAC THENL [ MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN DISCH_THEN (MP_TAC o SPEC `HD vl:real^3`) THEN ANTS_TAC THENL [ SUBGOAL_THEN `HD vl = HD ul:real^3` (fun th -> REWRITE_TAC[th]) THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN SIMP_TAC[]);;
(*************************************************) (***********) (* WAUFCHE *) (***********) (* WAUFCHE1 *)
let IN_VORONOI_LIST_IMP_IN_BIS = 
prove(`!V ul k x. barV V k ul /\ x IN voronoi_list V ul ==> (!u. u IN set_of_list ul ==> x IN bis (HD ul) u)`,
REPEAT STRIP_TAC THEN MP_TAC (ISPEC `ul:(real^3)list` LENGTH_IMP_CONS) THEN ANTS_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV; ARITH_RULE `1 <= k + 1`]; ALL_TAC ] THEN STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `h:real^3`; `t:(real^3)list`] VORONOI_LIST_BIS) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]); ALL_TAC ] THEN DISCH_TAC THEN UNDISCH_TAC `x:real^3 IN voronoi_list V ul` THEN ASM_REWRITE_TAC[IN_INTER; IN_INTERS; IN_ELIM_THM; HD] THEN STRIP_TAC THEN UNDISCH_TAC `u:real^3 IN set_of_list ul` THEN ASM_REWRITE_TAC[IN_SET_OF_LIST; MEM] THEN DISCH_THEN DISJ_CASES_TAC THENL [ ASM_REWRITE_TAC[bis; IN_ELIM_THM]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `bis h (u:real^3)`) THEN DISCH_THEN MATCH_MP_TAC THEN EXISTS_TAC `u:real^3` THEN ASM_REWRITE_TAC[IN_SET_OF_LIST]);;
let WAUFCHE1 = 
prove(`!V ul k. packing V /\ ul IN barV V k ==> hl ul <= dist(omega_list V ul, HD ul)`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN ABBREV_TAC `p = omega_list V ul` THEN MP_TAC (ISPECL [`set_of_list ul:real^3->bool`; `p:real^3`] AFFINE_HULL_PROJECTION_EXISTS) THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `HD (ul:(real^3)list) IN set_of_list ul` ASSUME_TAC THENL [ MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[SET_OF_LIST_EQ_EMPTY; GSYM LENGTH_EQ_NIL; ARITH_RULE `~(k + 1 = 0)`] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `dist (x:real^3, HD ul)` THEN CONJ_TAC THENL [ MP_TAC (SPEC_ALL HL_EQ_DIST0) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[REAL_LE_LT] THEN DISJ2_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[PAIR_EQ] THEN MP_TAC (ISPEC `set_of_list ul:real^3->bool` OAPVION3) THEN ANTS_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MATCH_MP_TAC o GSYM) THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `dist (x:real^3, HD ul)` THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC AFFINE_HULL_PROJECTION_DIST_EQ THEN MAP_EVERY EXISTS_TAC [`set_of_list ul:real^3->bool`; `p:real^3`; `n:real^3`] THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`; `p:real^3`] IN_VORONOI_LIST_IMP_IN_BIS) THEN ANTS_TAC THENL [ EXPAND_TAC "p" THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC OMEGA_LIST_IN_VORONOI_LIST THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPEC `w:real^3`) THEN ASM_REWRITE_TAC[bis; IN_ELIM_THM]; ALL_TAC ] THEN MATCH_MP_TAC AFFINE_HULL_PROJECTION_DIST_LE THEN MAP_EVERY EXISTS_TAC [`set_of_list ul:real^3->bool`; `n:real^3`] THEN ASM_REWRITE_TAC[]);;
(* WAUFCHE2 *)
let WAUFCHE2 = 
prove(`!V ul k. packing V /\ ul IN barV V k /\ hl ul < sqrt(&2) ==> (hl ul = dist(omega_list V ul, HD ul))`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`] HL_EQ_DIST0) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN AP_TERM_TAC THEN REWRITE_TAC[PAIR_EQ] THEN MATCH_MP_TAC (GSYM XNHPWAB1) THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[IN] THEN MATCH_MP_TAC BARV_IMP_K_LE_3 THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `ul:(real^3)list`] THEN ASM_REWRITE_TAC[]);;
(*************************************************) (********************) (* Delaunay simplex *) (********************) (* YIFVQDV *)
let CIRCUMCENTER_IN_VORONOI_SET = 
prove(`!V (S:real^3->bool). packing V /\ S SUBSET V /\ ~affine_dependent S /\ radV S < sqrt (&2) ==> circumcenter S IN voronoi_set V S`,
REPEAT STRIP_TAC THEN ABBREV_TAC `p:real^3 = circumcenter S` THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN MP_TAC (ISPECL [`V:real^3->bool`; `S:real^3->bool`; `p:real^3`] XYOFCGX) THEN ASM_REWRITE_TAC[] THEN REPEAT DISCH_TAC THEN REWRITE_TAC[VORONOI_SET; IN_INTERS; IN_ELIM_THM; voronoi_closed] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN POP_ASSUM (ASSUME_TAC o ONCE_REWRITE_RULE[GSYM IN]) THEN ASM_CASES_TAC `w:real^3 IN S` THENL [ FIRST_ASSUM (MP_TAC o SPEC `w:real^3`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `v:real^3`) THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[REAL_LE_REFL]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`v:real^3`; `w:real^3`]) THEN ASM_REWRITE_TAC[IN_DIFF; DIST_SYM] THEN REAL_ARITH_TAC);;
let NEIGHBORHOOD_lemma = 
prove(`!V S p. packing V /\ S SUBSET V /\ (!u v. u IN S /\ v IN V DIFF S ==> dist (v, p) > dist (u, p)) ==> ?r. &0 < r /\ (!x u v. x IN ball(p, r) /\ u IN S /\ v IN V DIFF S ==> dist (v, x) > dist (u, x))`,
REWRITE_TAC[real_gt] THEN REPEAT STRIP_TAC THEN ASM_CASES_TAC `V DIFF S = {}:real^3->bool` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THENL [ EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01]; ALL_TAC ] THEN SUBGOAL_THEN `?R. S SUBSET ball(p:real^3, R)` CHOOSE_TAC THENL [ POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN STRIP_TAC THEN EXISTS_TAC `dist (x:real^3, p)` THEN REWRITE_TAC[ball; SUBSET; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPECL [`x':real^3`; `x:real^3`]) THEN ASM_REWRITE_TAC[DIST_SYM]; ALL_TAC ] THEN SUBGOAL_THEN `?d. &0 < d /\ (!u v. u IN S /\ v IN (V DIFF S) INTER ball (p:real^3, R + &2) ==> dist (v, p) >= dist (u, p) + d)` STRIP_ASSUME_TAC THENL [ ABBREV_TAC `K = IMAGE (\(u,v). dist (v,p:real^3) - dist (u,p)) {u,v | u IN S /\ v IN (V DIFF S) INTER ball (p:real^3, R + &2)}` THEN SUBGOAL_THEN `FINITE (K:real->bool)` ASSUME_TAC THENL [ EXPAND_TAC "K" THEN MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_PRODUCT THEN CONJ_TAC THEN MATCH_MP_TAC FINITE_SUBSET THENL [ EXISTS_TAC `V INTER ball (p:real^3, R)` THEN ASM_SIMP_TAC[KIUMVTC; SUBSET_INTER]; EXISTS_TAC `V INTER (ball (p:real^3, R + &2))` THEN ASM_SIMP_TAC[KIUMVTC; SUBSET_INTER; INTER_SUBSET] THEN SIMP_TAC[SUBSET; IN_INTER; IN_DIFF] ]; ALL_TAC ] THEN ASM_CASES_TAC `K = {}:real->bool` THENL [ POP_ASSUM MP_TAC THEN EXPAND_TAC "K" THEN REWRITE_TAC[IMAGE_EQ_EMPTY; EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_EXISTS_THM] THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPECL [`u:real^3,v:real^3`; `u:real^3`; `v:real^3`]) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN EXISTS_TAC `inf (K:real->bool)` THEN MP_TAC (SPEC `K:real->bool` INF_FINITE) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ABBREV_TAC `d = inf K` THEN CONJ_TAC THENL [ UNDISCH_TAC `d:real IN K` THEN EXPAND_TAC "K" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`u:real^3`; `v:real^3`]) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN SIMP_TAC[IN_INTER]; ALL_TAC ] THEN REAL_ARITH_TAC; ALL_TAC ] THEN REPEAT STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `dist (v:real^3,p) - dist (u,p)`) THEN ANTS_TAC THENL [ EXPAND_TAC "K" THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN EXISTS_TAC `u:real^3,v:real^3` THEN REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC [`u:real^3`; `v:real^3`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REAL_ARITH_TAC; ALL_TAC ] THEN ABBREV_TAC `r = min (&1) (d / &2)` THEN SUBGOAL_THEN `&0 < r /\ r <= &1 /\ r <= d / &2` ASSUME_TAC THENL [ EXPAND_TAC "r" THEN REWRITE_TAC[REAL_MIN_MIN; REAL_LT_MIN] THEN UNDISCH_TAC `&0 < d` THEN REAL_ARITH_TAC; ALL_TAC ] THEN EXISTS_TAC `r:real` THEN ASM_REWRITE_TAC[ball; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_ARITH `a < b <=> &0 < b - a`] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `(dist (v, p) - dist (u, p)) - &2 * dist (p:real^3, x)` THEN CONJ_TAC THENL [ MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `dist (v, p) - dist (u, p:real^3) - &2 * r` THEN CONJ_TAC THENL [ ASM_CASES_TAC `v IN ball (p:real^3,R + &2)` THENL [ FIRST_X_ASSUM (MP_TAC o SPECL [`u:real^3`; `v:real^3`]) THEN ASM_REWRITE_TAC[IN_INTER] THEN FIRST_X_ASSUM (MP_TAC o check (is_conj o concl)) THEN REAL_ARITH_TAC; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN SUBGOAL_THEN `u IN ball(p:real^3,R)` MP_TAC THENL [ MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `S:real^3->bool` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[ball; IN_ELIM_THM; REAL_NOT_LT; DIST_SYM] THEN FIRST_X_ASSUM (MP_TAC o check (is_conj o concl)) THEN REAL_ARITH_TAC; ALL_TAC ] THEN UNDISCH_TAC `dist (p:real^3,x) < r` THEN REAL_ARITH_TAC; ALL_TAC ] THEN MP_TAC (ISPECL [`u:real^3`; `p:real^3`; `x:real^3`] DIST_TRIANGLE) THEN MP_TAC (ISPECL [`p:real^3`; `x:real^3`; `v:real^3`] DIST_TRIANGLE) THEN REWRITE_TAC[DIST_SYM] THEN REAL_ARITH_TAC);;
let SUBSPACES_INTER_BALL_EQ_IMP_EQ = 
prove(`!s t r. subspace s /\ subspace t /\ &0 < r /\ s INTER ball (vec 0:real^N, r) = t INTER ball (vec 0, r) ==> s = t`,
REWRITE_TAC[subspace] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `!v:real^N. ?d. d % v IN ball (vec 0,r) /\ v = (inv d) % (d % v)` ASSUME_TAC THENL [ GEN_TAC THEN EXISTS_TAC `(r / &2) * inv(norm (v:real^N))` THEN ASM_CASES_TAC `v = vec 0:real^N` THENL [ ASM_REWRITE_TAC[VECTOR_MUL_RZERO; CENTRE_IN_BALL]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM NORM_EQ_0] THEN DISCH_TAC THEN CONJ_TAC THENL [ REWRITE_TAC[ball; IN_ELIM_THM; dist; VECTOR_SUB_LZERO; NORM_NEG; NORM_MUL] THEN REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_INV; REAL_ABS_NORM; GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_MUL_LINV] THEN UNDISCH_TAC `&0 < r` THEN REAL_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_INV_MUL; REAL_INV_INV] THEN REWRITE_TAC[REAL_ARITH `(ia * b) * a * ib = (ia * a) * (ib * b)`] THEN ASM_SIMP_TAC[REAL_MUL_LINV; REAL_ARITH `&0 < r ==> ~(r / &2 = &0)`] THEN REWRITE_TAC[REAL_MUL_LID; VECTOR_MUL_LID]; ALL_TAC ] THEN REWRITE_TAC[EXTENSION] THEN GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `x:real^N`) THEN STRIP_TAC THEN ABBREV_TAC `v:real^N = d % x` THEN FIRST_X_ASSUM (MP_TAC o SPECL [`inv d`; `v:real^N`]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN SUBGOAL_THEN `v IN s INTER ball (vec 0:real^N,r)` MP_TAC THENL [ ASM_REWRITE_TAC[IN_INTER] THEN EXPAND_TAC "v" THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN SIMP_TAC[IN_INTER]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `x:real^N`) THEN STRIP_TAC THEN ABBREV_TAC `v:real^N = d % x` THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN SUBGOAL_THEN `v IN t INTER ball (vec 0:real^N,r)` MP_TAC THENL [ ASM_REWRITE_TAC[IN_INTER] THEN EXPAND_TAC "v" THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REPLICATE_TAC 4 REMOVE_ASSUM THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN SIMP_TAC[IN_INTER]);;
let AFFINES_INTER_BALL_EQ_IMP_EQ = 
prove(`!s t (x:real^N) r. affine s /\ affine t /\ &0 < r /\ s INTER ball (x, r) = t INTER ball (x, r) /\ x IN s ==> s = t`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `IMAGE (\v:real^N. --x + v) s = IMAGE (\v:real^N. --x + v) t` MP_TAC THENL [ MATCH_MP_TAC SUBSPACES_INTER_BALL_EQ_IMP_EQ THEN EXISTS_TAC `r:real` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ MATCH_MP_TAC AFFINE_IMP_SUBSPACE THEN ASM_REWRITE_TAC[AFFINE_TRANSLATION_EQ; IN_IMAGE] THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC; MATCH_MP_TAC AFFINE_IMP_SUBSPACE THEN ASM_REWRITE_TAC[AFFINE_TRANSLATION_EQ; IN_IMAGE] THEN EXISTS_TAC `x:real^N` THEN REWRITE_TAC[VECTOR_ARITH `vec 0 = --x + x:real^N`] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `s INTER ball (x:real^N, r)` THEN ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL; INTER_SUBSET]; ALL_TAC ] THEN SUBGOAL_THEN `!s. IMAGE (\v:real^N. --x + v) s INTER ball (vec 0,r) = IMAGE (\v. --x + v) (s INTER ball(x, r))` (fun th -> REWRITE_TAC[th]) THENL [ GEN_TAC THEN SUBGOAL_THEN `ball (vec 0,r) = IMAGE (\v:real^N. --x + v) (ball (x, r))` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[GSYM BALL_TRANSLATION; VECTOR_ARITH `--x + x = vec 0:real^N`]; ALL_TAC ] THEN MATCH_MP_TAC (GSYM IMAGE_INTER_INJ) THEN VECTOR_ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (ISPEC `\v:real^N. --x + v` INJECTIVE_IMAGE) THEN REWRITE_TAC[VECTOR_ARITH `--x + x' = --x + y ==> x' = y:real^N`] THEN DISCH_THEN (MP_TAC o ISPECL [`s:real^N->bool`; `t:real^N->bool`]) THEN SIMP_TAC[]);;
let VORONOI_LIST_EQ_INTERS_BIS = 
prove(`!V (ul:(real^3)list). set_of_list ul SUBSET V /\ 1 <= LENGTH ul ==> voronoi_list V ul = voronoi_closed V (HD ul) INTER (INTERS {bis (HD ul) u | u | u IN set_of_list ul})`,
REPEAT STRIP_TAC THEN MP_TAC (ISPEC `ul:(real^3)list` LENGTH_IMP_CONS) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[HD] THEN SUBGOAL_THEN `INTERS {bis h u | u | u:real^3 IN set_of_list (CONS h t)} = INTERS {bis h u | u | u IN set_of_list t}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[set_of_list; IN_INSERT] THEN REWRITE_TAC[EXTENSION; IN_INTERS; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `bis h (u:real^3)`) THEN ANTS_TAC THENL [ EXISTS_TAC `u:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SIMP_TAC[]; REPEAT STRIP_TAC THENL [ ASM_REWRITE_TAC[bis; IN_ELIM_THM]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPEC `bis h (u:real^3)`) THEN ANTS_TAC THENL [ EXISTS_TAC `u:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SIMP_TAC[] ]; ALL_TAC ] THEN MATCH_MP_TAC VORONOI_LIST_BIS THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]));;
let AFFINE_HULL_VORONOI_LIST_SUBSET_INTERS_BIS = 
prove(`!V (ul:(real^3)list). set_of_list ul SUBSET V ==> affine hull (voronoi_list V ul) SUBSET INTERS {bis (HD ul) u | u | u IN set_of_list ul}`,
REPEAT STRIP_TAC THEN ASM_CASES_TAC `ul:(real^3)list = []` THENL [ ASM_REWRITE_TAC[VORONOI_LIST; set_of_list; VORONOI_SET; NOT_IN_EMPTY] THEN SUBGOAL_THEN `{voronoi_closed V (v:real^3) | v | F} = {} /\ {bis (HD []) (u:real^3) | F} = {}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY]; ALL_TAC ] THEN REWRITE_TAC[INTERS_0; AFFINE_HULL_UNIV; SUBSET_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `1 <= LENGTH (ul:(real^3)list)` ASSUME_TAC THENL [ ASM_REWRITE_TAC[ARITH_RULE `1 <= a <=> ~(a = 0)`; LENGTH_EQ_NIL]; ALL_TAC ] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull (INTERS {bis (HD ul) u | u | u:real^3 IN set_of_list ul})` THEN CONJ_TAC THENL [ MATCH_MP_TAC HULL_MONO THEN ASM_SIMP_TAC[VORONOI_LIST_EQ_INTERS_BIS] THEN REWRITE_TAC[INTER_SUBSET]; ALL_TAC ] THEN REWRITE_TAC[AFFINE_HULL_INTERS_BIS; SUBSET_REFL]);;
let YIFVQDV_lemma_aff_dim = 
prove(`!V vl. packing V /\ set_of_list vl SUBSET V /\ ~affine_dependent (set_of_list vl) /\ hl vl < sqrt (&2) ==> aff_dim (voronoi_list V vl) = aff_dim (INTERS {bis (HD vl) v | v | v IN set_of_list vl})`,
REPEAT STRIP_TAC THEN GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM AFF_DIM_AFFINE_HULL] THEN AP_TERM_TAC THEN MATCH_MP_TAC AFFINES_INTER_BALL_EQ_IMP_EQ THEN ABBREV_TAC `p:real^3 = circumcenter (set_of_list vl)` THEN ABBREV_TAC `S:real^3->bool = set_of_list vl` THEN SUBGOAL_THEN `?r. &0 < r /\ (!x u v. x IN ball (p:real^3, r) /\ u IN S /\ v IN V DIFF S ==> dist (v, x) > dist (u, x))` STRIP_ASSUME_TAC THENL [ MATCH_MP_TAC NEIGHBORHOOD_lemma THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC XYOFCGX THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "S" THEN ASM_REWRITE_TAC[GSYM HL]; ALL_TAC ] THEN MAP_EVERY EXISTS_TAC [`p:real^3`; `r:real`] THEN ASM_REWRITE_TAC[AFFINE_AFFINE_HULL] THEN CONJ_TAC THENL [ REWRITE_TAC[GSYM AFFINE_HULL_EQ] THEN REWRITE_TAC[AFFINE_HULL_INTERS_BIS]; ALL_TAC ] THEN CONJ_TAC THENL [ MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL [ REWRITE_TAC[SUBSET_INTER; INTER_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `affine hull voronoi_list V vl` THEN REWRITE_TAC[INTER_SUBSET] THEN EXPAND_TAC "S" THEN MATCH_MP_TAC AFFINE_HULL_VORONOI_LIST_SUBSET_INTERS_BIS THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `voronoi_list V vl INTER ball (p,r)` THEN CONJ_TAC THENL [ ASM_CASES_TAC `S = {}:real^3->bool` THENL [ POP_ASSUM MP_TAC THEN EXPAND_TAC "S" THEN REWRITE_TAC[SET_OF_LIST_EQ_EMPTY] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[VORONOI_LIST; VORONOI_SET; set_of_list; NOT_IN_EMPTY] THEN SUBGOAL_THEN `{bis (HD []) (v:real^3) | F} = {} /\ {voronoi_closed V (v:real^3) | v | F} = {}` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM]; ALL_TAC ] THEN REWRITE_TAC[INTERS_0; INTER_UNIV; SUBSET_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `1 <= LENGTH (vl:(real^3)list)` ASSUME_TAC THENL [ POP_ASSUM MP_TAC THEN EXPAND_TAC "S" THEN REWRITE_TAC[SET_OF_LIST_EQ_EMPTY; ARITH_RULE `1 <= a <=> ~(a = 0)`; LENGTH_EQ_NIL]; ALL_TAC ] THEN MP_TAC (ISPECL [`V:real^3->bool`; `vl:(real^3)list`] VORONOI_LIST_EQ_INTERS_BIS) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN SIMP_TAC[SUBSET; IN_INTER] THEN REWRITE_TAC[IN_INTERS; voronoi_closed; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN POP_ASSUM (ASSUME_TAC o ONCE_REWRITE_RULE[GSYM IN]) THEN ASM_CASES_TAC `w:real^3 IN S` THENL [ FIRST_X_ASSUM (MP_TAC o SPEC `bis (HD vl) (w:real^3)`) THEN ANTS_TAC THENL [ EXISTS_TAC `w:real^3` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SIMP_TAC[bis; IN_ELIM_THM; REAL_LE_REFL]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`x:real^3`; `HD vl:real^3`; `w:real^3`]) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[IN_DIFF] THEN EXPAND_TAC "S" THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[DIST_SYM; real_gt; REAL_LT_IMP_LE]; ALL_TAC ] THEN REWRITE_TAC[SUBSET_INTER; INTER_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `voronoi_list V vl:real^3->bool` THEN REWRITE_TAC[INTER_SUBSET; HULL_SUBSET]; ALL_TAC ] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `voronoi_list V vl` THEN ASM_REWRITE_TAC[HULL_SUBSET; VORONOI_LIST] THEN EXPAND_TAC "p" THEN MATCH_MP_TAC CIRCUMCENTER_IN_VORONOI_SET THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "S" THEN ASM_REWRITE_TAC[GSYM HL]);;
let YIFVQDV_1 = 
prove(`!V ul k p. packing V /\ ul IN barV V k /\ hl ul < sqrt (&2) /\ p permutes (0..k) ==> left_action_list p ul IN barV V k`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN ABBREV_TAC `vl = left_action_list p (ul:(real^3)list)` THEN REWRITE_TAC[BARV] THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = k + 1 /\ LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN REWRITE_TAC[LENGTH_LEFT_ACTION_LIST] THEN UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `set_of_list vl = set_of_list ul:real^3->bool` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MP_TAC (ISPECL [`ul:(real^3)list`; `p:num->num`] SET_OF_LIST_LEFT_ACTION_LIST) THEN ASM_REWRITE_TAC[ARITH_RULE `(k + 1) - 1 = k`]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `?j. vl':(real^3)list = truncate_simplex j vl /\ j + 1 <= k + 1 /\ LENGTH vl' = j + 1` CHOOSE_TAC THENL [ EXISTS_TAC `LENGTH (vl':(real^3)list) - 1` THEN ABBREV_TAC `n = LENGTH (vl':(real^3)list)` THEN MP_TAC (ISPECL [`vl:(real^3)list`; `vl':(real^3)list`] INITIAL_SUBLIST_IMP_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[ARITH_RULE `1 <= n <=> 0 < n`] THEN ASM_SIMP_TAC[ARITH_RULE `0 < n ==> n - 1 + 1 = n`]; ALL_TAC ] THEN REWRITE_TAC[VORONOI_NONDG] THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ MATCH_MP_TAC LET_TRANS THEN EXISTS_TAC `k + 1` THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_SIMP_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 1`]; MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `set_of_list (vl:(real^3)list)` THEN CONJ_TAC THENL [ MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ABBREV_TAC `a = \j. if j = 0 then &4 else aff_dim (INTERS {bis (HD vl) (v:real^3) | v | v IN set_of_list (truncate_simplex (j - 1) vl)})` THEN SUBGOAL_THEN `!i. i <= k ==> aff_dim (voronoi_list (V:real^3->bool) (truncate_simplex i vl)) = a (i + 1)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN EXPAND_TAC "a" THEN REWRITE_TAC[ARITH_RULE `~(i + 1 = 0) /\ (i + 1) - 1 = i`] THEN SUBGOAL_THEN `HD vl = HD (truncate_simplex i vl):real^3` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC (GSYM HD_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`]; ALL_TAC ] THEN MATCH_MP_TAC YIFVQDV_lemma_aff_dim THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `set_of_list (truncate_simplex i vl) SUBSET set_of_list vl:real^3->bool` ASSUME_TAC THENL [ MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN ASM_REWRITE_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`]; ALL_TAC ] THEN REPEAT CONJ_TAC THENL [ MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `set_of_list vl:real^3->bool` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `set_of_list vl:real^3->bool` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (vl:(real^3)list)` THEN CONJ_TAC THENL [ REWRITE_TAC[HL] THEN MATCH_MP_TAC RADV_MONO THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `HD (truncate_simplex i vl):real^3` THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN MP_TAC (ISPECL [`i:num`; `vl:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[ARITH_RULE `i + 1 <= k + 1 <=> i <= k`] THEN SIMP_TAC[ARITH_RULE `1 <= i + 1`]; ALL_TAC ] THEN ASM_REWRITE_TAC[HL] THEN ASM_REWRITE_TAC[GSYM HL]; ALL_TAC ] THEN SUBGOAL_THEN `a 0 = int_of_num 4 /\ a 1 = &3` ASSUME_TAC THENL [ EXPAND_TAC "a" THEN REWRITE_TAC[ARITH_RULE `~(1 = 0) /\ 1 - 1 = 0`] THEN ASM_SIMP_TAC[TRUNCATE_0_EQ_HEAD; ARITH_RULE `1 <= k + 1`] THEN REWRITE_TAC[set_of_list; IN_SING] THEN SUBGOAL_THEN `INTERS {bis (HD vl) v | v | v = HD vl:real^3} = bis (HD vl) (HD vl)` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_INTERS; IN_ELIM_THM; IN_SING] THEN GEN_TAC THEN REWRITE_TAC[GSYM EXTENSION] THEN EQ_TAC THEN REPEAT STRIP_TAC THENL [ POP_ASSUM (MP_TAC o SPEC `bis (HD vl) (HD vl):real^3->bool`) THEN ANTS_TAC THENL [ EXISTS_TAC `HD vl:real^3` THEN REWRITE_TAC[]; ALL_TAC ] THEN REWRITE_TAC[]; ASM_REWRITE_TAC[] ]; ALL_TAC ] THEN REWRITE_TAC[bis] THEN SUBGOAL_THEN `{x:real^3 | T} = UNIV` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV]; ALL_TAC ] THEN REWRITE_TAC[AFF_DIM_UNIV; DIMINDEX_3]; ALL_TAC ] THEN SUBGOAL_THEN `!j. j <= k ==> int_of_num 3 - &j <= a j - &1 /\ a j - &1 <= a (j + 1) /\ (a (j + 1) = &3 - &j <=> (!i. i <= j ==> a (i + 1) = &3 - &i))` ASSUME_TAC THENL [ INDUCT_TAC THENL [ DISCH_TAC THEN ASM_SIMP_TAC[ARITH; ARITH_RULE `i <= 0 <=> i = 0`] THEN INT_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[ADD1] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o check (is_imp o concl)) THEN ASM_SIMP_TAC[ARITH_RULE `j' + 1 <= k ==> j' <= k`] THEN STRIP_TAC THEN CONJ_TAC THENL [ REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `a (j' + 1) - int_of_num 1 <= a ((j' + 1) + 1)` ASSUME_TAC THENL [ EXPAND_TAC "a" THEN REWRITE_TAC[ARITH_RULE `~(j' + 1 = 0) /\ ~((j' + 1) + 1 = 0) /\ (j' + 1) - 1 = j' /\ ((j' + 1) + 1) - 1 = j' + 1`] THEN ABBREV_TAC `s:real^3->bool = INTERS {bis (HD vl) v | v | v IN set_of_list (truncate_simplex j' vl)}` THEN ABBREV_TAC `t:real^3->bool = INTERS {bis (HD vl) v | v | v IN set_of_list (truncate_simplex (j' + 1) vl)}` THEN SUBGOAL_THEN `~(t = {}:real^3->bool)` ASSUME_TAC THENL [ EXPAND_TAC "t" THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN ABBREV_TAC `S:real^3->bool = set_of_list (truncate_simplex (j' + 1) vl)` THEN ABBREV_TAC `c:real^3 = circumcenter S` THEN EXISTS_TAC `c:real^3` THEN REWRITE_TAC[IN_INTERS; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[bis; IN_ELIM_THM] THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ANTS_TAC THENL [ MATCH_MP_TAC AFFINE_INDEPENDENT_SUBSET THEN EXISTS_TAC `set_of_list vl:real^3->bool` THEN CONJ_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN EXPAND_TAC "S" THEN MATCH_MP_TAC SET_OF_LIST_TRUNCATE_SIMPLEX_SUBSET THEN MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `k + 1` THEN ASM_REWRITE_TAC[LE_REFL; ARITH_RULE `a + 1 <= b + 1 <=> a <= b`]; ALL_TAC ] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `v:real^3`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `HD vl:real^3`) THEN ANTS_TAC THENL [ EXPAND_TAC "S" THEN SUBGOAL_THEN `HD vl:real^3 = HD (truncate_simplex (j' + 1) vl)` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC (GSYM HD_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[ARITH_RULE `j' + 1 <= k ==> (j' + 1) + 1 <= k + 1`]; ALL_TAC ] THEN MATCH_MP_TAC HD_IN_SET_OF_LIST THEN MP_TAC (ISPECL [`j' + 1`; `vl:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[ARITH_RULE `j' + 1 <= k ==> (j' + 1) + 1 <= k + 1`; ARITH_RULE `1 <= a + 1`]; ALL_TAC ] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `?w:real^3. t = s INTER bis (HD vl) w` CHOOSE_TAC THENL [ ABBREV_TAC `w:real^3 = LAST (truncate_simplex (j' + 1) vl)` THEN EXISTS_TAC `w:real^3` THEN EXPAND_TAC "t" THEN EXPAND_TAC "s" THEN MP_TAC (ISPECL [`vl:(real^3)list`; `j':num`] TRUNCATE_SIMPLEX_ADD1) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN UNDISCH_TAC `j' + 1 <= k` THEN ARITH_TAC; ALL_TAC ] THEN ABBREV_TAC `yl = truncate_simplex (j' + 1) vl:(real^3)list` THEN DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN ASM_REWRITE_TAC[SET_OF_LIST_APPEND; set_of_list; IN_UNION; IN_SING] THEN EXPAND_TAC "s" THEN SET_TAC[]; ALL_TAC ] THEN POP_ASSUM (ASSUME_TAC o REWRITE_RULE[BIS_EQ_HYPERPLANE]) THEN ABBREV_TAC `aa = &2 % (w - HD vl:real^3)` THEN ABBREV_TAC `bb = w dot (w:real^3) - HD vl dot (HD vl:real^3)` THEN MP_TAC (ISPECL [`aa:real^3`; `bb:real`; `s:real^3->bool`] AFF_DIM_AFFINE_INTER_HYPERPLANE) THEN ANTS_TAC THENL [ EXPAND_TAC "s" THEN REWRITE_TAC[GSYM AFFINE_HULL_EQ] THEN MATCH_MP_TAC HULL_INTERS_EQ_INTERS THEN REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[BIS_EQ_HYPERPLANE; AFFINE_HYPERPLANE]; ALL_TAC ] THEN REMOVE_ASSUM THEN REMOVE_ASSUM THEN POP_ASSUM (fun th -> REWRITE_TAC[SYM th]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN COND_CASES_TAC THEN INT_ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN EQ_TAC THENL [ REPEAT STRIP_TAC THEN SUBGOAL_THEN `a (j' + 1) = int_of_num 3 - &j'` MP_TAC THENL [ REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_CASES_TAC `i = j' + 1` THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPEC `j' + 1`) THEN REWRITE_TAC[LE_REFL]; ALL_TAC ] THEN SUBGOAL_THEN `a (k + 1) = int_of_num 3 - &k` MP_TAC THENL [ REMOVE_ASSUM THEN FIRST_X_ASSUM (MP_TAC o SPEC `k:num`) THEN REWRITE_TAC[LE_REFL] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN SUBGOAL_THEN `truncate_simplex k vl = vl:(real^3)list` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL [`k:num`; `vl:(real^3)list`; `vl:(real^3)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[LE_REFL; INITIAL_SUBLIST_REFL]; ALL_TAC ] THEN ASM_REWRITE_TAC[VORONOI_LIST] THEN REWRITE_TAC[GSYM VORONOI_LIST] THEN UNDISCH_TAC `barV V k ul` THEN REWRITE_TAC[BARV; VORONOI_NONDG] THEN STRIP_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[INITIAL_SUBLIST_REFL; ARITH_RULE `0 < k + 1`; GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `k:num`) THEN REWRITE_TAC[LE_REFL] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_THEN (MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[ARITH_RULE `j <= k <=> j + 1 <= k + 1`] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[ARITH_RULE `j <= k <=> j + 1 <= k + 1`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th; GSYM INT_OF_NUM_ADD]) THEN INT_ARITH_TAC);;
(* YIFVQDV *)
let YIFVQDV = 
prove(`!V ul k p. packing V /\ ul IN barV V k /\ hl ul < sqrt(&2) /\ p permutes (0..k) ==> (left_action_list p ul IN barV V k) /\ (omega_list V (left_action_list p ul) = omega_list V ul)`,
REWRITE_TAC[IN] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN MP_TAC (SPEC_ALL YIFVQDV_1) THEN ASM_REWRITE_TAC[IN] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN ABBREV_TAC `vl:(real^3)list = left_action_list p ul` THEN MP_TAC (SPEC_ALL XNHPWAB1) THEN ASM_REWRITE_TAC[IN] THEN DISCH_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `k:num`] XNHPWAB1) THEN ASM_REWRITE_TAC[HL; IN] THEN SUBGOAL_THEN `set_of_list vl = set_of_list ul:real^3->bool` (fun th -> REWRITE_TAC[th]) THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC SET_OF_LIST_LEFT_ACTION_LIST THEN UNDISCH_TAC `barV V k ul` THEN ASM_SIMP_TAC[BARV; ARITH_RULE `(k + 1) - 1 = k`]; ALL_TAC ] THEN ASM_REWRITE_TAC[GSYM HL]);;
(***************************************************) (***********) (* KSOQKWL *) (***********)
let HL_TRUNCATE_SIMPLEX_OMEGA_N = 
prove(`!V k ul j. packing V /\ barV V k ul /\ j <= k /\ hl ul < sqrt (&2) ==> hl (truncate_simplex j ul) = dist (omega_list_n V ul j, HD ul)`,
REPEAT STRIP_TAC THEN ABBREV_TAC `vl:(real^3)list = truncate_simplex j ul` THEN SUBGOAL_THEN `barV V j vl` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `j:num`; `vl:(real^3)list`] HL_EQ_DIST0) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN AP_TERM_TAC THEN REWRITE_TAC[PAIR_EQ] THEN CONJ_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `j:num`] OMEGA_LIST_LEMMA) THEN ANTS_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN UNDISCH_TAC `j <= k:num` THEN SIMP_TAC[BARV] THEN ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC (GSYM XNHPWAB1) THEN EXISTS_TAC `j:num` THEN ASM_REWRITE_TAC[IN] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN UNDISCH_TAC `barV V k ul` THEN UNDISCH_TAC `j <= k:num` THEN SIMP_TAC[BARV] THEN ARITH_TAC);;
let KSOQKWL_lemma0 = 
prove(`!V ul vl k. packing V /\ barV V k ul /\ barV V k vl /\ ~(HD ul = HD vl) ==> ~({omega_list_n V ul i | i <= k} = {omega_list_n V vl i | i <= k})`,
REPEAT GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[EXTENSION; NOT_FORALL_THM; IN_ELIM_THM] THEN EXISTS_TAC `HD ul:real^3` THEN MATCH_MP_TAC (TAUT `~(A ==> B) ==> ~(A <=> B)`) THEN REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL [ EXISTS_TAC `0` THEN REWRITE_TAC[OMEGA_LIST_N; LE_0]; ALL_TAC ] THEN REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(A /\ B) <=> A ==> ~B`] THEN REPEAT STRIP_TAC THEN POP_ASSUM (ASSUME_TAC o SYM) THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = k + 1 /\ LENGTH (ul:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k vl` THEN UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `i + 1 <= k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `i <= k:num` THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `omega_list_n V vl i IN voronoi_closed V (HD vl)` MP_TAC THENL [ MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `voronoi_list V (truncate_simplex i vl)` THEN CONJ_TAC THENL [ MATCH_MP_TAC OMEGA_LIST_N_IN_VORONOI_LIST THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `HD vl = HD (truncate_simplex i vl):real^3` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC (GSYM HD_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC VORONOI_LIST_SUBSET_VORONOI_CLOSED THEN MP_TAC (ISPECL [`i:num`; `vl:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[voronoi_closed; IN_ELIM_THM; NOT_FORALL_THM] THEN EXISTS_TAC `HD ul:real^3` THEN REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL [ ONCE_REWRITE_TAC[GSYM IN] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `set_of_list ul:real^3->bool` THEN CONJ_TAC THENL [ MATCH_MP_TAC HD_IN_SET_OF_LIST THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[DIST_REFL; DIST_LE_0]);;
let KSOQKWL_lemma1 = 
prove(`!V ul vl k j. packing V /\ barV V k ul /\ barV V k vl /\ hl ul < sqrt (&2) /\ hl vl < sqrt (&2) /\ 0 < j /\ j <= k /\ truncate_simplex (j - 1) ul = truncate_simplex (j - 1) vl /\ hl (truncate_simplex j ul) <= hl (truncate_simplex j vl) /\ ~(omega_list_n V ul j = omega_list_n V vl j) ==> ~({omega_list_n V ul i | i <= k} = {omega_list_n V vl i | i <= k})`,
REPEAT GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[EXTENSION; NOT_FORALL_THM; IN_ELIM_THM] THEN EXISTS_TAC `omega_list_n V ul j` THEN MATCH_MP_TAC (TAUT `~(A ==> B) ==> ~(A <=> B)`) THEN REWRITE_TAC[NOT_IMP; NOT_EXISTS_THM] THEN CONJ_TAC THENL [ EXISTS_TAC `j:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 1 /\ LENGTH (vl:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN UNDISCH_TAC `barV V k vl` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN SUBGOAL_THEN `j + 1 <= k + 1` ASSUME_TAC THENL [ ASM_REWRITE_TAC[ARITH_RULE `j + 1 <= k + 1 <=> j <= k`]; ALL_TAC ] THEN MP_TAC (ARITH_RULE `0 < j /\ j <= k ==> j - 1 + 1 = j /\ j <= k + 1`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN REWRITE_TAC[TAUT `~(A /\ B) <=> (A ==> ~B)`] THEN REPEAT STRIP_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`; `j:num`] HL_TRUNCATE_SIMPLEX_OMEGA_N) THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `vl:(real^3)list`; `i:num`] HL_TRUNCATE_SIMPLEX_OMEGA_N) THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `HD vl = HD ul:real^3` ASSUME_TAC THENL [ SUBGOAL_THEN `HD vl = HD (truncate_simplex (j - 1) ul):real^3` (fun th -> REWRITE_TAC[th]) THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC (GSYM HD_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC HD_TRUNCATE_SIMPLEX THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_CASES_TAC `i < j:num` THENL [ SUBGOAL_THEN `truncate_simplex i vl:(real^3)list = truncate_simplex i ul` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL [`ul:(real^3)list`; `i:num`; `j - 1`] TRUNCATE_TRUNCATE_SIMPLEX) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC (GSYM TRUNCATE_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN MATCH_MP_TAC (REAL_ARITH `a < b ==> ~(b = a:real)`) THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`] XNHPWAB4) THEN ASM_REWRITE_TAC[IN] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_LT; LE_LT] THEN DISCH_THEN DISJ_CASES_TAC THENL [ MATCH_MP_TAC (REAL_ARITH `a < b ==> ~(a = b:real)`) THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (truncate_simplex j vl:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPECL [`V:real^3->bool`; `vl:(real^3)list`; `k:num`] XNHPWAB4) THEN ASM_REWRITE_TAC[IN] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN UNDISCH_TAC `omega_list_n V ul j = omega_list_n V vl i` THEN POP_ASSUM (fun th -> ASM_REWRITE_TAC[SYM th]));;
let AFFINE_INDEPENDENT_OMEGA_LIST_N = 
prove(`!V ul k. packing V /\ barV V k ul /\ hl ul < sqrt (&2) ==> ~affine_dependent {omega_list_n V ul i | i <= k}`,
REPEAT GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[AFFINE_INDEPENDENT_IFF_CARD] THEN ABBREV_TAC `A = {omega_list_n V ul i | i <= k}` THEN SUBGOAL_THEN `FINITE (A:real^3->bool) /\ CARD A <= k + 1` ASSUME_TAC THENL [ EXPAND_TAC "A" THEN SUBGOAL_THEN `!i. i <= k <=> i IN 0..k` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[IN_NUMSEG; LE_0]; ALL_TAC ] THEN ONCE_REWRITE_TAC[GSYM IMAGE_LEMMA] THEN CONJ_TAC THENL [ MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG]; ALL_TAC ] THEN MP_TAC (ISPECL [`\i. omega_list_n V ul i`; `0..k`] CARD_IMAGE_LE) THEN REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG; ARITH_RULE `(k + 1) - 0 = k + 1`]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `k:num`] XNHPWAB3) THEN ASM_REWRITE_TAC[IN_NUMSEG; IN; LE_0] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN MP_TAC (ISPEC `A:real^3->bool` AFF_DIM_LE_CARD) THEN ASM_REWRITE_TAC[] THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_ADD] THEN INT_ARITH_TAC);;
let ROGERS_EQ = 
prove(`!V ul vl k. packing V /\ barV V k ul /\ barV V k vl /\ hl ul < sqrt (&2) /\ hl vl < sqrt (&2) ==> (rogers V ul = rogers V vl <=> {omega_list_n V ul i | i <= k} = {omega_list_n V vl i | i <= k})`,
REPEAT STRIP_TAC THEN REWRITE_TAC[ROGERS; IMAGE_LEMMA; IN_ELIM_THM] THEN SUBGOAL_THEN `LENGTH (ul:(real^3)list) = k + 1 /\ LENGTH (vl:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k ul` THEN UNDISCH_TAC `barV V k vl` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN ASM_REWRITE_TAC[ARITH_RULE `x < k + 1 <=> x <= k`] THEN MATCH_MP_TAC CONVEX_HULL_EQ_EQ_SET_EQ THEN ASM_SIMP_TAC[AFFINE_INDEPENDENT_OMEGA_LIST_N]);;
let NUM_FINITE_IMP_MAX_EXISTS = 
prove(`!K:num->bool. FINITE K /\ ~(K = {}) ==> ?m. m IN K /\ (!j. j IN K ==> j <= m)`,
REWRITE_TAC[GSYM IMP_IMP] THEN MATCH_MP_TAC FINITE_INDUCT THEN REWRITE_TAC[NOT_INSERT_EMPTY] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_CASES_TAC `s:num->bool = {}` THEN ASM_REWRITE_TAC[] THENL [ ASM_REWRITE_TAC[IN_SING] THEN EXISTS_TAC `x:num` THEN SIMP_TAC[LE_REFL]; ALL_TAC ] THEN STRIP_TAC THEN ASM_CASES_TAC `m <= x:num` THENL [ EXISTS_TAC `x:num` THEN REWRITE_TAC[IN_INSERT] THEN GEN_TAC THEN ASM_CASES_TAC `j = x:num` THEN ASM_REWRITE_TAC[LE_REFL] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `m <= x:num` THEN ARITH_TAC; ALL_TAC ] THEN EXISTS_TAC `m:num` THEN ASM_REWRITE_TAC[IN_INSERT] THEN GEN_TAC THEN ASM_CASES_TAC `j = x:num` THENL [ ASM_REWRITE_TAC[] THEN UNDISCH_TAC `~(m <= x:num)` THEN ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[]);;
let NOT_ID_IMP_LISTS_NOT_EQ = 
prove(`!ul:(A)list p k. LENGTH ul = k + 1 /\ CARD (set_of_list ul) = k + 1 /\ p permutes (0..k) /\ ~(p = I) ==> ~(ul = left_action_list p ul)`,
REPEAT STRIP_TAC THEN SUBGOAL_THEN `?j:num. j < k + 1 /\ ~(p j = j)` CHOOSE_TAC THENL [ UNDISCH_TAC `~(p = I:num->num)` THEN REWRITE_TAC[FUN_EQ_THM; I_THM; NOT_FORALL_THM] THEN STRIP_TAC THEN EXISTS_TAC `x:num` THEN ASM_REWRITE_TAC[] THEN DISJ_CASES_TAC (ARITH_RULE `x < k + 1 \/ k < x:num`) THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `p permutes 0..k` THEN REWRITE_TAC[permutes] THEN DISCH_THEN (CONJUNCTS_THEN2 (MP_TAC o SPEC `x:num`) (fun th -> ALL_TAC)) THEN ASM_REWRITE_TAC[IN_NUMSEG; LE_0] THEN ARITH_TAC; ALL_TAC ] THEN UNDISCH_TAC `ul:(A)list = left_action_list p ul` THEN DISCH_THEN (MP_TAC o AP_TERM `\l:(A)list. EL ((p:num->num) j) l`) THEN MP_TAC (SPECL [`ul:(A)list`; `p:num->num`; `j:num`] EL_LEFT_ACTION_LIST) THEN ASM_REWRITE_TAC[ARITH_RULE `(k + 1) - 1 = k`] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MP_TAC (SPEC `ul:(A)list` CARD_SET_OF_LIST_EQ_LENGTH_IMP_ALL_DISTINCT) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN MP_TAC (ISPECL [`p:num->num`; `0..k`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN DISCH_THEN (MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[LE_0; ARITH_RULE `a <= b <=> a < b + 1`]);;
let NOT_ID_IMP_EXISTS_MAX_EQ_TRUNCATE_SIMPLEX = 
prove(`!ul:(A)list p k. LENGTH ul = k + 1 /\ CARD (set_of_list ul) = k + 1 /\ p permutes (0..k) /\ ~(p = I) ==> ~(HD ul = HD (left_action_list p ul)) \/ ?j. j < k /\ truncate_simplex j ul = truncate_simplex j (left_action_list p ul) /\ ~(EL (j + 1) ul = EL (j + 1) (left_action_list p ul))`,
REPEAT STRIP_TAC THEN ABBREV_TAC `vl:(A)list = left_action_list p ul` THEN SUBGOAL_THEN `LENGTH (vl:(A)list) = k + 1` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST]; ALL_TAC ] THEN ASM_CASES_TAC `HD ul = HD vl:A` THEN ASM_REWRITE_TAC[] THEN ABBREV_TAC `K = {j | j <= k /\ truncate_simplex j (ul:(A)list) = truncate_simplex j vl}` THEN SUBGOAL_THEN `?i:num. i IN K /\ (!j. j IN K ==> j <= i)` STRIP_ASSUME_TAC THENL [ MATCH_MP_TAC NUM_FINITE_IMP_MAX_EXISTS THEN EXPAND_TAC "K" THEN CONJ_TAC THENL [ MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{j | j <= k:num}` THEN CONJ_TAC THENL [ SUBGOAL_THEN `!j. j <= k <=> j IN 0..k` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[IN_NUMSEG; LE_0]; ALL_TAC ] THEN REWRITE_TAC[GSYM IMAGE_LEMMA] THEN MATCH_MP_TAC FINITE_IMAGE THEN REWRITE_TAC[FINITE_NUMSEG]; ALL_TAC ] THEN SIMP_TAC[SUBSET; IN_ELIM_THM]; ALL_TAC ] THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `0` THEN REWRITE_TAC[IN_ELIM_THM; LE_0] THEN MP_TAC (SPEC `ul:(A)list` TRUNCATE_0_EQ_HEAD) THEN MP_TAC (SPEC `vl:(A)list` TRUNCATE_0_EQ_HEAD) THEN ASM_SIMP_TAC[ARITH_RULE `1 <= k + 1`]; ALL_TAC ] THEN EXISTS_TAC `i:num` THEN SUBGOAL_THEN `i < k:num` ASSUME_TAC THENL [ REWRITE_TAC[LT_LE] THEN CONJ_TAC THENL [ UNDISCH_TAC `i:num IN K` THEN EXPAND_TAC "K" THEN SIMP_TAC[IN_ELIM_THM]; ALL_TAC ] THEN DISCH_TAC THEN UNDISCH_TAC `i:num IN K` THEN EXPAND_TAC "K" THEN ASM_REWRITE_TAC[IN_ELIM_THM; LE_REFL] THEN MP_TAC (SPECL [`k:num`; `ul:(A)list`; `ul:(A)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN MP_TAC (SPECL [`k:num`; `vl:(A)list`; `vl:(A)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[LE_REFL; INITIAL_SUBLIST_REFL] THEN REPLICATE_TAC 2 (DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th])) THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC NOT_ID_IMP_LISTS_NOT_EQ THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `truncate_simplex i ul = truncate_simplex i vl:(A)list` ASSUME_TAC THENL [ UNDISCH_TAC `i:num IN K` THEN EXPAND_TAC "K" THEN SIMP_TAC[IN_ELIM_THM]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN `i + 1 IN K` ASSUME_TAC THENL [ EXPAND_TAC "K" THEN REWRITE_TAC[IN_ELIM_THM] THEN ASM_SIMP_TAC[ARITH_RULE `i < k ==> i + 1 <= k`] THEN MP_TAC (ARITH_RULE `i < k ==> i + 2 <= k + 1`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[TRUNCATE_SIMPLEX_ADD1_ALT]; ALL_TAC ] THEN FIRST_X_ASSUM (MP_TAC o SPEC `i + 1`) THEN ASM_REWRITE_TAC[ARITH_RULE `~(i + 1 <= i)`]);;
(* KSOQKWL *)
let KSOQKWL = 
prove(`!V ul p k. packing V /\ ul IN barV V k /\ hl ul < sqrt(&2) /\ p permutes (0..k) /\ (rogers V ul = rogers V (left_action_list p ul)) ==> (p = I)`,
REWRITE_TAC[IN] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN ABBREV_TAC `vl:(real^3)list = left_action_list p ul` THEN SUBGOAL_THEN `barV V k vl` ASSUME_TAC THENL [ EXPAND_TAC "vl" THEN MP_TAC (SPEC_ALL YIFVQDV) THEN ASM_SIMP_TAC[IN]; ALL_TAC ] THEN MP_TAC (SPEC_ALL BARV_IMP_LENGTH_EQ_CARD) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN SUBGOAL_THEN `hl (vl:(real^3)list) < sqrt (&2)` ASSUME_TAC THENL [ SUBGOAL_THEN `hl (vl:(real^3)list) = hl (ul:(real^3)list)` (fun th -> ASM_REWRITE_TAC[th]) THEN REWRITE_TAC[HL] THEN AP_TERM_TAC THEN EXPAND_TAC "vl" THEN MATCH_MP_TAC SET_OF_LIST_LEFT_ACTION_LIST THEN UNDISCH_TAC `barV V k ul` THEN SIMP_TAC[BARV] THEN ASM_REWRITE_TAC[ARITH_RULE `(k + 1) - 1 = k`]; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (vl:(real^3)list) = k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `barV V k vl` THEN SIMP_TAC[BARV]; ALL_TAC ] THEN ASM_SIMP_TAC[ROGERS_EQ] THEN MP_TAC (ISPECL [`ul:(real^3)list`; `p:num->num`; `k:num`] NOT_ID_IMP_EXISTS_MAX_EQ_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `~(HD ul = HD vl:real^3)` THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC KSOQKWL_lemma0 THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN SUBGOAL_THEN `~(omega_list_n V ul (j + 1) = omega_list_n V vl (j + 1))` ASSUME_TAC THENL [ DISCH_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `ul:(real^3)list`; `j + 1`] HL_TRUNCATE_SIMPLEX_OMEGA_N) THEN MP_TAC (SPECL [`V:real^3->bool`; `k:num`; `vl:(real^3)list`; `j + 1`] HL_TRUNCATE_SIMPLEX_OMEGA_N) THEN MP_TAC (ARITH_RULE `j < k ==> j + 1 <= k`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ABBREV_TAC `S = set_of_list (truncate_simplex (j + 1) ul:(real^3)list)` THEN ABBREV_TAC `c:real^3 = circumcenter S` THEN MP_TAC (SPECL [`V:real^3->bool`; `S:real^3->bool`; `c:real^3`] XYOFCGX) THEN SUBGOAL_THEN `barV V (j + 1) (truncate_simplex (j + 1) ul)` ASSUME_TAC THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `~affine_dependent (S:real^3->bool)` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `j + 1`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `S SUBSET V:real^3->bool` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `j + 1` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "S" THEN REWRITE_TAC[GSYM HL] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN ABBREV_TAC `x = EL (j + 1) ul:real^3` THEN ABBREV_TAC `y = EL (j + 1) vl:real^3` THEN DISCH_THEN (MP_TAC o SPECL [`x:real^3`; `y:real^3`]) THEN ABBREV_TAC `xl:(real^3)list = truncate_simplex (j + 1) ul` THEN ABBREV_TAC `yl:(real^3)list = truncate_simplex (j + 1) vl` THEN SUBGOAL_THEN `barV V (j + 1) yl` ASSUME_TAC THENL [ EXPAND_TAC "yl" THEN MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MP_TAC (SPECL [`V:real^3->bool`; `xl:(real^3)list`; `j + 1`] BARV_IMP_LENGTH_EQ_CARD) THEN MP_TAC (SPECL [`V:real^3->bool`; `yl:(real^3)list`; `j + 1`] BARV_IMP_LENGTH_EQ_CARD) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISCH_TAC THEN MP_TAC (ARITH_RULE `j + 1 <= k ==> (j + 1) + 1 <= k + 1`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN `!n. n < (j + 1) + 1 ==> (EL n xl):real^3 = if (n = j + 1) then x else EL n (truncate_simplex j vl)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`ul:(real^3)list`; `j + 1`] EL_TRUNCATE_SIMPLEX) THEN MP_TAC (ISPECL [`ul:(real^3)list`; `j:num`] EL_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[] THEN COND_CASES_TAC THENL [ DISCH_TAC THEN DISCH_THEN (MP_TAC o SPEC `j + 1`) THEN ASM_REWRITE_TAC[LE_REFL]; ALL_TAC ] THEN DISCH_TAC THEN DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC `n:num`) THEN POP_ASSUM (MP_TAC o SPEC `n:num`) THEN ASM_SIMP_TAC[ARITH_RULE `j + 1 <= k ==> j + 1 <= k + 1`; ARITH_RULE `n < (j + 1) + 1 /\ ~(n = j + 1) ==> n <= j /\ n <= j + 1`]; ALL_TAC ] THEN SUBGOAL_THEN `!n. n < (j + 1) + 1 ==> (EL n yl):real^3 = if (n = j + 1) then y else EL n (truncate_simplex j vl)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`vl:(real^3)list`; `j + 1`] EL_TRUNCATE_SIMPLEX) THEN MP_TAC (ISPECL [`vl:(real^3)list`; `j:num`] EL_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[] THEN COND_CASES_TAC THENL [ DISCH_TAC THEN DISCH_THEN (MP_TAC o SPEC `j + 1`) THEN ASM_REWRITE_TAC[LE_REFL]; ALL_TAC ] THEN DISCH_TAC THEN DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC `n:num`) THEN POP_ASSUM (MP_TAC o SPEC `n:num`) THEN ASM_SIMP_TAC[ARITH_RULE `j + 1 <= k ==> j + 1 <= k + 1`; ARITH_RULE `n < (j + 1) + 1 /\ ~(n = j + 1) ==> n <= j /\ n <= j + 1`]; ALL_TAC ] THEN SUBGOAL_THEN `x:real^3 IN S` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN REWRITE_TAC[IN_SET_OF_LIST] THEN REMOVE_ASSUM THEN POP_ASSUM (MP_TAC o SPEC `j + 1`) THEN REWRITE_TAC[ARITH_RULE `j + 1 < (j + 1) + 1`] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MATCH_MP_TAC MEM_EL THEN ASM_REWRITE_TAC[ARITH_RULE `j + 1 < (j + 1) + 1`]; ALL_TAC ] THEN SUBGOAL_THEN `y:real^3 IN (set_of_list yl) DIFF S` ASSUME_TAC THENL [ EXPAND_TAC "S" THEN REWRITE_TAC[IN_DIFF; IN_SET_OF_LIST; MEM_EXISTS_EL] THEN CONJ_TAC THENL [ EXISTS_TAC `j + 1` THEN ASM_SIMP_TAC[ARITH_RULE `j + 1 < (j + 1) + 1`]; ALL_TAC ] THEN REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(A /\ B) <=> (A ==> ~B)`] THEN GEN_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC `j + 1:num`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `i:num`) THEN FIRST_X_ASSUM (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN COND_CASES_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[ARITH_RULE `j + 1 < (j + 1) + 1`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MP_TAC (ISPECL [`yl:(real^3)list`] CARD_SET_OF_LIST_EQ_LENGTH_IMP_ALL_DISTINCT) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `(set_of_list yl:real^3->bool) DIFF S` THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `set_of_list yl:real^3->bool SUBSET V` MP_TAC THENL [ MATCH_MP_TAC BARV_SUBSET THEN EXISTS_TAC `j + 1` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SIMP_TAC[SUBSET; IN_DIFF]; ALL_TAC ] THEN SUBGOAL_THEN `omega_list_n V ul (j + 1) = c:real^3` ASSUME_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `xl:(real^3)list`; `j + 1`] XNHPWAB1) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[IN] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (ul:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "xl" THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN EXPAND_TAC "c" THEN EXPAND_TAC "S" THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN EXPAND_TAC "xl" THEN MATCH_MP_TAC (GSYM OMEGA_LIST_LEMMA) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `hl (xl:(real^3)list) = dist (x:real^3,c)` (fun th -> REWRITE_TAC[SYM th]) THENL [ ASM_REWRITE_TAC[HL] THEN MP_TAC (ISPEC `S:real^3->bool` OAPVION2) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `x:real^3`) THEN ASM_REWRITE_TAC[DIST_SYM]; ALL_TAC ] THEN SUBGOAL_THEN `hl (yl:(real^3)list) = dist (y:real^3,c)` (fun th -> REWRITE_TAC[SYM th]) THENL [ ASM_REWRITE_TAC[HL] THEN MP_TAC (SPECL [`V:real^3->bool`; `yl:(real^3)list`; `j + 1`] XNHPWAB1) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[IN] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (vl:(real^3)list)` THEN ASM_REWRITE_TAC[] THEN EXPAND_TAC "yl" THEN MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `k:num`] THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN DISCH_THEN (ASSUME_TAC o SYM) THEN MP_TAC (ISPEC `set_of_list yl:real^3->bool` OAPVION2) THEN ANTS_TAC THENL [ MATCH_MP_TAC BARV_AFFINE_INDEPENDENT THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `j + 1`] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o SPEC `y:real^3`) THEN ANTS_TAC THENL [ UNDISCH_TAC `y:real^3 IN set_of_list yl DIFF S` THEN SIMP_TAC[IN_DIFF]; ALL_TAC ] THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[th]) THEN SUBGOAL_THEN `omega_list V yl = omega_list_n V ul (j + 1)` (fun th -> REWRITE_TAC[th]) THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "yl" THEN MATCH_MP_TAC OMEGA_LIST_LEMMA THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN REMOVE_ASSUM THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[DIST_SYM]; ALL_TAC ] THEN REAL_ARITH_TAC; ALL_TAC ] THEN ASM_CASES_TAC `hl (truncate_simplex (j + 1) ul:(real^3)list) <= hl (truncate_simplex (j + 1) vl:(real^3)list)` THENL [ MATCH_MP_TAC KSOQKWL_lemma1 THEN EXISTS_TAC `j + 1` THEN ASM_REWRITE_TAC[ARITH_RULE `0 < j + 1`; ARITH_RULE `j + 1 <= k <=> j < k`; ARITH_RULE `(j + 1) - 1 = j`]; ALL_TAC ] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[REAL_NOT_LE; REAL_LT_LE] THEN DISCH_TAC THEN MATCH_MP_TAC (GSYM KSOQKWL_lemma1) THEN EXISTS_TAC `j + 1` THEN ASM_REWRITE_TAC[ARITH_RULE `0 < j + 1`; ARITH_RULE `j + 1 <= k <=> j < k`; ARITH_RULE `(j + 1) - 1 = j`]);;
(*****************************************************) (***********) (* IVFICRK *) (***********)
let IVFICRK = 
prove(`!k. ?g. (BIJ g { (i,sigma ) | i IN 0..(k+1) /\ sigma permutes (0..k) } { p | p permutes (0..(k+1)) }) /\ (!(ul:(A)list) i sigma j. (LENGTH ul = k+2) /\ j <= k /\ i IN 0..(k+1) /\ sigma permutes (0..k) ==> (EL j ( left_action_list (g(i,sigma)) ul) = EL j (left_action_list sigma (DROP ul i) )))`,
GEN_TAC THEN ABBREV_TAC `f = (\i j. if j = k + 1 then i else (if (i <= j /\ j < k + 1) then j + 1 else j))` THEN ABBREV_TAC `fi = (\i j. if j = i then k + 1 else (if (i < j /\ j <= k + 1) then j - 1 else j))` THEN SUBGOAL_THEN `!i. i <= k + 1 ==> (f:num->num->num) i o fi i = I:num->num /\ fi i o f i = I` ASSUME_TAC THENL [ REWRITE_TAC[IN_NUMSEG; FUN_EQ_THM; I_THM; o_THM] THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "fi" THEN COND_CASES_TAC THENL [ EXPAND_TAC "f" THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN COND_CASES_TAC THENL [ EXPAND_TAC "f" THEN ASM_SIMP_TAC[ARITH_RULE `x <= k + 1 ==> ~(x - 1 = k + 1)`] THEN MP_TAC (ARITH_RULE `i < x /\ x <= k + 1 ==> i <= x - 1 /\ x - 1 < k + 1`) THEN ASM_SIMP_TAC[] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN EXPAND_TAC "f" THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM; NOT_LT; NOT_LE] THEN DISCH_THEN DISJ_CASES_TAC THENL [ MP_TAC (ARITH_RULE `x <= i /\ ~(x = i) /\ i <= k + 1 ==> ~(x = k + 1)`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN MP_TAC (ARITH_RULE `x <= i /\ i <= x ==> x = i:num`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[ARITH_RULE `k + 1 < x ==> ~(x = k + 1) /\ ~(x < k + 1)`]; ALL_TAC ] THEN EXPAND_TAC "f" THEN COND_CASES_TAC THENL [ EXPAND_TAC "fi" THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN COND_CASES_TAC THENL [ EXPAND_TAC "fi" THEN ASM_SIMP_TAC[ARITH_RULE `i <= x ==> ~(x + 1 = i)`] THEN MP_TAC (ARITH_RULE `i <= x /\ x < k + 1 ==> i < x + 1 /\ x + 1 <= k + 1`) THEN ASM_SIMP_TAC[ARITH_RULE `(x + 1) - 1 = x`]; ALL_TAC ] THEN EXPAND_TAC "fi" THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM; NOT_LE; NOT_LT] THEN DISCH_THEN DISJ_CASES_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `x < i ==> ~(x = i:num) /\ ~(i < x)`]; ALL_TAC ] THEN MP_TAC (ARITH_RULE `k + 1 <= x /\ ~(x = k + 1) ==> ~(x <= k + 1)`) THEN ASM_SIMP_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!i j. i <= k + 1 ==> (f:num->num->num) i (fi i j) = j /\ fi i (f i j) = j` ASSUME_TAC THENL [ GEN_TAC THEN GEN_TAC THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN DISCH_THEN (CONJUNCTS_THEN (ASSUME_TAC o SPEC `j:num`)) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!i. i <= k + 1 ==> f i permutes (0..k+1) /\ fi i permutes (0..k+1)` ASSUME_TAC THENL [ GEN_TAC THEN DISCH_TAC THEN SUBGOAL_THEN `(f:num->num->num) i permutes (0..k+1)` ASSUME_TAC THENL [ REWRITE_TAC[permutes; IN_NUMSEG; DE_MORGAN_THM; NOT_LE; ARITH_RULE `~(x < 0)`] THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "f" THEN ASM_SIMP_TAC[ARITH_RULE `k + 1 < x ==> ~(x = k + 1) /\ ~(x < k + 1)`]; ALL_TAC ] THEN REWRITE_TAC[EXISTS_UNIQUE] THEN EXISTS_TAC `(fi:num->num->num) i y` THEN CONJ_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC ] THEN GEN_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC Hypermap_and_fan.INVERSE_PERMUTES THEN EXISTS_TAC `(f:num->num->num) i` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ABBREV_TAC `g = \(i:num,sigma:num->num). sigma o (fi:num->num->num) i` THEN EXISTS_TAC `g:(num#(num->num))->num->num` THEN SUBGOAL_THEN `!i sigma. i <= k + 1 /\ sigma permutes 0..k ==> g (i,sigma) permutes (0..k+1)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN MATCH_MP_TAC PERMUTES_COMPOSE THEN ASM_SIMP_TAC[] THEN MATCH_MP_TAC PERMUTES_SUBSET THEN EXISTS_TAC `0..k` THEN ASM_REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `!i sigma. i <= k + 1 /\ sigma permutes 0..k ==> inverse (g (i,sigma)) (k + 1) = i` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN SUBGOAL_THEN `g (i:num, sigma:num->num) i = k + 1` MP_TAC THENL [ EXPAND_TAC "g" THEN REWRITE_TAC[o_THM] THEN EXPAND_TAC "fi" THEN REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[permutes; IN_NUMSEG; DE_MORGAN_THM; NOT_LE; ARITH_RULE `~(x < 0)`] THEN DISCH_THEN (CONJUNCTS_THEN2 (MP_TAC o SPEC `k + 1`) (fun th -> ALL_TAC)) THEN SIMP_TAC[ARITH_RULE `k < k + 1`]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o AP_TERM `\x:num. (inverse (g (i:num, sigma:num->num)) x):num`) THEN BETA_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MP_TAC (ISPECL [`(g (i:num, sigma:num->num)):num->num`; `0..k+1`] PERMUTES_INVERSES) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN CONJ_TAC THENL [ REWRITE_TAC[BIJ; INJ; SURJ; IN_ELIM_THM; IN_NUMSEG; ARITH_RULE `0 <= i`] THEN REPEAT STRIP_TAC THENL [ ASM_SIMP_TAC[]; ASM_REWRITE_TAC[PAIR_EQ] THEN FIRST_ASSUM (MP_TAC o SPECL [`i:num`; `sigma:num->num`]) THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i':num`; `sigma':num->num`]) THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP] THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o AP_TERM `(\x:num->num. x o (f:num->num->num) i)`) THEN ASM_SIMP_TAC[GSYM o_ASSOC; I_O_ID]; ASM_SIMP_TAC[]; ABBREV_TAC `r = inverse (x:num->num) (k + 1)` THEN EXISTS_TAC `r:num, (x:num->num) o (f:num->num->num) r` THEN SUBGOAL_THEN `r <= k + 1` ASSUME_TAC THENL [ MP_TAC (ISPECL [`x:num->num`; `0..k+1`] PERMUTES_INVERSE) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`inverse (x:num->num)`; `0..k+1`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `k + 1`) THEN ASM_REWRITE_TAC[IN_NUMSEG; LE_0; LE_REFL]; ALL_TAC ] THEN CONJ_TAC THENL [ EXISTS_TAC `r:num` THEN EXISTS_TAC `(x:num->num) o (f:num->num->num) r` THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `(x:num->num) o (f:num->num->num) r permutes 0..k+1` MP_TAC THENL [ MATCH_MP_TAC PERMUTES_COMPOSE THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN SIMP_TAC[permutes; IN_NUMSEG; DE_MORGAN_THM; NOT_LE; ARITH_RULE `~(x < 0)`] THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC (fun th -> ALL_TAC)) THEN X_GEN_TAC `j:num` THEN ONCE_REWRITE_TAC[ARITH_RULE `k < j <=> j = k + 1 \/ k + 1 < j`] THEN DISCH_THEN DISJ_CASES_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "r" THEN REWRITE_TAC[o_THM] THEN EXPAND_TAC "f" THEN REWRITE_TAC[] THEN MP_TAC (ISPECL [`x:num->num`; `0..k+1`] PERMUTES_INVERSES) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN EXPAND_TAC "g" THEN REWRITE_TAC[GSYM o_ASSOC] THEN ASM_SIMP_TAC[I_O_ID] ]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `j < k + 2 /\ j < k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `j <= k:num` THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `i < k + 2` ASSUME_TAC THENL [ UNDISCH_TAC `i IN 0..k+1` THEN REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (DROP (ul:(A)list) i) = k + 1` ASSUME_TAC THENL [ MP_TAC (SPECL [`i:num`; `ul:(A)list`] LENGTH_DROP) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[left_action_list; EL_TABLE] THEN ABBREV_TAC `r = inverse (sigma:num->num) j` THEN MP_TAC (SPECL [`i:num`; `r:num`; `ul:(A)list`] EL_DROP) THEN SUBGOAL_THEN `r <= k:num` ASSUME_TAC THENL [ MP_TAC (ISPECL [`sigma:num->num`; `0..k`] PERMUTES_INVERSE) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`inverse (sigma:num->num)`; `0..k`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[IN_NUMSEG; LE_0]; ALL_TAC ] THEN ASM_REWRITE_TAC[ARITH_RULE `r < (k + 2) - 1 <=> r <= k`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN SUBGOAL_THEN `inverse ((sigma:num->num) o (fi:num->num->num) i) = (f:num->num->num) i o inverse sigma` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC INVERSE_UNIQUE_o THEN SUBGOAL_THEN `!a:num->num b:num->num c:num->num d:num->num. (a o b) o c o d = a o (b o c) o d` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[o_ASSOC]; ALL_TAC ] THEN UNDISCH_TAC `!i. i <= k + 1 ==> (f:num->num->num) i o fi i = I /\ fi i o f i = I` THEN DISCH_THEN (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[ARITH_RULE `i <= k + 1 <=> i < k + 2`] THEN DISCH_TAC THEN MP_TAC (ISPECL [`sigma:num->num`; `0..k`] PERMUTES_INVERSES_o) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[I_O_ID]; ALL_TAC ] THEN ASM_REWRITE_TAC[o_THM] THEN EXPAND_TAC "f" THEN ASM_SIMP_TAC[ARITH_RULE `r <= k ==> ~(r = k + 1) /\ r < k + 1`] THEN ONCE_REWRITE_TAC[GSYM NOT_LE] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[]);;
(* COPY *)
let IVFICRK_real3 = 
prove(`!k. ?g. (BIJ g { (i,sigma ) | i IN 0..(k+1) /\ sigma permutes (0..k) } { p | p permutes (0..(k+1)) }) /\ (!(ul:(real^3)list) i sigma j. (LENGTH ul = k+2) /\ j <= k /\ i IN 0..(k+1) /\ sigma permutes (0..k) ==> (EL j ( left_action_list (g(i,sigma)) ul) = EL j (left_action_list sigma (DROP ul i) )))`,
GEN_TAC THEN ABBREV_TAC `f = (\i j. if j = k + 1 then i else (if (i <= j /\ j < k + 1) then j + 1 else j))` THEN ABBREV_TAC `fi = (\i j. if j = i then k + 1 else (if (i < j /\ j <= k + 1) then j - 1 else j))` THEN SUBGOAL_THEN `!i. i <= k + 1 ==> (f:num->num->num) i o fi i = I:num->num /\ fi i o f i = I` ASSUME_TAC THENL [ REWRITE_TAC[IN_NUMSEG; FUN_EQ_THM; I_THM; o_THM] THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "fi" THEN COND_CASES_TAC THENL [ EXPAND_TAC "f" THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN COND_CASES_TAC THENL [ EXPAND_TAC "f" THEN ASM_SIMP_TAC[ARITH_RULE `x <= k + 1 ==> ~(x - 1 = k + 1)`] THEN MP_TAC (ARITH_RULE `i < x /\ x <= k + 1 ==> i <= x - 1 /\ x - 1 < k + 1`) THEN ASM_SIMP_TAC[] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN EXPAND_TAC "f" THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM; NOT_LT; NOT_LE] THEN DISCH_THEN DISJ_CASES_TAC THENL [ MP_TAC (ARITH_RULE `x <= i /\ ~(x = i) /\ i <= k + 1 ==> ~(x = k + 1)`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN MP_TAC (ARITH_RULE `x <= i /\ i <= x ==> x = i:num`) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[ARITH_RULE `k + 1 < x ==> ~(x = k + 1) /\ ~(x < k + 1)`]; ALL_TAC ] THEN EXPAND_TAC "f" THEN COND_CASES_TAC THENL [ EXPAND_TAC "fi" THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN COND_CASES_TAC THENL [ EXPAND_TAC "fi" THEN ASM_SIMP_TAC[ARITH_RULE `i <= x ==> ~(x + 1 = i)`] THEN MP_TAC (ARITH_RULE `i <= x /\ x < k + 1 ==> i < x + 1 /\ x + 1 <= k + 1`) THEN ASM_SIMP_TAC[ARITH_RULE `(x + 1) - 1 = x`]; ALL_TAC ] THEN EXPAND_TAC "fi" THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM; NOT_LE; NOT_LT] THEN DISCH_THEN DISJ_CASES_TAC THENL [ ASM_SIMP_TAC[ARITH_RULE `x < i ==> ~(x = i:num) /\ ~(i < x)`]; ALL_TAC ] THEN MP_TAC (ARITH_RULE `k + 1 <= x /\ ~(x = k + 1) ==> ~(x <= k + 1)`) THEN ASM_SIMP_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!i j. i <= k + 1 ==> (f:num->num->num) i (fi i j) = j /\ fi i (f i j) = j` ASSUME_TAC THENL [ GEN_TAC THEN GEN_TAC THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN DISCH_THEN (CONJUNCTS_THEN (ASSUME_TAC o SPEC `j:num`)) THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!i. i <= k + 1 ==> f i permutes (0..k+1) /\ fi i permutes (0..k+1)` ASSUME_TAC THENL [ GEN_TAC THEN DISCH_TAC THEN SUBGOAL_THEN `(f:num->num->num) i permutes (0..k+1)` ASSUME_TAC THENL [ REWRITE_TAC[permutes; IN_NUMSEG; DE_MORGAN_THM; NOT_LE; ARITH_RULE `~(x < 0)`] THEN REPEAT STRIP_TAC THENL [ EXPAND_TAC "f" THEN ASM_SIMP_TAC[ARITH_RULE `k + 1 < x ==> ~(x = k + 1) /\ ~(x < k + 1)`]; ALL_TAC ] THEN REWRITE_TAC[EXISTS_UNIQUE] THEN EXISTS_TAC `(fi:num->num->num) i y` THEN CONJ_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC ] THEN GEN_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC Hypermap_and_fan.INVERSE_PERMUTES THEN EXISTS_TAC `(f:num->num->num) i` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ABBREV_TAC `g = \(i:num,sigma:num->num). sigma o (fi:num->num->num) i` THEN EXISTS_TAC `g:(num#(num->num))->num->num` THEN SUBGOAL_THEN `!i sigma. i <= k + 1 /\ sigma permutes 0..k ==> g (i,sigma) permutes (0..k+1)` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN MATCH_MP_TAC PERMUTES_COMPOSE THEN ASM_SIMP_TAC[] THEN MATCH_MP_TAC PERMUTES_SUBSET THEN EXISTS_TAC `0..k` THEN ASM_REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `!i sigma. i <= k + 1 /\ sigma permutes 0..k ==> inverse (g (i,sigma)) (k + 1) = i` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN SUBGOAL_THEN `g (i:num, sigma:num->num) i = k + 1` MP_TAC THENL [ EXPAND_TAC "g" THEN REWRITE_TAC[o_THM] THEN EXPAND_TAC "fi" THEN REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[permutes; IN_NUMSEG; DE_MORGAN_THM; NOT_LE; ARITH_RULE `~(x < 0)`] THEN DISCH_THEN (CONJUNCTS_THEN2 (MP_TAC o SPEC `k + 1`) (fun th -> ALL_TAC)) THEN SIMP_TAC[ARITH_RULE `k < k + 1`]; ALL_TAC ] THEN DISCH_THEN (MP_TAC o AP_TERM `\x:num. (inverse (g (i:num, sigma:num->num)) x):num`) THEN BETA_TAC THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN MP_TAC (ISPECL [`(g (i:num, sigma:num->num)):num->num`; `0..k+1`] PERMUTES_INVERSES) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN CONJ_TAC THENL [ REWRITE_TAC[BIJ; INJ; SURJ; IN_ELIM_THM; IN_NUMSEG; ARITH_RULE `0 <= i`] THEN REPEAT STRIP_TAC THENL [ ASM_SIMP_TAC[]; ASM_REWRITE_TAC[PAIR_EQ] THEN FIRST_ASSUM (MP_TAC o SPECL [`i:num`; `sigma:num->num`]) THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i':num`; `sigma':num->num`]) THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP] THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o AP_TERM `(\x:num->num. x o (f:num->num->num) i)`) THEN ASM_SIMP_TAC[GSYM o_ASSOC; I_O_ID]; ASM_SIMP_TAC[]; ABBREV_TAC `r = inverse (x:num->num) (k + 1)` THEN EXISTS_TAC `r:num, (x:num->num) o (f:num->num->num) r` THEN SUBGOAL_THEN `r <= k + 1` ASSUME_TAC THENL [ MP_TAC (ISPECL [`x:num->num`; `0..k+1`] PERMUTES_INVERSE) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`inverse (x:num->num)`; `0..k+1`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `k + 1`) THEN ASM_REWRITE_TAC[IN_NUMSEG; LE_0; LE_REFL]; ALL_TAC ] THEN CONJ_TAC THENL [ EXISTS_TAC `r:num` THEN EXISTS_TAC `(x:num->num) o (f:num->num->num) r` THEN ASM_REWRITE_TAC[] THEN SUBGOAL_THEN `(x:num->num) o (f:num->num->num) r permutes 0..k+1` MP_TAC THENL [ MATCH_MP_TAC PERMUTES_COMPOSE THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN SIMP_TAC[permutes; IN_NUMSEG; DE_MORGAN_THM; NOT_LE; ARITH_RULE `~(x < 0)`] THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC (fun th -> ALL_TAC)) THEN X_GEN_TAC `j:num` THEN ONCE_REWRITE_TAC[ARITH_RULE `k < j <=> j = k + 1 \/ k + 1 < j`] THEN DISCH_THEN DISJ_CASES_TAC THENL [ ASM_REWRITE_TAC[] THEN EXPAND_TAC "r" THEN REWRITE_TAC[o_THM] THEN EXPAND_TAC "f" THEN REWRITE_TAC[] THEN MP_TAC (ISPECL [`x:num->num`; `0..k+1`] PERMUTES_INVERSES) THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN EXPAND_TAC "g" THEN REWRITE_TAC[GSYM o_ASSOC] THEN ASM_SIMP_TAC[I_O_ID] ]; ALL_TAC ] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN `j < k + 2 /\ j < k + 1` ASSUME_TAC THENL [ UNDISCH_TAC `j <= k:num` THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `i < k + 2` ASSUME_TAC THENL [ UNDISCH_TAC `i IN 0..k+1` THEN REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `LENGTH (DROP (ul:(real^3)list) i) = k + 1` ASSUME_TAC THENL [ MP_TAC (ISPECL [`i:num`; `ul:(real^3)list`] LENGTH_DROP) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[left_action_list; EL_TABLE] THEN ABBREV_TAC `r = inverse (sigma:num->num) j` THEN MP_TAC (ISPECL [`i:num`; `r:num`; `ul:(real^3)list`] EL_DROP) THEN SUBGOAL_THEN `r <= k:num` ASSUME_TAC THENL [ MP_TAC (ISPECL [`sigma:num->num`; `0..k`] PERMUTES_INVERSE) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`inverse (sigma:num->num)`; `0..k`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[IN_NUMSEG; LE_0]; ALL_TAC ] THEN ASM_REWRITE_TAC[ARITH_RULE `r < (k + 2) - 1 <=> r <= k`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN SUBGOAL_THEN `inverse ((sigma:num->num) o (fi:num->num->num) i) = (f:num->num->num) i o inverse sigma` (fun th -> REWRITE_TAC[th]) THENL [ MATCH_MP_TAC INVERSE_UNIQUE_o THEN SUBGOAL_THEN `!a:num->num b:num->num c:num->num d:num->num. (a o b) o c o d = a o (b o c) o d` (fun th -> REWRITE_TAC[th]) THENL [ REWRITE_TAC[o_ASSOC]; ALL_TAC ] THEN UNDISCH_TAC `!i. i <= k + 1 ==> (f:num->num->num) i o fi i = I /\ fi i o f i = I` THEN DISCH_THEN (MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[ARITH_RULE `i <= k + 1 <=> i < k + 2`] THEN DISCH_TAC THEN MP_TAC (ISPECL [`sigma:num->num`; `0..k`] PERMUTES_INVERSES_o) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[I_O_ID]; ALL_TAC ] THEN ASM_REWRITE_TAC[o_THM] THEN EXPAND_TAC "f" THEN ASM_SIMP_TAC[ARITH_RULE `r <= k ==> ~(r = k + 1) /\ r < k + 1`] THEN ONCE_REWRITE_TAC[GSYM NOT_LE] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[]);;
(******************************************) (* WQPRRDY *)
let WQPRRDY = 
prove(`!V ul k. packing V /\ ul IN barV V k /\ hl ul < sqrt(&2) ==> (convex hull (set_of_list ul) = UNIONS { rogers V (left_action_list p ul) | p permutes (0..k) })`,
GEN_TAC THEN REWRITE_TAC[IN] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN INDUCT_TAC THEN REPEAT STRIP_TAC THENL [ SUBGOAL_THEN `?x:real^3. ul = [x]` CHOOSE_TAC THENL [ EXISTS_TAC `HD ul:real^3` THEN MATCH_MP_TAC LENGTH_1_LEMMA THEN UNDISCH_TAC `barV V 0 ul` THEN SIMP_TAC[BARV; ARITH]; ALL_TAC ] THEN ASM_REWRITE_TAC[set_of_list; CONVEX_HULL_SING; PERMUTES_TRIVIAL; SING_GSPEC_APP; LEFT_ACTION_LIST_I] THEN REWRITE_TAC[ROGERS; LENGTH; ARITH_RULE `j < SUC 0 <=> j = 0`; SING_GSPEC; IMAGE_LEMMA; IN_SING; SING_GSPEC_APP; CONVEX_HULL_SING] THEN REWRITE_TAC[OMEGA_LIST_N; HD; UNIONS_1]; ALL_TAC ] THEN ABBREV_TAC `S:real^3->bool = set_of_list ul` THEN MP_TAC (ISPECL [`S:real^3->bool`; `omega_list V ul`] CONVEX_HULL_EXCHANGE_UNION) THEN ANTS_TAC THENL [ EXPAND_TAC "S" THEN MATCH_MP_TAC XNHPWAB2 THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[IN]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ABBREV_TAC `u = omega_list V ul` THEN EXPAND_TAC "S" THEN ASM_REWRITE_TAC[IN_SET_OF_LIST] THEN MP_TAC (ISPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`] BARV_IMP_LENGTH_EQ_CARD) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN MP_TAC (SPEC `k:num` IVFICRK_real3) THEN DISCH_THEN (CHOOSE_THEN (CONJUNCTS_THEN2 (LABEL_TAC "g0") ASSUME_TAC)) THEN POP_ASSUM (MP_TAC o ISPEC `ul:(real^3)list`) THEN ASM_REWRITE_TAC[ARITH_RULE `SUC k + 1 = k + 2`; IN_NUMSEG; LE_0] THEN DISCH_THEN (LABEL_TAC "tmp") THEN SUBGOAL_THEN `!i p. i < SUC k + 1 /\ p permutes 0..k ==> g (i,p) permutes 0..SUC k` (LABEL_TAC "g1") THENL [ REPEAT STRIP_TAC THEN REMOVE_THEN "g0" MP_TAC THEN REWRITE_TAC[BIJ; INJ; GSYM CONJ_ASSOC] THEN DISCH_THEN (CONJUNCTS_THEN2 MP_TAC (fun th -> ALL_TAC)) THEN DISCH_THEN (MP_TAC o SPEC `i:num, p:num->num`) THEN REWRITE_TAC[IN_ELIM_THM; ADD1] THEN ANTS_TAC THENL [ MAP_EVERY EXISTS_TAC [`i:num`; `p:num->num`] THEN ASM_REWRITE_TAC[IN_NUMSEG; LE_0; ARITH_RULE `i <= k + 1 <=> i < SUC k + 1`]; ALL_TAC ] THEN REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!s. s permutes 0..SUC k ==> ?i p. i < SUC k + 1 /\ p permutes 0..k /\ s = g(i,p)` (LABEL_TAC "g2") THENL [ REWRITE_TAC[ADD1; ARITH_RULE `i < (k + 1) + 1 <=> i <= k + 1`] THEN REPEAT STRIP_TAC THEN REMOVE_THEN "g0" MP_TAC THEN REWRITE_TAC[BIJ; SURJ] THEN REPLICATE_TAC 2 (DISCH_THEN (CONJUNCTS_THEN2 (fun th -> ALL_TAC) MP_TAC)) THEN DISCH_THEN (MP_TAC o SPEC `s:num->num`) THEN ASM_REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG; LE_0] THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC [`i:num`; `sigma:num->num`] THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[EQ_SYM_EQ]; ALL_TAC ] THEN REMOVE_THEN "g0" (fun th -> ALL_TAC) THEN SUBGOAL_THEN `!i p r. i < SUC k + 1 /\ r <= k /\ p permutes 0..k ==> truncate_simplex r (left_action_list (g(i,p)) ul:(real^3)list) = truncate_simplex r (left_action_list p (DROP ul i))` (LABEL_TAC "tr") THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[LIST_EL_EQ] THEN ABBREV_TAC `xl:(real^3)list = truncate_simplex r (left_action_list (g (i:num,p:num->num)) ul)` THEN ABBREV_TAC `yl:(real^3)list = truncate_simplex r (left_action_list p (DROP ul i))` THEN MP_TAC (ISPECL [`i:num`; `ul:(real^3)list`] LENGTH_DROP) THEN ASM_REWRITE_TAC[ARITH_RULE `(SUC k + 1) - 1 = SUC k`] THEN DISCH_TAC THEN MP_TAC (ISPECL [`r:num`; `left_action_list (g (i:num,p:num->num)) ul:(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN MP_TAC (ARITH_RULE `r <= k ==> r + 1 <= SUC k + 1`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST] THEN MP_TAC (ISPECL [`r:num`; `left_action_list p (DROP ul i):(real^3)list`] LENGTH_TRUNCATE_SIMPLEX) THEN ASM_SIMP_TAC[LENGTH_LEFT_ACTION_LIST; ARITH_RULE `r <= k ==> r + 1 <= SUC k`] THEN REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`left_action_list (g(i:num,p:num->num)) ul:(real^3)list`; `r:num`; `j:num`] EL_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST] THEN MP_TAC (ARITH_RULE `j < r + 1 ==> j <= r`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC (ISPECL [`left_action_list p (DROP ul i):(real^3)list`; `r:num`; `j:num`] EL_TRUNCATE_SIMPLEX) THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST; ARITH_RULE `r + 1 <= SUC k <=> r <= k`] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN UNDISCH_TAC `r <= k:num` THEN UNDISCH_TAC `j <= r:num` THEN UNDISCH_TAC `i < SUC k + 1` THEN ARITH_TAC; ALL_TAC ] THEN REMOVE_THEN "tmp" (fun th -> ALL_TAC) THEN SUBGOAL_THEN `!i b:real^3. i < SUC k + 1 /\ b = EL i ul ==> convex hull (u INSERT (S DELETE b)) = UNIONS {convex hull (u INSERT rogers V (left_action_list p (DROP ul i))) | p permutes 0..k}` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN MP_TAC (ISPECL [`i:num`; `ul:(real^3)list`] SET_OF_LIST_DELETE_EQ_DROP) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN ABBREV_TAC `vl:(real^3)list = DROP ul i` THEN FIRST_X_ASSUM (MP_TAC o SPEC `vl:(real^3)list`) THEN ANTS_TAC THENL [ ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i:num`; `I:num->num`; `k:num`]) THEN ASM_REWRITE_TAC[PERMUTES_I; LE_REFL; LEFT_ACTION_LIST_I] THEN MP_TAC (ISPECL [`i:num`; `ul:(real^3)list`] LENGTH_DROP) THEN ASM_REWRITE_TAC[ARITH_RULE `(SUC k + 1) - 1 = k + 1`] THEN DISCH_TAC THEN ABBREV_TAC `xl:(real^3)list = left_action_list (g (i:num, I:num->num)) ul` THEN SUBGOAL_THEN `truncate_simplex k vl = vl:(real^3)list` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL [`k:num`; `vl:(real^3)list`; `vl:(real^3)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN ASM_REWRITE_TAC[LE_REFL; INITIAL_SUBLIST_REFL]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i:num`; `I:num->num`]) THEN ASM_REWRITE_TAC[PERMUTES_I] THEN DISCH_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`; `(g(i:num,I:num->num)):num->num`] YIFVQDV) THEN ASM_REWRITE_TAC[IN] THEN DISCH_TAC THEN CONJ_TAC THENL [ MATCH_MP_TAC TRUNCATE_SIMPLEX_BARV THEN EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[ARITH_RULE `k <= SUC k`]; ALL_TAC ] THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `hl (xl:(real^3)list)` THEN CONJ_TAC THENL [ MATCH_MP_TAC HL_DECREASE THEN MAP_EVERY EXISTS_TAC [`V:real^3->bool`; `SUC k`] THEN ASM_REWRITE_TAC[IN; ARITH_RULE `k <= SUC k`]; ALL_TAC ] THEN EXPAND_TAC "xl" THEN REWRITE_TAC[HL] THEN ASM_SIMP_TAC[ARITH_RULE `(SUC k + 1) - 1 = SUC k`; SET_OF_LIST_LEFT_ACTION_LIST] THEN EXPAND_TAC "S" THEN REWRITE_TAC[GSYM HL] THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `convex hull (u:real^3 INSERT set_of_list vl) = convex hull (u INSERT convex hull set_of_list vl)` (fun th -> REWRITE_TAC[th]) THENL [ MP_TAC (ISPECL [`{u:real^3}`; `set_of_list vl:real^3->bool`] CONV_UNION_lemma) THEN REWRITE_TAC[SET_RULE `!x s. {x:real^3} UNION s = x INSERT s`]; ALL_TAC ] THEN DISCH_THEN (LABEL_TAC "A") THEN ASM_REWRITE_TAC[] THEN ABBREV_TAC `f = {rogers V (left_action_list p vl) | p permutes 0..k}` THEN ONCE_REWRITE_TAC[SET_RULE `!x s. (x:real^3) INSERT s = {x} UNION s`] THEN MP_TAC (ISPECL [`f:(real^3->bool)->bool`; `{u:real^3}`] CONVEX_HULL_UNION_UNIONS) THEN ANTS_TAC THENL [ REMOVE_THEN "A" (fun th -> REWRITE_TAC[SYM th]) THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; CONVEX_CONVEX_HULL] THEN EXISTS_TAC `rogers V vl` THEN EXPAND_TAC "f" THEN REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `I:num->num` THEN REWRITE_TAC[LEFT_ACTION_LIST_I; PERMUTES_I]; ALL_TAC ] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN AP_TERM_TAC THEN ASM SET_TAC[]; ALL_TAC ] THEN SUBGOAL_THEN `!i p. i < SUC k + 1 /\ p permutes 0..k ==> convex hull (u:real^3 INSERT rogers V (left_action_list p (DROP ul i))) = rogers V (left_action_list (g (i, p)) ul)` (LABEL_TAC "r") THENL [ REPEAT STRIP_TAC THEN REWRITE_TAC[ROGERS] THEN ABBREV_TAC `xl:(real^3)list = left_action_list p (DROP ul i)` THEN ABBREV_TAC `yl:(real^3)list = left_action_list (g (i:num, p:num->num)) ul` THEN SUBGOAL_THEN `!s:real^3->bool. convex hull (u INSERT convex hull s) = convex hull (u INSERT s)` (fun th -> REWRITE_TAC[th]) THENL [ GEN_TAC THEN MP_TAC (ISPECL [`{u:real^3}`; `s:real^3->bool`] CONV_UNION_lemma) THEN SIMP_TAC[SET_RULE `{u:real^3} UNION s = u INSERT s`]; ALL_TAC ] THEN AP_TERM_TAC THEN EXPAND_TAC "xl" THEN EXPAND_TAC "yl" THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST] THEN MP_TAC (ISPECL [`i:num`; `ul:(real^3)list`] LENGTH_DROP) THEN ASM_REWRITE_TAC[ARITH_RULE `(SUC k + 1) - 1 = SUC k`] THEN DISCH_TAC THEN SUBGOAL_THEN `u = omega_list_n V yl (SUC k)` ASSUME_TAC THENL [ MP_TAC (SPECL [`V:real^3->bool`; `ul:(real^3)list`; `SUC k`; `(g (i:num, p:num->num)):num->num`] YIFVQDV) THEN ASM_SIMP_TAC[IN] THEN DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN MP_TAC (SPECL [`V:real^3->bool`; `yl:(real^3)list`; `SUC k`] OMEGA_LIST_LEMMA) THEN EXPAND_TAC "yl" THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST; LE_REFL] THEN MP_TAC (ISPECL [`SUC k`; `yl:(real^3)list`; `yl:(real^3)list`] TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN EXPAND_TAC "yl" THEN ASM_REWRITE_TAC[LENGTH_LEFT_ACTION_LIST; LE_REFL; INITIAL_SUBLIST_REFL] THEN DISCH_THEN (fun th -> ASM_REWRITE_TAC[th]); ALL_TAC ] THEN SUBGOAL_THEN `!j. j < SUC k ==> omega_list_n V xl j = omega_list_n V yl j` ASSUME_TAC THENL [ REPEAT STRIP_TAC THEN REMOVE_THEN "tr" (MP_TAC o SPECL [`i:num`; `p:num->num`; `k:num`]) THEN ASM_REWRITE_TAC[LE_REFL] THEN DISCH_TAC THEN MP_TAC (SPECL [`V:real^3->bool`; `xl:(real^3)list`; `j:num`; `k - j:num`] OMEGA_LIST_N_LEMMA) THEN MP_TAC (SPECL [`V:real^3->bool`; `yl:(real^3)list`; `j:num`; `k - j:num`] OMEGA_LIST_N_LEMMA) THEN MP_TAC (ARITH_RULE `j < SUC k ==> j + k - j = k /\ j + k - j + 1 = k + 1`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN EXPAND_TAC "yl" THEN EXPAND_TAC "xl" THEN REWRITE_TAC[LENGTH_LEFT_ACTION_LIST] THEN ASM_REWRITE_TAC[ARITH_RULE `k + 1 <= SUC k /\ k + 1 <= SUC k + 1`] THEN SIMP_TAC[]; ALL_TAC ] THEN ASM_REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INSERT; IN_ELIM_THM] THEN GEN_TAC THEN EQ_TAC THENL [ STRIP_TAC THENL [ EXISTS_TAC `SUC k` THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC ] THEN EXISTS_TAC `x':num` THEN ASM_SIMP_TAC[] THEN POP_ASSUM MP_TAC THEN ARITH_TAC; ALL_TAC ] THEN STRIP_TAC THEN ASM_CASES_TAC `x' = SUC k` THENL [ DISJ1_TAC THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN DISJ2_TAC THEN EXISTS_TAC `x':num` THEN MP_TAC (ARITH_RULE `x' < SUC k + 1 /\ ~(x' = SUC k) ==> x' < SUC k`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN REWRITE_TAC[EXTENSION; IN_UNIONS; IN_ELIM_THM] THEN GEN_TAC THEN REWRITE_TAC[GSYM EXTENSION; MEM_EXISTS_EL] THEN EQ_TAC THENL [ ASM_REWRITE_TAC[] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN REMOVE_ASSUM THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i:num`; `b:real^3`]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN POP_ASSUM (fun th -> REWRITE_TAC[th]) THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i:num`; `p:num->num`]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN EXISTS_TAC `rogers V (left_action_list (g (i:num, p:num->num)) ul)` THEN ASM_REWRITE_TAC[] THEN EXISTS_TAC `(g (i:num, p:num->num)):num->num` THEN ASM_SIMP_TAC[]; ALL_TAC ] THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC `p:num->num`) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC `convex hull (u:real^3 INSERT (S DELETE (EL i ul)))` THEN CONJ_TAC THENL [ EXISTS_TAC `EL i ul:real^3` THEN REWRITE_TAC[] THEN EXISTS_TAC `i:num` THEN ASM_REWRITE_TAC[]; ALL_TAC ] THEN MATCH_MP_TAC IN_TRANS THEN EXISTS_TAC `rogers V (left_action_list p ul)` THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i:num`; `p':num->num`]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[SYM th]) THEN FIRST_X_ASSUM (MP_TAC o SPECL [`i:num`; `EL i ul:real^3`]) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN REWRITE_TAC[SUBSET; IN_UNIONS] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `convex hull (u INSERT rogers V (left_action_list p' (DROP ul i)))` THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `p':num->num` THEN ASM_REWRITE_TAC[]);;
end;;