(* ========================================================================== *)
(* FLYSPECK - BOOK FORMALIZATION *)
(* *)
(* Author: Thomas C. Hales *)
(* Date: 2013-02-11 *)
(* ========================================================================== *)
(* General lemmas *)
module Basics = struct
open Hales_tactic;;
(* SECTION: LOGIC *)
(* }}} *)
(* SECTION: SETS *)
(* }}} *)
let BIJ_INVERSE = prove_by_refinement(
`!a b (f:A->B). (
SURJ f a b) ==> (?(g:B->A). (
INJ g b a))`,
(* {{{ proof *)
[
REPEAT WEAKER_STRIP_TAC;
TYPIFY `!y. ?u. ((y
IN b) ==> ((u
IN a) /\ ((f:A->B) u = y)))` (C SUBGOAL_THEN ASSUME_TAC);
BY(ASM_MESON_TAC[
SURJ]);
FIRST_X_ASSUM (MP_TAC o (REWRITE_RULE[
SKOLEM_THM]));
REPEAT WEAKER_STRIP_TAC;
EXISTS_TAC `u:B->A`;
REWRITE_TAC[
INJ];
BY(ASM_MESON_TAC[])
]
(* }}} *)
);;
(* }}} *)
(* SECTION: LISTS *)
let EL_EXPLICIT = prove_by_refinement(
`!h t.
EL 0 (CONS (h:a) t) = h /\
EL 1 (CONS h t) =
EL 0 t /\
EL 2 (CONS h t) =
EL 1 t /\
EL 3 (CONS h t) =
EL 2 t /\
EL 4 (CONS h t) =
EL 3 t /\
EL 5 (CONS h t) =
EL 4 t /\
EL 6 (CONS h t) =
EL 5 t`,
(* {{{ proof *)
[
BY(REWRITE_TAC[
EL;
HD;
TL;arith `6 = SUC 5 /\ 5 = SUC 4 /\ 4 = SUC 3 /\ 3 = SUC 2 /\ 2 = SUC 1 /\ 1 = SUC 0`])
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let LENGTH4 = prove_by_refinement(
`!(ul:(A)list).
LENGTH ul = 4 ==> ul = [
EL 0 ul;
EL 1 ul;
EL 2 ul;
EL 3 ul]`,
(* {{{ proof *)
[
REWRITE_TAC[
LENGTH_EQ_CONS;arith `4 = SUC 3`];
REPEAT WEAK_STRIP_TAC;
ASM_REWRITE_TAC[];
FIRST_X_ASSUM (unlist ONCE_REWRITE_TAC o (MATCH_MP
LENGTH3));
BY(REWRITE_TAC[
EL;
HD;arith `1 = SUC 0`;arith `2 = SUC 1`;arith `3 = SUC 2`;
TL])
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let INITIAL_SUBLIST_CONS = prove_by_refinement(
`!(a:A) b x y. initial_sublist (CONS a x) (CONS b y) <=> (a = b) /\ initial_sublist x y`,
(* {{{ proof *)
[
REWRITE_TAC[Sphere.INITIAL_SUBLIST];
REPEAT WEAKER_STRIP_TAC;
REWRITE_TAC[
APPEND];
REWRITE_TAC[
CONS_11];
BY(MESON_TAC[])
]);;
(* }}} *)
let INITIAL_SUBLIST_TRANS = prove(`!(xl:(A)list) yl zl. initial_sublist xl yl /\ initial_sublist yl zl ==> initial_sublist xl zl`,
REWRITE_TAC[Sphere.INITIAL_SUBLIST] THEN
REPEAT STRIP_TAC THEN
ASM_MESON_TAC[
APPEND_ASSOC]);;
(* truncate simplex *)
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 TRUNCATE_SIMPLEX_EXISTS = prove_by_refinement(
`!k ul:(A)list. k+1 <=
LENGTH ul ==> (?vl.
LENGTH vl = k+1 /\ initial_sublist vl ul)`,
(* {{{ proof *)
[
TYPIFY `!r k (ul:(A)list). k + 1 <=
LENGTH ul /\
LENGTH ul = r ==> (?vl.
LENGTH vl = k + 1 /\ initial_sublist vl ul)` ENOUGH_TO_SHOW_TAC;
BY(MESON_TAC[]);
INDUCT_TAC;
REPEAT WEAKER_STRIP_TAC;
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC);
REPEAT WEAKER_STRIP_TAC;
TYPIFY `SUC r = k + 1` ASM_CASES_TAC;
TYPIFY `ul` EXISTS_TAC;
REWRITE_TAC[
INITIAL_SUBLIST_REFL];
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC);
FIRST_X_ASSUM (C INTRO_TAC [`k`;`
BUTLAST ul`]);
ANTS_TAC;
INTRO_TAC
LENGTH_BUTLAST [`ul`];
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC);
REPEAT WEAKER_STRIP_TAC;
TYPIFY `vl` EXISTS_TAC;
ASM_REWRITE_TAC[];
MATCH_MP_TAC
INITIAL_SUBLIST_TRANS;
TYPIFY `
BUTLAST ul` EXISTS_TAC;
ASM_REWRITE_TAC[];
MATCH_MP_TAC
BUTLAST_INITIAL_SUBLIST;
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC)
]);;
(* }}} *)
let TRUNCATE_SIMPLEX_PROP = prove_by_refinement(
`!k ul:(A)list. k + 1 <=
LENGTH ul ==>
LENGTH (truncate_simplex k ul) = k + 1 /\ initial_sublist (truncate_simplex k ul) ul`,
(* {{{ proof *)
[
REPEAT WEAKER_STRIP_TAC;
INTRO_TAC
TRUNCATE_SIMPLEX_EXISTS [`k`;`ul`];
ASM_REWRITE_TAC[];
REPEAT WEAKER_STRIP_TAC;
REWRITE_TAC[Sphere.TRUNCATE_SIMPLEX];
SELECT_TAC THEN ASM_REWRITE_TAC[];
BY(ASM_MESON_TAC[]);
BY(ASM_MESON_TAC[])
]);;
(* }}} *)
(* }}} *)
(* }}} *)
let INITIAL_SUBLIST_INJ = prove_by_refinement(
`!ul:(A) list vl wl.
LENGTH ul =
LENGTH vl /\ initial_sublist ul wl /\ initial_sublist vl wl ==>
(ul = vl)`,
(* {{{ proof *)
[
TYPIFY `!k (ul:(A) list) vl wl. k =
LENGTH ul /\ k =
LENGTH vl /\ initial_sublist ul wl /\ initial_sublist vl wl ==> (ul = vl)` ENOUGH_TO_SHOW_TAC;
BY(MESON_TAC[]);
INDUCT_TAC;
BY(MESON_TAC[
LENGTH_EQ_NIL]);
REPEAT WEAKER_STRIP_TAC;
INTRO_TAC
LENGTH_IMP_CONS [`ul`];
INTRO_TAC
LENGTH_IMP_CONS [`vl`];
ANTS_TAC;
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC);
STRIP_TAC;
ANTS_TAC;
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC);
STRIP_TAC;
TYPIFY `
LENGTH wl = 0` ASM_CASES_TAC;
BY(ASM_MESON_TAC[
LENGTH_EQ_NIL;
INITIAL_SUBLIST_OF_NIL;
NOT_CONS_NIL]);
INTRO_TAC
LENGTH_IMP_CONS [`wl`];
ANTS_TAC;
BY(REPEAT (FIRST_X_ASSUM MP_TAC) THEN ARITH_TAC);
REPEAT WEAKER_STRIP_TAC;
ASM_REWRITE_TAC[
CONS_11];
PROOF_BY_CONTR_TAC;
REPEAT (FIRST_X_ASSUM_ST `initial_sublist` MP_TAC);
ASM_REWRITE_TAC[
INITIAL_SUBLIST_CONS];
REPEAT WEAKER_STRIP_TAC;
FIRST_X_ASSUM (C INTRO_TAC [`t`;`t'`;`t''`]);
ANTS_TAC;
ASM_REWRITE_TAC[];
REPEAT (FIRST_X_ASSUM_ST `
LENGTH` MP_TAC);
ASM_REWRITE_TAC[
LENGTH;
SUC_INJ];
BY(MESON_TAC[]);
DISCH_TAC;
FIRST_X_ASSUM_ST `~` MP_TAC;
BY(ASM_REWRITE_TAC[])
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let TRUNCATE_SIMPLEX_EXPLICIT = prove_by_refinement(
`!(x1:A) x2 x3 x4. truncate_simplex 3 [x1;x2;x3;x4] = [x1;x2;x3;x4] /\
truncate_simplex 2 [x1;x2;x3;x4] = [x1;x2;x3] /\
truncate_simplex 2 [x1;x2;x3] = [x1;x2;x3] /\
truncate_simplex 1 [x1;x2;x3;x4] = [x1;x2] /\
truncate_simplex 1 [x1;x2;x3] = [x1;x2] /\
truncate_simplex 1 [x1;x2] = [x1;x2]`,
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
end;;