(* ========================================================================= *)
(* Various convenient background stuff. *)
(* *)
(* (c) Copyright, John Harrison 1998-2008 *)
(* ========================================================================= *)
prioritize_real();;
(* ------------------------------------------------------------------------- *)
(* A couple of extra tactics used in some proofs below. *)
(* ------------------------------------------------------------------------- *)
let ASSERT_TAC tm =
SUBGOAL_THEN tm STRIP_ASSUME_TAC;;
let EQ_TRANS_TAC tm =
MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC tm THEN CONJ_TAC;;
(* ------------------------------------------------------------------------- *)
(* Miscellaneous lemmas. *)
(* ------------------------------------------------------------------------- *)
let SEQ_MONO_LEMMA = prove
(`!d e. (!n. n >= m ==> d(n) < e(n)) /\ (!n. n >= m ==> e(n) <= e(m))
==> !n:num. n >= m ==> d(n) < e(m)`,
let REAL_HALF = prove
(`(!e. &0 < e / &2 <=> &0 < e) /\
(!e. e / &2 + e / &2 = e) /\
(!e. &2 * (e / &2) = e)`,
REAL_ARITH_TAC);;
let TRIANGLE_LEMMA = prove
(`!x y z. &0 <= x /\ &0 <= y /\ &0 <= z /\ x pow 2 <= y pow 2 + z pow 2
==> x <= y + z`,
REPEAT GEN_TAC THEN
REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
REWRITE_TAC[
REAL_NOT_LE] THEN DISCH_TAC THEN
MATCH_MP_TAC
REAL_LET_TRANS THEN EXISTS_TAC `(y + z) pow 2` THEN
ASM_SIMP_TAC[
REAL_POW_LT2;
REAL_LE_ADD;
ARITH_EQ] THEN
ASM_SIMP_TAC[
REAL_LE_MUL; REAL_POW_2; REAL_ARITH
`x * x + y * y <= (x + y) * (x + y) <=> &0 <= x * y`]);;
let EPSILON_DELTA_MINIMAL = prove
(`!P:real->A->bool Q.
FINITE {x | Q x} /\
(!d e x. Q x /\ &0 < e /\ e < d ==> P d x ==> P e x) /\
(!x. Q x ==> ?d. &0 < d /\ P d x)
==> ?d. &0 < d /\ !x. Q x ==> P d x`,
(* ------------------------------------------------------------------------- *)
(* A generic notion of "hull" (convex, affine, conic hull and closure). *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("hull",(21,"left"));;
let HULL_IMAGE = prove
(`!P f s. (!s. P(P
hull s)) /\ (!s. P(
IMAGE f s) <=> P s) /\
(!x y:A. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
==> P
hull (
IMAGE f s) =
IMAGE f (P
hull s)`,
REPEAT GEN_TAC THEN
REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
REWRITE_TAC[
BIJECTIVE_LEFT_RIGHT_INVERSE] THEN
DISCH_THEN(X_CHOOSE_THEN `g:A->A` STRIP_ASSUME_TAC) THEN
MATCH_MP_TAC
HULL_IMAGE_GALOIS THEN EXISTS_TAC `g:A->A` THEN
ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
X_GEN_TAC `s:A->bool` THEN
FIRST_X_ASSUM(fun
th -> GEN_REWRITE_TAC RAND_CONV [GSYM
th]) THEN
MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
(* ------------------------------------------------------------------------- *)
(* More variants of the Archimedian property and useful consequences. *)
(* ------------------------------------------------------------------------- *)
let REAL_ARCH_POW = prove
(`!x y. &1 < x ==> ?n. y < x pow n`,
REPEAT STRIP_TAC THEN
MP_TAC(SPEC `x - &1`
REAL_ARCH) THEN ASM_REWRITE_TAC[
REAL_SUB_LT] THEN
DISCH_THEN(MP_TAC o SPEC `y:real`) THEN MATCH_MP_TAC
MONO_EXISTS THEN
X_GEN_TAC `n:num` THEN DISCH_TAC THEN MATCH_MP_TAC
REAL_LTE_TRANS THEN
EXISTS_TAC `&1 + &n * (x - &1)` THEN
ASM_SIMP_TAC[REAL_ARITH `x < y ==> x < &1 + y`] THEN
ASM_MESON_TAC[
REAL_POW_LBOUND;
REAL_SUB_ADD2; REAL_ARITH
`&1 < x ==> &0 <= x - &1`]);;
let FORALL_POS_MONO = prove
(`!P. (!d e. d < e /\ P d ==> P e) /\ (!n. ~(n = 0) ==> P(inv(&n)))
==> !e. &0 < e ==> P e`,
(* ------------------------------------------------------------------------- *)
(* Relate max and min to sup and inf. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Define square root here to decouple it from the existing analysis theory. *)
(* ------------------------------------------------------------------------- *)
let sqrt = new_definition
`sqrt(x) = @y. &0 <= y /\ (y pow 2 = x)`;;
let SQRT_UNIQUE = prove
(`!x y. &0 <= y /\ (y pow 2 = x) ==> (
sqrt(x) = y)`,
REPEAT STRIP_TAC THEN REWRITE_TAC[
sqrt] THEN MATCH_MP_TAC
SELECT_UNIQUE THEN
FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[REAL_POW_2] THEN
REWRITE_TAC[REAL_ARITH `(x * x = y * y) <=> ((x + y) * (x - y) = &0)`] THEN
REWRITE_TAC[
REAL_ENTIRE] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
(* ------------------------------------------------------------------------- *)
(* Geometric progression. *)
(* ------------------------------------------------------------------------- *)
let SUM_GP = prove
(`!x m n.
sum(m..n) (\i. x pow i) =
if n < m then &0
else if x = &1 then &((n + 1) - m)
else (x pow m - x pow (SUC n)) / (&1 - x)`,
let SUM_GP_OFFSET = prove
(`!x m n.
sum(m..m+n) (\i. x pow i) =
if x = &1 then &n + &1
else x pow m * (&1 - x pow (SUC n)) / (&1 - x)`,
REPEAT GEN_TAC THEN REWRITE_TAC[
SUM_GP; ARITH_RULE `~(m + n < m:num)`] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
[REWRITE_TAC[REAL_OF_NUM_ADD] THEN AP_TERM_TAC THEN ARITH_TAC;
REWRITE_TAC[
real_div;
real_pow;
REAL_POW_ADD] THEN REAL_ARITH_TAC]);;
(* ------------------------------------------------------------------------- *)
(* Segment of natural numbers starting at a specific number. *)
(* ------------------------------------------------------------------------- *)
let from = new_definition
`from n = {m:num | n <= m}`;;