(* ========================================================================== *)
(* FLYSPECK - BOOK FORMALIZATION *)
(* *)
(* Chapter: Packing *)
(* Author: Alexey Solovyev *)
(* Date: 2010-03-15 *)
(* Proofs of: KIUMVTC, TIWWFYQ, DRUQUFE *)
(* ========================================================================== *)
flyspeck_needs "general/sphere.hl";;
flyspeck_needs "packing/pack_defs.hl";;
flyspeck_needs "packing/pack2.hl";;
module Packing3 = struct
open Sphere;;
open Pack_defs;;
let REMOVE_ASSUM = POP_ASSUM (fun th -> ALL_TAC);;
(* Alternative definition of the packing *)
let packing_lt = prove(`packing (V:real^3 -> bool) =
(!u:real^3 v:real^3. (u
IN V) /\ (v
IN V) /\ (
dist( u, v) < &2) ==>
(u = v))`,
REWRITE_TAC[packing;
IN;REAL_ARITH `x<y <=> ~(y<= x)`]
THEN MESON_TAC[]);;
let BIS_SYM = prove(`!p (q:real^N). bis p q = bis q p`,
REWRITE_TAC[bis] THEN SET_TAC[]);;
(***********************************************************************************)
(***********************************************************************************)
(***********************************************************************************)
(*********************************)
(* Auxiliary general definitions *)
(*********************************)
(****************************)
(* Auxiliary general lemmas *)
(****************************)
let CHOICE_LEMMA = MESON[] `!y (P:A->bool). ((?x. P x) /\ (!x. P x ==> (x = y))) ==> (@x. P x) = y`;;
let SING_GSPEC_APP = prove(`!(f:A->B) a. {f x | x = a} = {f a}`,
REWRITE_TAC[
EXTENSION;
IN_ELIM_THM;
IN_SING] THEN
REPEAT STRIP_TAC THEN
EQ_TAC THEN REPEAT STRIP_TAC THENL [ ASM_REWRITE_TAC[]; ALL_TAC ] THEN
EXISTS_TAC `a:A` THEN ASM_REWRITE_TAC[]);;
let LENGTH_IMP_CONS = prove(`!l:(A)list. 1 <=
LENGTH l ==> ?h t. l = CONS h t`,
REPEAT STRIP_TAC THEN
MP_TAC (ISPECL [`l:(A)list`; `
PRE (
LENGTH (l:(A)list))`]
LENGTH_EQ_CONS) THEN
ASM_SIMP_TAC[ARITH_RULE `1 <= n ==> SUC (
PRE n) = n`] THEN
STRIP_TAC THEN
MAP_EVERY EXISTS_TAC [`h:A`; `t:(A)list`] THEN
ASM_REWRITE_TAC[]);;
let PERMUTES_TRIVIAL = prove(`!p. p
permutes 0..0 <=> p = I`,
GEN_TAC THEN EQ_TAC THENL
[
REWRITE_TAC[
permutes;
FUN_EQ_THM;
I_THM;
IN_NUMSEG; DE_MORGAN_THM;
LE_0;
NOT_LE] THEN
REPEAT STRIP_TAC THEN
ASM_CASES_TAC `x = 0` THENL
[
FIRST_X_ASSUM (MP_TAC o SPEC `0`) THEN
REWRITE_TAC[
EXISTS_UNIQUE] THEN
STRIP_TAC THEN REMOVE_ASSUM THEN
SUBGOAL_THEN `x' = 0` ASSUME_TAC THENL
[
ASM_CASES_TAC `x' = 0` THEN ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM (MP_TAC o SPEC `x':num`) THEN
ASM_REWRITE_TAC[ARITH_RULE `0 < x' <=> ~(x' = 0)`];
ALL_TAC
] THEN
UNDISCH_TAC `(p:num->num) x' = 0` THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
SIMP_TAC[
PERMUTES_I]);;
(* conv (A UNION B) = conv(A UNION conv B) *)
(* Lemmas about intersections *)
let INTER_INTERS = prove(`!(s:A->bool) (f:(B->bool)) (P:B->(A->bool)). ~(f = {}) ==> s
INTER INTERS {P t | t
IN f} =
INTERS {s
INTER P t | t
IN f}`,
REPEAT STRIP_TAC THEN
REWRITE_TAC[
EXTENSION;
IN_INTER;
IN_INTERS;
IN_ELIM_THM] THEN
GEN_TAC THEN EQ_TAC THENL
[
REPEAT STRIP_TAC THEN
ASM SET_TAC[];
ALL_TAC
] THEN
REPEAT STRIP_TAC THENL
[
SUBGOAL_THEN `?t':B. t'
IN (f:B->bool)` MP_TAC THENL
[
FIRST_X_ASSUM (MP_TAC o check (is_neg o concl)) THEN
REWRITE_TAC[
EXTENSION;
NOT_IN_EMPTY] THEN
REWRITE_TAC[
NOT_FORALL_THM];
ALL_TAC
] THEN
STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `(s:A->bool)
INTER (P (t':B))`) THEN
ANTS_TAC THENL
[
EXISTS_TAC `t':B` THEN
ASM_REWRITE_TAC[
IN_INTER];
ALL_TAC
] THEN
SIMP_TAC[
IN_INTER];
ALL_TAC
] THEN
ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM (MP_TAC o SPEC `(s:A->bool)
INTER (P (t':B))`) THEN
ANTS_TAC THENL
[
EXISTS_TAC `t':B` THEN
ASM_REWRITE_TAC[
IN_INTER];
ALL_TAC
] THEN
SIMP_TAC[
IN_INTER]);;
(* Union of finite sets is finite *)
let UNIONS_FINITE_LEMMA = prove(`!(g:(A->bool)->bool) (P:(A->bool)->(A->bool)). FINITE g /\ (!t. t
IN g ==> FINITE (P t)) ==> FINITE (
UNIONS {P t | t
IN g})`,
REPEAT STRIP_TAC THEN
MP_TAC (ISPEC `{(P:(A->bool)->(A->bool)) t | t
IN g}`
FINITE_FINITE_UNIONS) THEN
SUBGOAL_THEN `FINITE {(P:(A->bool)->(A->bool)) t | t
IN (g:(A->bool)->bool)}` (fun
th -> REWRITE_TAC[
th]) THENL
[
REWRITE_TAC[
SIMPLE_IMAGE] THEN
ASM_SIMP_TAC[
FINITE_IMAGE];
ALL_TAC
] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
REWRITE_TAC[
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THEN
ASM_MESON_TAC[]);;
(* Lemmas about min and max for finite sets of real numbers *)
(***************************)
(* Properties of bisectors *)
(***************************)
(* Auxiliary lemma for distances and points inside an interval *)
(********************************************************)
(* Proof that V(v,r) is finite begins here *)
(********************************************************)
(* General properties of discrete sets *)
(* Any discrete set is closed *)
(* Any subset of a discrete set is discrete *)
let DISCRETE_SUBSET = prove(`!A B:real^N -> bool. discrete A /\ B
SUBSET A ==> discrete B`,
REWRITE_TAC[discrete;
SUBSET] THEN REPEAT STRIP_TAC THEN
EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN
ASM_MESON_TAC[]);;
(* A discrete and bounded set is compact *)
(* If S is discrete, then there is an open cover by balls b such that |b INTER S| = 1 *)
(* Discrete and bounded S is finite *)
let DISCRETE_BOUNDED_IMP_FINITE = prove(`!S:real^N->bool. discrete S /\
bounded S ==> FINITE S`,
REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN
MP_TAC (ISPEC `S:real^N->bool`
DISCRETE_IMP_BOUNDED_EQ_COMPACT) THEN
ASM_REWRITE_TAC[] THEN DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
REWRITE_TAC[
COMPACT_EQ_HEINE_BOREL] THEN
REPEAT STRIP_TAC THEN
MP_TAC (SPEC `S:real^N -> bool`
DISCRETE_OPEN_COVER) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (X_CHOOSE_THEN `f:(real^N->bool)->bool` MP_TAC) THEN
FIRST_X_ASSUM ((LABEL_TAC "A") o (SPEC `f:(real^N->bool)->bool`)) THEN
DISCH_THEN (LABEL_TAC "B") THEN
REMOVE_THEN "A" MP_TAC THEN ASM_SIMP_TAC[] THEN
DISCH_THEN (X_CHOOSE_THEN `g:(real^N->bool)->bool` MP_TAC) THEN
STRIP_TAC THEN
SUBGOAL_THEN `FINITE (S
INTER UNIONS (g:(real^N->bool)->bool))` ASSUME_TAC THENL
[
REWRITE_TAC[
INTER_UNIONS] THEN
MATCH_MP_TAC
UNIONS_FINITE_LEMMA THEN
ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
REMOVE_THEN "B" (MP_TAC o (SPEC `x:real^N -> bool`) o CONJUNCT1) THEN
MP_TAC (SET_RULE `x:(real^N->bool)
IN g /\ g
SUBSET f ==> x
IN f`) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
SIMP_TAC[
INTER_COMM;
HAS_SIZE];
ALL_TAC
] THEN
ASM_MESON_TAC[SET_RULE `S
SUBSET A ==> S
INTER A = S`]);;
(* Proof of the main lemma begins here *)
(* A packing is a discrete set *)
(* Main lemma: if V is a packing then (V INTER ball) is finite *)
(****************************************************)
(* TIWWFYQ *)
(* If a packing is saturated, then every point of *)
(* the space is inside some Voronoi (closed) cell *)
(****************************************************)
(* AS: real^N <== pacling:real^N *)
let TIWWFYQ = prove(`!V (p:real^3). packing V /\ saturated V ==> (?v. v
IN V /\ p
IN voronoi_closed V v)`,
REWRITE_TAC[saturated] THEN REPEAT STRIP_TAC THEN
ABBREV_TAC `S = V
INTER ball(p:real^3, &2)` THEN
SUBGOAL_THEN `?v:real^3. v
IN S /\ !w. w
IN S ==>
dist(v, p) <=
dist(w, p)` MP_TAC THENL
[
MATCH_MP_TAC
REAL_FINITE_ARGMIN THEN
EXPAND_TAC "S" THEN
ASM_SIMP_TAC[
KIUMVTC] THEN
REWRITE_TAC[SET_RULE `~(S = {}) <=> ?a. a
IN S`] THEN
EXPAND_TAC "S" THEN REWRITE_TAC[
ball;
INTER;
IN_ELIM_THM] THEN
ASM_MESON_TAC[];
ALL_TAC
] THEN
STRIP_TAC THEN
EXISTS_TAC `v:real^3` THEN
REPLICATE_TAC 2 (POP_ASSUM MP_TAC) THEN EXPAND_TAC "S" THEN POP_ASSUM (fun
th -> ALL_TAC) THEN
ASM_SIMP_TAC[
IN_INTER] THEN
DISCH_THEN (LABEL_TAC "A") THEN
DISCH_THEN (LABEL_TAC "B") THEN
REWRITE_TAC[
voronoi_closed;
IN_ELIM_THM] THEN GEN_TAC THEN
GEN_REWRITE_TAC LAND_CONV [GSYM
IN] THEN
DISJ_CASES_TAC (TAUT `w:real^3
IN ball(p, &2) \/ ~(w
IN ball(p, &2))`) THENL
[
ASM_MESON_TAC[
DIST_SYM];
SUBGOAL_THEN `&2 <=
dist(p:real^3, w)` MP_TAC THENL
[
POP_ASSUM MP_TAC THEN REWRITE_TAC[
ball;
IN_ELIM_THM;
REAL_NOT_LT];
ALL_TAC
] THEN
SUBGOAL_THEN `
dist(p:real^3, v) < &2` MP_TAC THENL
[
REMOVE_THEN "A" MP_TAC THEN SIMP_TAC[
ball;
IN_ELIM_THM];
ALL_TAC
] THEN
REAL_ARITH_TAC
]);;
(*******************************)
(* Porperties of Voronoi cells *)
(*******************************)
(* v IN voronoi_closed V v *)
(* voronoi_closed V v contains a ball *)
let VORONOI_CLOSED_CONTAINS_BALL = prove(`!V (v:real^3). packing V ==> ?r. &0 < r /\
ball (v, r)
SUBSET voronoi_closed V v`,
REWRITE_TAC[packing;
voronoi_closed] THEN
REPEAT STRIP_TAC THEN
ASM_CASES_TAC `v:real^3
IN V` THENL
[
POP_ASSUM MP_TAC THEN REWRITE_TAC[
IN] THEN DISCH_TAC THEN
EXISTS_TAC `&1` THEN
REWRITE_TAC[
REAL_LT_01;
ball;
SUBSET;
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THEN
ASM_CASES_TAC `w = v:real^3` THEN ASM_REWRITE_TAC[
REAL_LE_REFL] THEN
FIRST_X_ASSUM (MP_TAC o SPECL [`v:real^3`; `w:real^3`]) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
SUBGOAL_THEN `&2 -
dist(x,v:real^3) <=
dist(x,w:real^3)` MP_TAC THENL
[
REWRITE_TAC[REAL_ARITH `a - b <= c <=> a <= b + c:real`] THEN
MATCH_MP_TAC
REAL_LE_TRANS THEN
EXISTS_TAC `
dist (v,w:real^3)` THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ISPECL [`v:real^3`; `x:real^3`; `w:real^3`]
DIST_TRIANGLE) THEN
REWRITE_TAC[
DIST_SYM];
ALL_TAC
] THEN
UNDISCH_TAC `
dist (v,x:real^3) < &1` THEN
REWRITE_TAC[
DIST_SYM] THEN
REAL_ARITH_TAC;
ALL_TAC
] THEN
SUBGOAL_THEN `?s. &0 < s /\
ball (v:real^3, s)
INTER V = {}` STRIP_ASSUME_TAC THENL
[
SUBGOAL_THEN `~(
ball (v:real^3, &1)
INTER V = {}) ==> ?x.
ball (v:real^3, &1)
INTER V = {x}` MP_TAC THENL
[
REWRITE_TAC[GSYM
MEMBER_NOT_EMPTY;
IN_INTER;
EXTENSION;
IN_SING;
ball;
IN_ELIM_THM] THEN
STRIP_TAC THEN
EXISTS_TAC `x:real^3` THEN
GEN_TAC THEN EQ_TAC THENL
[
STRIP_TAC THEN
SUBGOAL_THEN `
dist (x:real^3, x') < &2` MP_TAC THENL
[
MATCH_MP_TAC
REAL_LET_TRANS THEN
EXISTS_TAC `
dist (x,v) +
dist(v:real^3,x')` THEN
REWRITE_TAC[
DIST_TRIANGLE; REAL_ARITH `&2 = &1 + &1`] THEN
MATCH_MP_TAC
REAL_LT_ADD2 THEN
ASM_REWRITE_TAC[
DIST_SYM];
ALL_TAC
] THEN
FIRST_X_ASSUM (MP_TAC o SPECL [`x:real^3`; `x':real^3`]) THEN
POP_ASSUM MP_TAC THEN REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN SIMP_TAC[
IN] THEN
DISCH_TAC THEN DISCH_TAC THEN
ASM_CASES_TAC `x' = x:real^3` THEN ASM_REWRITE_TAC[
REAL_NOT_LT];
ALL_TAC
] THEN
ASM_SIMP_TAC[];
ALL_TAC
] THEN
ASM_CASES_TAC `
ball (v:real^3, &1)
INTER V = {}` THEN ASM_REWRITE_TAC[] THENL
[
EXISTS_TAC `&1` THEN
ASM_REWRITE_TAC[
REAL_LT_01];
ALL_TAC
] THEN
STRIP_TAC THEN
EXISTS_TAC `
dist (v:real^3, x)` THEN
CONJ_TAC THENL
[
MATCH_MP_TAC
DIST_POS_LT THEN
DISCH_THEN (ASSUME_TAC o SYM) THEN
UNDISCH_TAC `
ball (v:real^3, &1)
INTER V = {x}` THEN
ASM_REWRITE_TAC[
EXTENSION;
IN_INTER;
IN_SING;
NOT_FORALL_THM] THEN
EXISTS_TAC `x:real^3` THEN
ASM_REWRITE_TAC[];
ALL_TAC
] THEN
POP_ASSUM MP_TAC THEN
REWRITE_TAC[
EXTENSION;
IN_INTER;
ball;
IN_ELIM_THM;
NOT_IN_EMPTY;
IN_SING] THEN
REPEAT STRIP_TAC THEN
FIRST_ASSUM (MP_TAC o SPEC `x:real^3`) THEN
REWRITE_TAC[] THEN DISCH_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `x':real^3`) THEN
SUBGOAL_THEN `
dist (v,x':real^3) < &1` ASSUME_TAC THENL
[
MATCH_MP_TAC
REAL_LT_TRANS THEN
EXISTS_TAC `
dist (v, x:real^3)` THEN
ASM_REWRITE_TAC[];
ALL_TAC
] THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
UNDISCH_TAC `
dist (v,x':real^3) <
dist (v,x)` THEN
ASM_REWRITE_TAC[
REAL_LT_REFL];
ALL_TAC
] THEN
EXISTS_TAC `s / &2` THEN
POP_ASSUM MP_TAC THEN
ASM_REWRITE_TAC[REAL_ARITH `&0 < s / &2 <=> &0 < s`;
ball;
SUBSET;
IN_ELIM_THM;
EXTENSION;
IN_INTER;
NOT_IN_EMPTY; DE_MORGAN_THM;
REAL_NOT_LT] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `w:real^3`) THEN
ASM_REWRITE_TAC[
IN] THEN DISCH_TAC THEN
SUBGOAL_THEN `s -
dist(x,v:real^3) <=
dist(x,w:real^3)` MP_TAC THENL
[
REWRITE_TAC[REAL_ARITH `a - b <= c <=> a <= b + c:real`] THEN
MATCH_MP_TAC
REAL_LE_TRANS THEN
EXISTS_TAC `
dist (v,w:real^3)` THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ISPECL [`v:real^3`; `x:real^3`; `w:real^3`]
DIST_TRIANGLE) THEN
REWRITE_TAC[
DIST_SYM];
ALL_TAC
] THEN
UNDISCH_TAC `
dist (v, x:real^3) < s / &2` THEN
UNDISCH_TAC `&0 < s` THEN
REWRITE_TAC[
DIST_SYM] THEN
REAL_ARITH_TAC);;
(* aff_dim voronoi_closed V v = 3 *)
(* For a saturated packing each Voronoi cell is inside a ball of radius 2 *)
(* A Voronoi cell is bounded (for a saturated packing) *)
(* A closed Voronoi cell is an intersection of bisector half-spaces *)
(* The same result with excluded point v *)
(* A closed Voronoi cell is an intersection of bisectors for w IN ball(v, 4) *)
let VORONOI_INTER_BIS_LE = prove(`!V (v:real^3). packing V /\ saturated V /\ (v
IN V) ==>
(
voronoi_closed V v =
INTERS {
bis_le v u | u | u
IN V /\ u
IN ball(v, &4) /\ ~(u=v) })`,
REWRITE_TAC[
VORONOI_CLOSED_EQ_INTERS_BIS_LE_ALT; saturated] THEN REPEAT STRIP_TAC THEN
REPLICATE_TAC 2 (POP_ASSUM MP_TAC) THEN DISCH_THEN (LABEL_TAC "A") THEN DISCH_TAC THEN
REWRITE_TAC[
EXTENSION;
IN_INTERS] THEN GEN_TAC THEN EQ_TAC THENL
[
SET_TAC[];
ALL_TAC
] THEN
REWRITE_TAC[
IN_ELIM_THM] THEN
DISCH_THEN (LABEL_TAC "B") THEN REPEAT STRIP_TAC THEN
DISJ_CASES_TAC (TAUT `(w:real^3)
IN ball(v:real^3, &4) \/ ~(w
IN ball(v, &4))`) THENL
[
REPLICATE_TAC 5 (POP_ASSUM MP_TAC) THEN SET_TAC[];
ALL_TAC
] THEN
SUBGOAL_THEN `x:real^3
IN ball(v, &2)` (LABEL_TAC "C") THENL
[
POP_ASSUM MP_TAC THEN REWRITE_TAC[
ball;
IN_ELIM_THM] THEN
ONCE_REWRITE_TAC[TAUT `~A ==> B <=> ~B ==> A`] THEN
REWRITE_TAC[
REAL_NOT_LT] THEN DISCH_TAC THEN
MP_TAC (ISPECL [`v:real^3`; `x:real^3`; `&2`]
MID_POINT_EXISTS) THEN
ASM_REWRITE_TAC[REAL_ARITH `&0 <= &2`] THEN
DISCH_THEN (X_CHOOSE_THEN `q:real^3` MP_TAC) THEN
REWRITE_TAC[
between] THEN STRIP_TAC THEN
REMOVE_THEN "A" ((X_CHOOSE_THEN `p:real^3` MP_TAC) o SPEC `q:real^3`) THEN STRIP_TAC THEN
REMOVE_THEN "B" (MP_TAC o SPEC `
bis_le v (p:real^3)`) THEN
ANTS_TAC THENL
[
EXISTS_TAC `p:real^3` THEN ASM_REWRITE_TAC[
ball;
IN_ELIM_THM] THEN
CONJ_TAC THENL
[
MP_TAC (ISPECL [`v:real^3`; `q:real^3`; `p:real^3`]
DIST_TRIANGLE) THEN
REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[
DIST_NZ] THEN
MP_TAC (ISPECL [`v:real^3`; `p:real^3`; `q:real^3`]
DIST_TRIANGLE) THEN
REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN REWRITE_TAC[
DIST_SYM] THEN
REAL_ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[
bis_le;
IN_ELIM_THM] THEN
SUBGOAL_TAC "A" `
dist(x:real^3, v) = &2 +
dist(q, x)` [ASM_SIMP_TAC[
DIST_SYM]] THEN
MP_TAC (ISPECL [`x:real^3`; `q:real^3`; `p:real^3`]
DIST_TRIANGLE) THEN
REPLICATE_TAC 2 (POP_ASSUM MP_TAC) THEN REWRITE_TAC[
DIST_SYM] THEN REAL_ARITH_TAC;
ALL_TAC
] THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
ASM_REWRITE_TAC[
bis_le;
ball;
IN_ELIM_THM;
REAL_NOT_LT] THEN
MP_TAC (ISPECL [`v:real^3`; `x:real^3`; `w:real^3`]
DIST_TRIANGLE) THEN
REWRITE_TAC[
DIST_SYM] THEN REAL_ARITH_TAC);;
(* A closed Voronoi cell is an intersection of finitely many closed half-spaces *)
(* A closed Voronoi cell is a polyhedron *)
(* AS: real^N (requires packing:real^N) *)
(* A closed Voronoi cell is convex *)
(* A closed Voronoi cell is closed *)
(* A closed Voronoi cell is compact if a packing is saturated (for boundness) *)
(****************************************************************)
(* DRUQUFE: *)
(* For a saturated packing, each closed Voronoi closed cell is *)
(* compact, convex, and measurable *)
(****************************************************************)
(* AS: real^N, remove `packing` *)
(*************************************************************)
(*******************************************)
(* Some results for initial sublists *)
(*******************************************)
let INITIAL_SUBLIST_HEAD_EQ = prove(`!xl zl hx tx hz tz. xl = CONS hx tx /\ zl = CONS hz tz /\ initial_sublist xl zl ==> hx = hz`,
REPEAT GEN_TAC THEN
REWRITE_TAC[
INITIAL_SUBLIST] THEN
STRIP_TAC THEN
POP_ASSUM MP_TAC THEN
ASM_REWRITE_TAC[
APPEND] THEN
MESON_TAC[injectivity "list"]);;
let INITIAL_SUBLIST_TAIL = prove(`!xl zl hx tx. xl = CONS hx tx /\ initial_sublist xl zl ==> initial_sublist tx (
TL zl)`,
REWRITE_TAC[
INITIAL_SUBLIST] THEN
REPEAT STRIP_TAC THEN
POP_ASSUM MP_TAC THEN
ASM_REWRITE_TAC[
APPEND] THEN
DISCH_TAC THEN
ASM_REWRITE_TAC[
TL] THEN
MESON_TAC[]);;
(* Two initial sublists of the same list and of the same size are equal *)
(* Transitivity for initial sublists *)
(* initial_sublist is reflexive *)
(* An empty list is an initial sublist of any list *)
(* There exists initial sublists of all acceptable lengths *)
let INITIAL_SUBLIST_EXISTS_ALT = prove(`!n (zl:(A)list) k.
LENGTH zl = n /\ k <= n ==> ?xl. initial_sublist xl zl /\
LENGTH xl = k`,
INDUCT_TAC THEN REPEAT STRIP_TAC THENL
[
EXISTS_TAC `[]:(A)list` THEN
REWRITE_TAC[
INITIAL_SUBLIST_NIL] THEN
POP_ASSUM MP_TAC THEN
SIMP_TAC[
LE;
LENGTH];
ALL_TAC
] THEN
MP_TAC (ISPECL [`zl:(A)list`; `n:num`]
LENGTH_EQ_CONS) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
SUBGOAL_THEN `?yl:(A)list. initial_sublist yl t /\
LENGTH yl = k - 1` MP_TAC THENL
[
FIRST_X_ASSUM (MP_TAC o SPECL [`t:(A)list`; `k - 1`]) THEN
ASM_SIMP_TAC[ARITH_RULE `k <= SUC n ==> k - 1 <= n`];
ALL_TAC
] THEN
STRIP_TAC THEN
DISJ_CASES_TAC (ARITH_RULE `k = 0 \/ 0 < k`) THENL
[
EXISTS_TAC `[]:(A)list` THEN
ASM_REWRITE_TAC[
INITIAL_SUBLIST_NIL;
LENGTH];
ALL_TAC
] THEN
EXISTS_TAC `CONS (h:A) yl` THEN
ASM_REWRITE_TAC[
INITIAL_SUBLIST;
APPEND;
LENGTH] THEN
CONJ_TAC THENL
[
REPLICATE_TAC 2 (POP_ASSUM (fun
th -> ALL_TAC)) THEN
POP_ASSUM MP_TAC THEN
REWRITE_TAC[
INITIAL_SUBLIST] THEN
MESON_TAC[];
POP_ASSUM MP_TAC THEN
ARITH_TAC
]);;
(* The length of an initial sublist does not exceed the length of the list itself *)
(* Structure of initial sublists of APPEND ul vl *)
(* Initial sublists of an one-element list *)
(* Initial sublists of APPEND ul [v] *)
(* (HD ul) is an initial sublist of ul *)
(* (BUTLAST ul) is an initial sublist of ul *)
(**********************************************************)
(**********************************)
(* Additional properties of lists *)
(**********************************)
let EL_REVERSE = prove(`!(ul:(A)list) i. i <
LENGTH ul ==>
EL i (
REVERSE ul) =
EL (
LENGTH ul - 1 - i) ul`,
LIST_INDUCT_TAC THENL
[
REWRITE_TAC[
LENGTH] THEN ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[
LENGTH;
REVERSE;
EL_APPEND;
LENGTH_REVERSE] THEN
REPEAT STRIP_TAC THEN
COND_CASES_TAC THENL
[
FIRST_X_ASSUM (MP_TAC o SPEC `i:num`) THEN
ASM_REWRITE_TAC[] THEN DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
SUBGOAL_THEN `SUC (
LENGTH t) - 1 - i = SUC (
LENGTH (t:(A)list) - 1 - i)` (fun
th -> REWRITE_TAC[
th]) THENL
[
POP_ASSUM MP_TAC THEN
ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[
EL;
TL];
ALL_TAC
] THEN
SUBGOAL_THEN `
LENGTH (t:(A)list) = i` (fun
th -> REWRITE_TAC[
th]) THENL
[
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[ARITH_RULE `i - i = 0`; ARITH_RULE `SUC i - 1 - i = 0`] THEN
REWRITE_TAC[
EL;
HD]);;
let EL_TABLE = prove(`!(f:num->A) n i. i < n ==>
EL i (
TABLE f n) = f i`,
REPEAT GEN_TAC THEN SPEC_TAC (`n:num`, `n:num`) THEN
INDUCT_TAC THENL [ ARITH_TAC; ALL_TAC ] THEN
REWRITE_TAC[
TABLE;
REVERSE_TABLE;
REVERSE;
EL_APPEND] THEN
REWRITE_TAC[GSYM
TABLE;
LENGTH_TABLE] THEN
DISCH_TAC THEN COND_CASES_TAC THENL
[
FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
SUBGOAL_THEN `i = n:num` (fun
th -> REWRITE_TAC[
th]) THENL
[
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[ARITH_RULE `n - n = 0`;
EL;
HD]);;
let EL_LEFT_ACTION_LIST = prove(`!(ul:(A)list) p i. p
permutes (0..LENGTH ul - 1) /\ i <
LENGTH ul
==>
EL i ul =
EL (p i) (
left_action_list p ul)`,
REPEAT STRIP_TAC THEN
REWRITE_TAC[
left_action_list] THEN
ABBREV_TAC `n =
LENGTH (ul:(A)list)` THEN
SUBGOAL_THEN `(p:num->num) i < n` ASSUME_TAC THENL
[
MP_TAC (ISPECL [`p:num->num`; `0..n - 1`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN
ASM_REWRITE_TAC[
IN_NUMSEG] THEN
DISCH_THEN (MP_TAC o SPEC `i:num`) THEN
ASM_REWRITE_TAC[ARITH_RULE `0 <= i`] THEN
ASM_SIMP_TAC[ARITH_RULE `i < n ==> i <= n - 1`] THEN
UNDISCH_TAC `i < n:num` THEN
ARITH_TAC;
ALL_TAC
] THEN
ASM_SIMP_TAC[
EL_TABLE] THEN
AP_THM_TAC THEN AP_TERM_TAC THEN
MP_TAC (ISPECL [`p:num->num`; `0..n-1`]
PERMUTES_INVERSES) THEN
ASM_REWRITE_TAC[] THEN
SIMP_TAC[]);;
let MEM_LEFT_ACTION_LIST = prove(`!(ul:(A)list) p x. p
permutes (0..LENGTH ul - 1)
==> (
MEM x (
left_action_list p ul) <=>
MEM x ul)`,
REPEAT STRIP_TAC THEN
ABBREV_TAC `n =
LENGTH (ul:(A)list)` THEN
ASM_REWRITE_TAC[
MEM_EXISTS_EL;
LENGTH_LEFT_ACTION_LIST] THEN
EQ_TAC THENL
[
STRIP_TAC THEN
POP_ASSUM MP_TAC THEN
ASM_SIMP_TAC[
left_action_list;
EL_TABLE] THEN
DISCH_TAC THEN
EXISTS_TAC `
inverse (p:num->num) i` THEN
REWRITE_TAC[] THEN
MP_TAC (ISPECL [`p:num->num`; `0..n-1`]
PERMUTES_INVERSE) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
MP_TAC (ISPECL [`
inverse (p:num->num)`; `0..n-1`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (MP_TAC o SPEC `i:num`) THEN
ASM_SIMP_TAC[
IN_NUMSEG; ARITH_RULE `i < n ==> i <= n - 1`;
LE_0] THEN
UNDISCH_TAC `i < n:num` THEN ARITH_TAC;
ALL_TAC
] THEN
STRIP_TAC THEN
EXISTS_TAC `(p:num->num) i` THEN
MP_TAC (SPEC_ALL
EL_LEFT_ACTION_LIST) THEN
ASM_SIMP_TAC[] THEN DISCH_TAC THEN
MP_TAC (ISPECL [`p:num->num`; `0..n-1`] Hypermap_and_fan.PERMUTES_IMP_INSIDE) THEN
ASM_REWRITE_TAC[
IN_NUMSEG] THEN DISCH_THEN (MP_TAC o SPEC `i:num`) THEN
UNDISCH_TAC `i < n:num` THEN
ARITH_TAC);;
let CARD_SET_OF_LIST_EQ_LENGTH_IMP_ALL_DISTINCT = prove(`!ul:(A)list.
CARD (
set_of_list ul) =
LENGTH ul
==> (!i j. i <
LENGTH ul /\ j <
LENGTH ul /\ ~(i = j) ==> ~(
EL i ul =
EL j ul))`,
LIST_INDUCT_TAC THEN REWRITE_TAC[
set_of_list;
LENGTH;
CARD_CLAUSES; ARITH_RULE `~(j < 0)`] THEN
SIMP_TAC[
CARD_CLAUSES;
FINITE_SET_OF_LIST] THEN
COND_CASES_TAC THENL
[
MP_TAC (ISPEC `t:(A)list`
CARD_SET_OF_LIST_LE) THEN
ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[ARITH_RULE `SUC n = SUC m <=> n = m`] THEN
DISCH_THEN (fun
th -> FIRST_X_ASSUM (ASSUME_TAC o (fun
th2 -> MATCH_MP
th2 th))) THEN
REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN
MP_TAC (SPEC `i:num`
num_CASES) THEN STRIP_TAC THENL
[
ASM_REWRITE_TAC[
EL;
HD] THEN
MP_TAC (SPEC `j:num`
num_CASES) THEN STRIP_TAC THENL
[
UNDISCH_TAC `~(i = j:num)` THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
ASM_REWRITE_TAC[
EL;
TL] THEN
DISCH_TAC THEN UNDISCH_TAC `~(h:A
IN set_of_list t)` THEN
ASM_REWRITE_TAC[
IN_SET_OF_LIST] THEN
MATCH_MP_TAC (ISPECL [`t:(A)list`; `n:num`]
MEM_EL) THEN
UNDISCH_TAC `j = SUC n` THEN UNDISCH_TAC `j < SUC (
LENGTH (t:(A)list))` THEN
ARITH_TAC;
ALL_TAC
] THEN
ASM_REWRITE_TAC[
EL;
TL] THEN
MP_TAC (SPEC `j:num`
num_CASES) THEN STRIP_TAC THENL
[
ASM_REWRITE_TAC[
EL;
HD] THEN
DISCH_THEN (ASSUME_TAC o SYM) THEN UNDISCH_TAC `~(h:A
IN set_of_list t)` THEN
ASM_REWRITE_TAC[
IN_SET_OF_LIST] THEN
MATCH_MP_TAC (ISPECL [`t:(A)list`; `n:num`]
MEM_EL) THEN
UNDISCH_TAC `i = SUC n` THEN UNDISCH_TAC `i < SUC (
LENGTH (t:(A)list))` THEN
ARITH_TAC;
ALL_TAC
] THEN
ASM_REWRITE_TAC[
EL;
TL] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
REPLICATE_TAC 5 (POP_ASSUM MP_TAC) THEN
ARITH_TAC);;
let LENGTH_DROP = prove(`!i ul:(A)list. i <
LENGTH ul ==>
LENGTH (
DROP ul i) =
LENGTH ul - 1`,
INDUCT_TAC THENL
[
GEN_TAC THEN
REWRITE_TAC[
DROP] THEN DISCH_TAC THEN
MATCH_MP_TAC
LENGTH_TL THEN
ASM_REWRITE_TAC[GSYM
LENGTH_EQ_NIL] THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
REPEAT STRIP_TAC THEN
REWRITE_TAC[
DROP;
LENGTH] THEN
FIRST_X_ASSUM (MP_TAC o SPEC `
TL ul:(A)list`) THEN
SUBGOAL_THEN `
LENGTH (
TL ul) =
LENGTH (ul:(A)list) - 1` ASSUME_TAC THENL
[
MATCH_MP_TAC
LENGTH_TL THEN
ASM_REWRITE_TAC[GSYM
LENGTH_EQ_NIL] THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
ANTS_TAC THENL
[
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN
ARITH_TAC);;
let EL_DROP = prove(`!i j ul:(A)list. i <
LENGTH ul /\ j <
LENGTH ul - 1 ==>
EL j (
DROP ul i) = if (j < i) then
EL j ul else
EL (j + 1) ul`,
INDUCT_TAC THEN INDUCT_TAC THEN REPEAT STRIP_TAC THEN REWRITE_TAC[
DROP;
EL;
LT_REFL; ARITH_RULE `0 + 1 = SUC 0`] THENL
[
REWRITE_TAC[ARITH_RULE `~(x < 0)`; ARITH_RULE `SUC j + 1 = SUC (SUC j)`;
EL];
REWRITE_TAC[ARITH_RULE `0 < SUC i`;
HD];
ALL_TAC
] THEN
REWRITE_TAC[ARITH_RULE `SUC j + 1 = SUC (SUC j)`; ARITH_RULE `SUC j < SUC i <=> j < i`;
TL;
EL] THEN
FIRST_X_ASSUM (MP_TAC o SPECL [`j:num`; `
TL ul:(A)list`]) THEN
SUBGOAL_THEN `
LENGTH (
TL ul:(A)list) =
LENGTH ul - 1` ASSUME_TAC THENL
[
MATCH_MP_TAC
LENGTH_TL THEN
REWRITE_TAC[GSYM
LENGTH_EQ_NIL] THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
ASM_REWRITE_TAC[ARITH_RULE `j + 1 = SUC j`;
EL] THEN
DISCH_THEN MATCH_MP_TAC THEN
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
ARITH_TAC);;
let LIST_EL_EQ = prove(`!ul vl:(A)list. ul = vl <=>
(
LENGTH ul =
LENGTH vl /\ (!j. j <
LENGTH ul ==>
EL j ul =
EL j vl))`,
REPEAT STRIP_TAC THEN
EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
SPEC_TAC (`vl:(A)list`, `vl:(A)list`) THEN SPEC_TAC (`ul:(A)list`, `ul:(A)list`) THEN
LIST_INDUCT_TAC THEN LIST_INDUCT_TAC THEN SIMP_TAC[
LENGTH_EQ_NIL;
EQ_SYM_EQ;
LENGTH; ARITH_RULE `~(0 = SUC a)`] THEN
REMOVE_ASSUM THEN
REWRITE_TAC[ARITH_RULE `SUC a = SUC b <=> a = b`] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `t':(A)list`) THEN
ASM_REWRITE_TAC[] THEN
ANTS_TAC THENL
[
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `SUC j`) THEN
ASM_REWRITE_TAC[ARITH_RULE `SUC a < SUC b <=> a < b`;
EL;
TL];
ALL_TAC
] THEN
DISCH_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `0`) THEN
ASM_SIMP_TAC[ARITH_RULE `0 < SUC a`;
EL;
HD]);;
let SET_OF_LIST_DELETE_SUBSET_DROP = prove(`!j ul:(A)list. j <
LENGTH ul ==>
set_of_list ul
DELETE (
EL j ul)
SUBSET set_of_list (
DROP ul j)`,
REPEAT STRIP_TAC THEN
ABBREV_TAC `k =
LENGTH (ul:(A)list)` THEN
ASM_REWRITE_TAC[
SUBSET;
IN_SET_OF_LIST;
IN_DELETE;
MEM_EXISTS_EL] THEN
REPEAT STRIP_TAC THEN
MP_TAC (ISPECL [`j:num`; `ul:(A)list`]
LENGTH_DROP) THEN
ASM_REWRITE_TAC[] THEN DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
ASM_CASES_TAC `i:num < j` THENL
[
EXISTS_TAC `i:num` THEN
MP_TAC (ARITH_RULE `i < j /\ j < k ==> i < k - 1`) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ISPECL [`j:num`; `i:num`; `ul:(A)list`]
EL_DROP) THEN
ASM_SIMP_TAC[];
ALL_TAC
] THEN
EXISTS_TAC `i - 1` THEN
POP_ASSUM MP_TAC THEN REWRITE_TAC[
NOT_LT;
LE_LT] THEN
STRIP_TAC THENL
[
MP_TAC (ARITH_RULE `j < k /\ i < k /\ j < i ==> i - 1 < k - 1`) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ISPECL [`j:num`; `i - 1`; `ul:(A)list`]
EL_DROP) THEN
ASM_SIMP_TAC[ARITH_RULE `j < i ==> ~(i - 1 < j)`] THEN
MP_TAC (ARITH_RULE `j < i ==> i - 1 + 1 = i`) THEN
ASM_SIMP_TAC[];
ALL_TAC
] THEN
UNDISCH_TAC `x:A =
EL i ul` THEN
POP_ASSUM (fun
th -> ASM_REWRITE_TAC[SYM
th]));;
let SET_OF_LIST_DELETE_EQ_DROP = prove(`!j ul:(A)list.
CARD (
set_of_list ul) =
LENGTH ul /\ j <
LENGTH ul
==>
set_of_list ul
DELETE (
EL j ul) =
set_of_list (
DROP ul j)`,
REPEAT STRIP_TAC THEN
MATCH_MP_TAC
SUBSET_ANTISYM THEN
ASM_SIMP_TAC[
SET_OF_LIST_DELETE_SUBSET_DROP] THEN
ABBREV_TAC `k =
LENGTH (ul:(A)list)` THEN
MP_TAC (SPECL [`j:num`; `ul:(A)list`]
LENGTH_DROP) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
ASM_REWRITE_TAC[
SUBSET;
IN_SET_OF_LIST;
IN_DELETE;
MEM_EXISTS_EL] THEN
GEN_TAC THEN STRIP_TAC THEN
POP_ASSUM (ASSUME_TAC o SYM) THEN
MP_TAC (SPECL [`j:num`; `i:num`; `ul:(A)list`]
EL_DROP) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ARITH_RULE `i < k - 1 ==> i < k`) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
MP_TAC (SPEC `ul:(A)list`
CARD_SET_OF_LIST_EQ_LENGTH_IMP_ALL_DISTINCT) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
COND_CASES_TAC THENL
[
DISCH_TAC THEN
CONJ_TAC THENL
[
EXISTS_TAC `i:num` THEN
ASM_REWRITE_TAC[];
ALL_TAC
] THEN
ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_SIMP_TAC[ARITH_RULE `i < j ==> ~(i = j:num)`];
ALL_TAC
] THEN
DISCH_TAC THEN
CONJ_TAC THENL
[
EXISTS_TAC `i + 1` THEN
ASM_SIMP_TAC[ARITH_RULE `i < k - 1 ==> i + 1 < k`];
ALL_TAC
] THEN
ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_SIMP_TAC[ARITH_RULE `i < k - 1 ==> i + 1 < k`] THEN
UNDISCH_TAC `~(i < j:num)` THEN ARITH_TAC);;
(**********************************************************)
(*****************************************)
(* Properties of barV *)
(*****************************************)
(* barV(k) SUBSET V *)
(* barV(k) = (h:t) for some h, t *)
let BARV_CONS = prove(`!V k ul. barV V k ul ==> ?h t. ul = CONS h t /\ h =
HD ul`,
REPEAT GEN_TAC THEN
REWRITE_TAC[
BARV] THEN
DISCH_THEN (MP_TAC o CONJUNCT1) THEN
REWRITE_TAC[GSYM
ADD1;
LENGTH_EQ_CONS] THEN
ASM_MESON_TAC[
HD]);;
(* An initial sublist of barV(k) is barV(length - 1) *)
let BARV_INITIAL_SUBLIST = prove(`!V k ul vl. barV V k ul /\ initial_sublist vl ul /\ 0 <
LENGTH vl ==> barV V ((
LENGTH vl) - 1) vl`,
REWRITE_TAC[
BARV] THEN
REPEAT STRIP_TAC THENL
[
ASM_SIMP_TAC[ARITH_RULE `0 < a ==> a - 1 + 1 = a`];
ALL_TAC
] THEN
MP_TAC (ISPECL [`vl':(real^3)list`; `vl:(real^3)list`; `ul:(real^3)list`]
INITIAL_SUBLIST_TRANS) THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `vl':(real^3)list`) THEN
ASM_SIMP_TAC[]);;
(* barV V 0 [v] (if v IN V) *)
(* ul IN barV V k ==> k <= 3 *)
(* ul IN barV V k ul ==> HD ul IN set_of_list ul *)
(* Lemma for truncate_simplex operation *)
let TRUNCATE_SIMPLEX_BARV = prove(`!V r k zl. barV V k zl /\ r <= k ==> barV V r (truncate_simplex r zl)`,
REPEAT STRIP_TAC THEN
SUBGOAL_TAC "A" `
LENGTH (zl:(real^3)list) = k + 1` [ ASM_MESON_TAC[
BARV] ] THEN
ABBREV_TAC `xl:(real^3)list = truncate_simplex r zl` THEN
SUBGOAL_THEN `initial_sublist xl (zl:(real^3)list) /\
LENGTH xl = r + 1` STRIP_ASSUME_TAC THENL
[
REWRITE_TAC[GSYM
TRUNCATE_SIMPLEX_INITIAL_SUBLIST] THEN
ASM_SIMP_TAC[ARITH_RULE `r <= k ==> r + 1 <= k + 1`];
ALL_TAC
] THEN
MP_TAC (ISPECL [`V:real^3->bool`; `k:num`; `zl:(real^3)list`; `xl:(real^3)list`]
BARV_INITIAL_SUBLIST) THEN
ASM_SIMP_TAC[ARITH_RULE `0 < r + 1`; ARITH_RULE `(r + 1) - 1 = r`]);;
let TRUNCATE_TRUNCATE_SIMPLEX = prove(`!(ul:(A)list) i j. i <= j /\ j + 1 <=
LENGTH ul ==>
truncate_simplex i (truncate_simplex j ul) = truncate_simplex i ul`,
REPEAT STRIP_TAC THEN
ABBREV_TAC `xl = truncate_simplex j (ul:(A)list)` THEN
SUBGOAL_THEN `i + 1 <=
LENGTH (xl:(A)list) /\ i + 1 <=
LENGTH (ul:(A)list) /\ initial_sublist (xl:(A)list) ul` STRIP_ASSUME_TAC THENL
[
POP_ASSUM (fun
th -> REWRITE_TAC[SYM
th]) THEN
MP_TAC (SPECL [`j:num`; `truncate_simplex j (ul:(A)list)`; `ul:(A)list`]
TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN
ASM_SIMP_TAC[] THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
ARITH_TAC;
ALL_TAC
] THEN
MP_TAC (SPECL [`i:num`; `truncate_simplex i (xl:(A)list)`; `xl:(A)list`]
TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN
MP_TAC (SPECL [`i:num`; `truncate_simplex i (ul:(A)list)`; `ul:(A)list`]
TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN
ASM_REWRITE_TAC[] THEN
REPEAT STRIP_TAC THEN
MATCH_MP_TAC
INITIAL_SUBLIST_UNIQUE THEN
MAP_EVERY EXISTS_TAC [`i + 1`; `ul:(A)list`] THEN
ASM_REWRITE_TAC[] THEN
MATCH_MP_TAC
INITIAL_SUBLIST_TRANS THEN
EXISTS_TAC `xl:(A)list` THEN
ASM_REWRITE_TAC[]);;
let TRUNCATE_SIMPLEX_ADD1 = prove(`!(ul:(A)list) k. k + 2 <=
LENGTH ul ==>
truncate_simplex (k + 1) ul =
APPEND (truncate_simplex k ul) [
LAST (truncate_simplex (k + 1) ul)]`,
REPEAT STRIP_TAC THEN
ABBREV_TAC `xl:(A)list = truncate_simplex (k + 1) ul` THEN
SUBGOAL_THEN `truncate_simplex k ul = truncate_simplex k xl:(A)list` (fun
th -> REWRITE_TAC[
th]) THENL
[
EXPAND_TAC "xl" THEN
MATCH_MP_TAC (GSYM
TRUNCATE_TRUNCATE_SIMPLEX) THEN
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
SUBGOAL_THEN `
LENGTH (xl:(A)list) = k + 2` ASSUME_TAC THENL
[
EXPAND_TAC "xl" THEN
REWRITE_TAC[ARITH_RULE `k + 2 = (k + 1) + 1`] THEN
MATCH_MP_TAC
LENGTH_TRUNCATE_SIMPLEX THEN
ASM_REWRITE_TAC[ARITH_RULE `(k + 1) + 1 = k + 2`];
ALL_TAC
] THEN
SUBGOAL_THEN `k =
LENGTH (xl:(A)list) - 2` (fun
th -> REWRITE_TAC[
th]) THENL
[
POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
MATCH_MP_TAC
LIST_EQ_TRUNCATE_SIMPLEX_APPEND_LAST THEN
POP_ASSUM MP_TAC THEN ARITH_TAC);;
let EL_TRUNCATE_SIMPLEX = prove(`!ul:(A)list k j. k + 1 <=
LENGTH ul /\ j <= k ==>
EL j (truncate_simplex k ul) =
EL j ul`,
REPEAT STRIP_TAC THEN
ABBREV_TAC `vl:(A)list = truncate_simplex k ul` THEN
SUBGOAL_THEN `?yl:(A)list. ul =
APPEND vl yl /\
LENGTH vl = k + 1` CHOOSE_TAC THENL
[
MP_TAC (SPECL [`k:num`; `vl:(A)list`; `ul:(A)list`]
TRUNCATE_SIMPLEX_INITIAL_SUBLIST) THEN
ASM_REWRITE_TAC[
INITIAL_SUBLIST] THEN
STRIP_TAC THEN
EXISTS_TAC `yl:(A)list` THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
ASM_REWRITE_TAC[
EL_APPEND; ARITH_RULE `j < k + 1 <=> j <= k`]);;
let TRUNCATE_SIMPLEX_ADD1_ALT = prove(`!ul:(A)list k. k + 2 <=
LENGTH ul
==> truncate_simplex (k + 1) ul =
APPEND (truncate_simplex k ul) [
EL (k + 1) ul]`,
REPEAT STRIP_TAC THEN
MP_TAC (SPEC_ALL
TRUNCATE_SIMPLEX_ADD1) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> ONCE_REWRITE_TAC[
th]) THEN
AP_TERM_TAC THEN
MP_TAC (SPECL [`k + 1`; `ul:(A)list`]
LENGTH_TRUNCATE_SIMPLEX) THEN
ASM_SIMP_TAC[ARITH_RULE `k + 2 <= a ==> (k + 1) + 1 <= a`] THEN
DISCH_TAC THEN
MP_TAC (ISPEC `(truncate_simplex (k + 1) ul:(A)list)`
LAST_EL) THEN
ASM_REWRITE_TAC[GSYM
LENGTH_EQ_NIL; ARITH_RULE `~(a + 1 = 0)`; ARITH_RULE `(a + 1) - 1 = a`] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
MP_TAC (SPECL [`ul:(A)list`; `k + 1`; `k + 1`]
EL_TRUNCATE_SIMPLEX) THEN
ASM_SIMP_TAC[ARITH_RULE `k + 2 <= a ==> (k + 1) + 1 <= a`;
LE_REFL]);;
(****************************************************)
(***************************************************************************)
(* Properties of voronoi_set (Omega(V, W)) and voronoi_list (Omega(V, vl)) *)
(***************************************************************************)
(* Equivalent definitions for intersections of one and two Voronoi cells *)
(* Omega(V, v) INTER Omega(V, u) *)
(* Omega(V, v) INTER A(u, v) *)
(* Omega(V, v) INTER A+(u, v) *)
(* The result for lists of arbitrary length *)
let VORONOI_LIST_BIS = prove(`!V ul (h:real^3) t.
set_of_list ul
SUBSET V /\ ul = CONS h t ==> voronoi_list V ul =
voronoi_closed V h
INTER (
INTERS {bis h u | u | u
IN set_of_list t})`,
REPEAT STRIP_TAC THEN
SUBGOAL_THEN `V (h:real^3) /\ (!u. u
IN set_of_list t ==> V u)` ASSUME_TAC THENL
[
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 ASM_REWRITE_TAC[] THEN
REWRITE_TAC[
set_of_list] THEN
SET_TAC[];
ALL_TAC
] THEN
REWRITE_TAC[
VORONOI_LIST;
VORONOI_SET; bis;
EXTENSION;
IN_INTER;
IN_INTERS;
IN_ELIM_THM] THEN
X_GEN_TAC `y:real^3` THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
[
FIRST_X_ASSUM (MP_TAC o SPEC `
voronoi_closed V (h:real^3)`) THEN
ASM_REWRITE_TAC[
set_of_list] THEN
ANTS_TAC THEN REWRITE_TAC[] THEN
EXISTS_TAC `h:real^3` THEN
REWRITE_TAC[
COMPONENT];
ASM_REWRITE_TAC[] THEN POP_ASSUM (fun
th -> ALL_TAC) THEN
SUBGOAL_THEN `y:real^3
IN voronoi_closed V h` ASSUME_TAC THENL
[
POP_ASSUM (fun
th -> ALL_TAC) THEN
POP_ASSUM (MP_TAC o SPEC `
voronoi_closed V (h:real^3)`) THEN
ANTS_TAC THEN REWRITE_TAC[] THEN
EXISTS_TAC `h:real^3` THEN
ASM_REWRITE_TAC[
set_of_list;
COMPONENT];
ALL_TAC
] THEN
SUBGOAL_THEN `y:real^3
IN voronoi_closed V u` ASSUME_TAC THENL
[
FIRST_X_ASSUM (MP_TAC o SPEC `
voronoi_closed V (u:real^3)` o check (is_forall o concl)) THEN
ANTS_TAC THEN REWRITE_TAC[] THEN
EXISTS_TAC `u:real^3` THEN
ASM_REWRITE_TAC[
set_of_list;
IN_INSERT];
ALL_TAC
] THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
REWRITE_TAC[
voronoi_closed;
IN_ELIM_THM] THEN
DISCH_THEN (ASSUME_TAC o SPEC `u:real^3`) THEN
DISCH_THEN (ASSUME_TAC o SPEC `h:real^3`) THEN
ASM_MESON_TAC[REAL_ARITH `a <= b /\ b <= a ==> a = b`];
ASM_REWRITE_TAC[
voronoi_closed;
IN_ELIM_THM] THEN GEN_TAC THEN
POP_ASSUM (fun
th -> ALL_TAC) THEN
POP_ASSUM MP_TAC THEN ASM_REWRITE_TAC[
set_of_list;
IN_INSERT] THEN
POP_ASSUM (MP_TAC o SPEC `bis h (v:real^3)`) THEN
POP_ASSUM MP_TAC THEN REWRITE_TAC[bis;
voronoi_closed;
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THENL
[
ASM_MESON_TAC[];
ALL_TAC
] THEN
FIRST_X_ASSUM (MP_TAC o check (is_imp o concl)) THEN
ANTS_TAC THENL
[
EXISTS_TAC `v:real^3` THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
ASM_MESON_TAC[]
]);;
(* Used below *)
(* Omega(V,h:t) = Omega(V,h) INTER INTERS {A+(u, h) | u IN t} *)
(* Voronoi list is bounded *)
(* Omega(V, h:t) INTER A(h, v) = Omega(V, (h:t) ++ [v]) *)
(* Canonical representations of Omega(V, vl) as a polyhedron *)
(* "Almost canonical" polyhedron representation for Omega(V, ul) *)
(* For a canonical polyhedron representation we need to find a minimal intersection *)
(* Lemma about minimal intersection *)
(* The proof is a modification of the proof of POLYHEDRON_INTER_AFFINE_MINIMAL *)
let MINIMAL_INTERS_EXISTS = prove(`!(s:A->bool) f. FINITE f /\ s =
INTERS f ==> (?g. g
SUBSET f /\ s =
INTERS g /\ (!g'. g'
PSUBSET g ==> s
PSUBSET INTERS g'))`,
REPEAT GEN_TAC THEN
DISCH_THEN (MP_TAC o (fun
th -> MATCH_MP
lemma1 th)) THEN
GEN_REWRITE_TAC LAND_CONV [
num_WOP] THEN
DISCH_THEN(X_CHOOSE_THEN `n:num` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
MATCH_MP_TAC
MONO_EXISTS THEN
SIMP_TAC[
HAS_SIZE; GSYM
CONJ_ASSOC] THEN
X_GEN_TAC `g:(A->bool)->bool` THEN STRIP_TAC THEN
X_GEN_TAC `g':(A->bool)->bool` THEN DISCH_TAC THEN
FIRST_X_ASSUM(MP_TAC o SPEC `
CARD(g':(A->bool)->bool)`) THEN
ANTS_TAC THENL [ASM_MESON_TAC[
CARD_PSUBSET]; ALL_TAC] THEN
REWRITE_TAC[
NOT_EXISTS_THM;
HAS_SIZE] THEN
DISCH_THEN(MP_TAC o SPEC `g':(A->bool)->bool`) THEN
MATCH_MP_TAC(TAUT `a /\ b /\ (~c ==> d) ==> ~(a /\ b /\ c) ==> d`) THEN
CONJ_TAC THENL [ASM_MESON_TAC[
PSUBSET;
SUBSET_TRANS]; ALL_TAC] THEN
CONJ_TAC THENL [ASM_MESON_TAC[
PSUBSET;
FINITE_SUBSET]; ALL_TAC] THEN
ASM_REWRITE_TAC[] THEN
MATCH_MP_TAC(SET_RULE `s
SUBSET t ==> ~(s = t) ==> s
PSUBSET t`) THEN
FIRST_X_ASSUM MP_TAC THEN
SET_TAC[]);;
(* Variation of the previous lemma: the proof is exactly the same *)
(* Canonical polyhedron representation for Omega(V, ul) *)
let VORONOI_LIST_CANONICAL = prove(`!V ul (h:real^3) t. packing V /\ saturated V /\
set_of_list ul
SUBSET V /\ ul = CONS h t
==> ?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 = h) /\ (a =
bis_le v h \/ a =
bis_le h v))) /\
(!K'. K'
PSUBSET K ==> voronoi_list V ul
PSUBSET affine hull (voronoi_list V ul)
INTER INTERS K')`,
REPEAT GEN_TAC THEN
DISCH_THEN (MP_TAC o (fun
th -> MATCH_MP
VORONOI_LIST_ALMOST_CANONICAL th)) THEN
STRIP_TAC THEN
REPLICATE_TAC 3 (POP_ASSUM MP_TAC) THEN
DISCH_THEN (LABEL_TAC "A") THEN
DISCH_THEN (LABEL_TAC "B") THEN
DISCH_THEN (LABEL_TAC "C") THEN
MP_TAC (ISPECL [`voronoi_list (V:real^3->bool) ul`; `
affine hull (voronoi_list (V:real^3->bool) ul)`; `K:(real^3->bool)->bool`]
MINIMAL_INTER_INTERS_EXISTS) THEN
USE_THEN "A" (fun
th -> REWRITE_TAC[
th]) THEN
ANTS_TAC THENL
[
ASM_MESON_TAC[];
ALL_TAC
] THEN
STRIP_TAC THEN
EXISTS_TAC `g:(real^3->bool)->bool` THEN
ASM_REWRITE_TAC[] THEN
REPEAT STRIP_TAC THENL
[
ASM_MESON_TAC[
FINITE_SUBSET];
ASM_MESON_TAC[];
POP_ASSUM MP_TAC THEN
REPLICATE_TAC 2 (POP_ASSUM (fun
th -> ALL_TAC)) THEN
REPLICATE_TAC 2 (POP_ASSUM MP_TAC) THEN
REWRITE_TAC[
SUBSET] THEN MESON_TAC[]
]);;
(* voronoi_list is a polyhedron *)
(* voronoi_list is a polytope *)
(* closed (voronoi_list V ul) *)
(* convex (voronoi_list V ul) *)
(* aff_dim voronoi_list *)
(* voronoi_list V vl SUBSET voronoi_closed V (HD vl) *)
(************************************************************)
(*****************************************************)
(* General properties of omega_list_n and omega_list *)
(*****************************************************)
(* omega_k(u) = omega_k (d_(k+i) u) *)
let OMEGA_LIST_N_LEMMA = prove(`!V ul k i. k + i + 1 <=
LENGTH ul ==> omega_list_n V ul k = omega_list_n V (truncate_simplex (k + i) ul) k`,
GEN_TAC THEN GEN_TAC THEN
INDUCT_TAC THEN REWRITE_TAC[
OMEGA_LIST_N] THEN REPEAT STRIP_TAC THENL
[
MATCH_MP_TAC (GSYM
HD_TRUNCATE_SIMPLEX) THEN
POP_ASSUM MP_TAC THEN ARITH_TAC;
ALL_TAC
] THEN
MP_TAC (ISPECL [`ul:(real^3)list`; `SUC k`; `SUC k + i`]
TRUNCATE_TRUNCATE_SIMPLEX) THEN
ASM_REWRITE_TAC[ARITH_RULE `a:num <= a + i`; ARITH_RULE `(a + b) + 1 = a + b + 1`] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
AP_TERM_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `i + 1`) THEN
ASM_REWRITE_TAC[ARITH_RULE `k + (i + 1) + 1 = SUC k + i + 1`] THEN
SIMP_TAC[ARITH_RULE `k + i + 1 = SUC k + i`]);;
(* omega(d_k u) = omega_k (u) *)
(* omega_i IN voronoi_list V (d_i ul) *)
(* omega ul IN voronoi_list V ul *)
end;;