override_interface ("-->",`(tends_num_real)`);;
prioritize_real();;
(* ---------------------------------------------------------------------- *)
(* properites of num sequences *)
(* ---------------------------------------------------------------------- *)
(* }}} *)
let LIM_INV_CONST = prove_by_refinement(
`!c. (\n. c / &n) --> &0`,
(* {{{ Proof *)
[
ONCE_REWRITE_TAC[REAL_ARITH `c / &n = c * &1 / &n`];
STRIP_TAC;
CONV_TAC (RAND_CONV (ONCE_REWRITE_CONV[REAL_ARITH `&0 = c * &0`]));
MATCH_MP_TAC
SEQ_MUL;
CONJ_TAC THENL [MATCH_ACCEPT_TAC
SEQ_CONST;MATCH_ACCEPT_TAC
LIM_INV_1N];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let LIM_MONO = prove_by_refinement(
`!c d a b. ~(d = &0) /\ a < b ==> (\n. (c * &n pow a) / (d * &n pow b)) --> &0`,
(* {{{ Proof *)
[
STRIP_TAC THEN STRIP_TAC;
INDUCT_TAC;
REPEAT STRIP_TAC;
REWRITE_TAC[
real_pow;
REAL_MUL_RID];
POP_ASSUM MP_TAC THEN MATCH_ACCEPT_TAC
LIM_INV_CON;
REPEAT STRIP_TAC;
REWRITE_TAC[
real_pow];
CLAIM `(b = SUC(
PRE b))`;
POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ONCE_ASM_REWRITE_TAC[];
REWRITE_TAC[
real_pow];
ONCE_REWRITE_TAC[ARITH_RULE `a * b * c = b * a * c`];
ONCE_REWRITE_TAC[
REAL_DIV_DISTRIB_2];
ONCE_REWRITE_TAC[REAL_ARITH `&0 = &1 * &0`];
MATCH_MP_TAC
SEQ_MUL;
CONJ_TAC;
MATCH_ACCEPT_TAC
LIM_NN;
FIRST_ASSUM MATCH_MP_TAC;
ASM_REWRITE_TAC[];
LABEL_ALL_TAC;
USE_THEN "Z-1" MP_TAC;
ARITH_TAC;
]);;
(* }}} *)
let LIM_POLY_LT = prove_by_refinement(
`!p k.
LENGTH p <= k ==> (\n. poly p (&n) / &n pow k) --> &0`,
(* {{{ Proof *)
[
LIST_INDUCT_TAC;
REWRITE_TAC[poly;
LENGTH];
REPEAT STRIP_TAC;
REWRITE_TAC[
REAL_DIV_LZERO;
SEQ_CONST];
REWRITE_TAC[poly;
LENGTH];
REPEAT STRIP_TAC;
CLAIM `~(k = 0)`;
POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
LABEL_ALL_TAC;
CLAIM `
LENGTH t <=
PRE k`;
USE_THEN "Z-1" MP_TAC THEN ARITH_TAC;
DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
STRIP_TAC;
REWRITE_TAC[
REAL_DIV_ADD_DISTRIB];
ONCE_REWRITE_TAC[REAL_ARITH `&0 = &0 + &0`];
MATCH_MP_TAC
SEQ_ADD;
CONJ_TAC;
ONCE_REWRITE_TAC[ARITH_RULE `n pow k = &1 * n pow k`];
MATCH_MP_TAC
LIM_INV_CON;
USE_THEN "Z-0" MP_TAC THEN ARITH_TAC;
CLAIM `k = SUC (
PRE k)`;
USE_THEN "Z-0" MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ONCE_ASM_REWRITE_TAC[];
REWRITE_TAC[
real_pow];
REWRITE_TAC[
REAL_DIV_DISTRIB_2];
ONCE_REWRITE_TAC[REAL_ARITH `&0 = &1 * &0`];
MATCH_MP_TAC
SEQ_MUL;
CONJ_TAC;
MATCH_ACCEPT_TAC
LIM_NN;
FIRST_ASSUM MATCH_MP_TAC;
USE_THEN "Z-1" MP_TAC THEN ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
let mono_inc = new_definition(
`mono_inc (f:num -> real) = !(m:num) n. m <= n ==> f m <= f n`);;
let mono_dec = new_definition(
`mono_dec (f:num -> real) = !(m:num) n. m <= n ==> f n <= f m`);;
(* }}} *)
(* }}} *)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Unbounded sequences *)
(* ---------------------------------------------------------------------- *)
(* }}} *)
let mono_unbounded_below_neg = prove_by_refinement(
`
mono_unbounded_below (f:num -> real) = !c. c <= &0 ==> ?N. !n. N <= n ==> f n < c`,
(* {{{ Proof *)
[
REWRITE_TAC[
mono_unbounded_below];
EQ_TAC THENL [ASM_MESON_TAC[];ALL_TAC];
REPEAT STRIP_TAC;
POP_ASSUM (ASSUME_TAC o ISPEC `-- (abs c)`);
POP_ASSUM (MP_TAC o (C MATCH_MP) (ISPEC `c:real`
NEG_ABS));
STRIP_TAC;
EXISTS_TAC `N`;
GEN_TAC;
DISCH_THEN (fun x -> POP_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x)));
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let mua_quotient_limit = prove_by_refinement(
`!k f g. &0 < k /\ (\n. f n / g n) --> k /\
mono_unbounded_above g
==>
mono_unbounded_above f`,
(* {{{ Proof *)
[
REWRITE_TAC[
SEQ;
mono_unbounded_above_pos;AND_IMP_THM];
REPEAT GEN_TAC;
STRIP_TAC;
CLAIM `&0 < k / &2`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
DISCH_THEN (fun x -> DISCH_THEN (fun y -> (ASSUME_TAC (MATCH_MP (ISPEC `k / &2` y) x))));
POP_ASSUM (X_CHOOSE_TAC `M:num`);
STRIP_TAC;
X_GEN_TAC `d:real`;
STRIP_TAC;
CLAIM `&0 <= &2 * d / k`;
MATCH_MP_TAC
REAL_LE_MUL;
CONJ_TAC THENL [REAL_ARITH_TAC;ALL_TAC];
MATCH_MP_TAC
REAL_LE_DIV;
CONJ_TAC THENL [FIRST_ASSUM MATCH_ACCEPT_TAC;ASM_MESON_TAC[
REAL_LT_LE]];
STRIP_TAC;
LABEL_ALL_TAC;
MOVE_TO_FRONT "Z-2";
POP_ASSUM (fun x -> USE_THEN "Z-0" (fun y -> MP_TAC (MATCH_MP x y)));
DISCH_THEN (X_CHOOSE_TAC `K:num`);
EXISTS_TAC `nmax M K`;
REPEAT STRIP_TAC;
CLAIM `M <= n /\ K <= (n:num)`;
POP_ASSUM MP_TAC THEN REWRITE_TAC[nmax] THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
RULE_ASSUM_TAC (REWRITE_RULE[GE]);
FIRST_X_ASSUM (fun x -> FIRST_X_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x)));
FIRST_X_ASSUM (fun x -> FIRST_X_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x)));
RULE_ASSUM_TAC (REWRITE_RULE[real_div]);
CASES_ON `k <= f n * inv (g n)`;
MATCH_MP_TAC (prove(`d <= &2 * d /\ &2 * d < k * (g n) /\ k * (g n) <= f n ==> d < f n`,MESON_TAC !REAL_REWRITES));
REPEAT STRIP_TAC;
USE_THEN "Z-1" MP_TAC THEN REAL_ARITH_TAC;
FIRST_ASSUM (fun x -> ASSUME_TAC (MATCH_MP (REWRITE_RULE[AND_IMP_THM] REAL_LT_LMUL) x));
LABEL_ALL_TAC;
POP_ASSUM (fun y -> USE_THEN "Z-6" (fun x -> ASSUME_TAC (MATCH_MP y x)));
CLAIM `k * &2 * d * inv k = (k * inv k) * &2 * d`;
REAL_ARITH_TAC;
CLAIM `k * inv k = &1`;
ASM_MESON_TAC[REAL_MUL_RINV;REAL_LT_NZ];
STRIP_TAC;
ASM_REWRITE_TAC[REAL_MUL_LID];
ASM_MESON_TAC[];
(* *)
MATCH_MP_TAC REAL_LE_RCANCEL_IMP;
EXISTS_TAC `inv (g n)`;
REWRITE_TAC[GSYM REAL_MUL_ASSOC];
CLAIM `&0 < inv (g n)`;
CLAIM `&0 < inv k`;
MATCH_MP_TAC REAL_LT_INV THEN FIRST_ASSUM MATCH_ACCEPT_TAC;
STRIP_TAC;
CLAIM `&0 < g n`;
ASM_MESON_TAC !REAL_REWRITES;
STRIP_TAC;
ASM_MESON_TAC[REAL_LT_INV];
STRIP_TAC;
ASM_REWRITE_TAC[];
CLAIM `g n * inv (g n) = &1`;
ASM_MESON_TAC[REAL_MUL_RINV;REAL_LT_NZ;REAL_LT_INV_EQ];
DISCH_THEN SUBST1_TAC;
REWRITE_TAC[REAL_MUL_RID];
FIRST_ASSUM MATCH_ACCEPT_TAC;
(* *)
RULE_ASSUM_TAC (REWRITE_RULE[REAL_NOT_LE]);
CLAIM `f n * inv (g n) - k < &0`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `abs (f n * inv (g n) - k) = k - (f n * inv (g n))`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
DISCH_THEN (RULE_ASSUM_TAC o REWRITE_RULE o list);
CLAIM `k * inv(&2) < f n * inv (g n)`;
LABEL_ALL_TAC;
USE_THEN "Z-5" MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `k * g n < &2 * f n`;
CLAIM `&0 < g n`;
LABEL_ALL_TAC;
MATCH_MP_TAC REAL_LET_TRANS;
EXISTS_TAC `&2 * d * inv k`;
CONJ_TAC THEN FIRST_ASSUM MATCH_ACCEPT_TAC;
STRIP_TAC;
MATCH_MP_TAC REAL_LT_LCANCEL_IMP;
EXISTS_TAC `inv(&2)`;
CONJ_TAC THENL [REAL_ARITH_TAC;ALL_TAC];
REWRITE_TAC[ARITH_RULE `inv(&2) * &2 = &1`;REAL_MUL_LID;REAL_MUL_ASSOC];
MATCH_MP_TAC REAL_LT_LCANCEL_IMP;
EXISTS_TAC `inv(g n)`;
CONJ_TAC;
ASM_MESON_TAC[REAL_LT_INV];
ONCE_REWRITE_TAC[ARITH_RULE `a * (b * c) * d = c * b * (d * a)`];
CLAIM `g n * inv (g n) = &1`;
POP_ASSUM MP_TAC THEN ASM_MESON_TAC[REAL_MUL_RINV;REAL_POS_NZ];
DISCH_THEN SUBST1_TAC;
ASM_MESON_TAC[REAL_MUL_RID;REAL_MUL_SYM];
STRIP_TAC;
CLAIM `&2 * d < k * g n`;
MATCH_MP_TAC REAL_LT_RCANCEL_IMP;
EXISTS_TAC `inv k`;
STRIP_TAC;
ASM_MESON_TAC[REAL_LT_INV];
MATCH_MP_TAC REAL_LTE_TRANS;
EXISTS_TAC `g n`;
CONJ_TAC;
REWRITE_TAC[GSYM REAL_MUL_ASSOC];
FIRST_ASSUM MATCH_ACCEPT_TAC;
LABEL_ALL_TAC;
ONCE_REWRITE_TAC[ARITH_RULE `(a * b) * c = b * (a * c)`];
CLAIM `k * inv k = &1`;
ASM_MESON_TAC[REAL_MUL_RINV;REAL_POS_NZ];
DISCH_THEN SUBST1_TAC;
REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `&2 * d < &2 * f n`;
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
REAL_ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Polynomial properties *)
(* ---------------------------------------------------------------------- *)
(* }}} *)
let NORMALIZE_PAIR = prove_by_refinement(
`!x y. ~(y = &0) <=> (normalize [x; y] = [x; y])`,
(* {{{ Proof *)
[
REWRITE_TAC[normalize;
NOT_CONS_NIL];
REPEAT GEN_TAC;
COND_CASES_TAC;
CLAIM `y = &0`;
ASM_MESON_TAC !LIST_REWRITES;
DISCH_THEN SUBST1_TAC;
ASM_MESON_TAC !LIST_REWRITES;
ASM_MESON_TAC !LIST_REWRITES;
]);;
(* }}} *)
let POLY_NORMALIZE = prove
(`!p. poly (normalize p) = poly p`,
(* {{{ Proof *)
LIST_INDUCT_TAC THEN REWRITE_TAC[normalize; poly] THEN
ASM_CASES_TAC `h = &0` THEN ASM_REWRITE_TAC[] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[poly;
FUN_EQ_THM] THEN
UNDISCH_TAC `poly (normalize t) = poly t` THEN
DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[poly] THEN
REWRITE_TAC[
REAL_MUL_RZERO; REAL_ADD_LID]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let LIM_POLY2 = prove_by_refinement(
`!p. normal p ==> (\n. poly p (&n) / (
LAST p * &n pow (degree p))) --> &1`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
REWRITE_TAC[degree];
CLAIM `normalize p = p`;
ASM_MESON_TAC[normal];
DISCH_THEN SUBST1_TAC;
MATCH_MP_TAC
LIM_POLY;
ASM_MESON_TAC[
NORMAL_ID];
]);;
(* }}} *)
(* }}} *)
POP_ASSUM (fun x -> MP_TAC (MATCH_MP POW_UNB x));
REWRITE_TAC[mono_unbounded_above];
DISCH_THEN (MP_TAC o ISPEC `inv a * c`);
STRIP_TAC;
EXISTS_TAC `N`;
STRIP_TAC;
DISCH_THEN (fun x -> POP_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x)));
CLAIM `inv a * a = &1`;
MATCH_MP_TAC REAL_MUL_LINV;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
MATCH_MP_TAC REAL_LT_LCANCEL_IMP;
EXISTS_TAC `inv a`;
CONJ_TAC;
ASM_MESON_TAC[REAL_LT_INV];
ASM_REWRITE_TAC[REAL_MUL_ASSOC;REAL_MUL_LID];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
let POLY_LAST_GT = prove_by_refinement(
`!p. normal p /\ (?X. !x. X < x ==> &0 < poly p x) ==> &0 <
LAST p`,
(* {{{ Proof *)
[
GEN_TAC;
CASES_ON `
LENGTH p = 1`;
RULE_ASSUM_TAC (REWRITE_RULE[
LENGTH_1]);
POP_ASSUM MP_TAC THEN STRIP_TAC;
ASM_REWRITE_TAC[
LAST_SING;
POLY_SING];
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
EXISTS_TAC `X + &1`;
REAL_ARITH_TAC;
(* *)
REWRITE_TAC[AND_IMP_THM;];
DISCH_THEN (fun x -> MP_TAC (MATCH_MP
LIM_POLY2 x) THEN ASSUME_TAC x);
REPEAT STRIP_TAC;
DISJ_CASES_TAC (ISPECL [`&0`;`
LAST (p:real list)`]
REAL_LT_TOTAL);
ASM_MESON_TAC[
NORMAL_ID];
POP_ASSUM DISJ_CASES_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
(* save *)
CLAIM `
mono_unbounded_below (\n.
LAST p * &n pow degree p)`;
MATCH_MP_TAC
POW_UNBB_CON;
REWRITE_TAC[degree];
CONJ_TAC THENL [ALL_TAC;FIRST_ASSUM MATCH_ACCEPT_TAC];
CLAIM `normalize p = p`;
ASM_MESON_TAC[normal];
DISCH_THEN SUBST1_TAC;
CLAIM `~(
LENGTH p = 0)`;
ASM_MESON_TAC[normal;
LENGTH_EQ_NIL];
LABEL_ALL_TAC;
USE_THEN "Z-4" MP_TAC;
ARITH_TAC;
(* save *)
STRIP_TAC;
CLAIM `
mono_unbounded_below (\n. poly p (&n))`;
MATCH_MP_TAC
mua_quotient_limit_neg;
BETA_TAC;
EXISTS_TAC `&1`;
EXISTS_TAC `(\n.
LAST p * &n pow degree p)`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
BETA_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
REWRITE_TAC[
mono_unbounded_below];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-3" MP_TAC;
POP_ASSUM MP_TAC;
POP_ASSUM_LIST (fun x -> ALL_TAC);
MP_TAC (ISPEC `X:real`
REAL_ARCH_SIMPLE);
STRIP_TAC;
DISCH_THEN (ASSUME_TAC o ISPEC `1 + nmax N n`);
DISCH_THEN (ASSUME_TAC o ISPEC `&1 + &(nmax N n)`);
POP_ASSUM MP_TAC THEN ANTS_TAC;
REWRITE_TAC[nmax];
COND_CASES_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
RULE_ASSUM_TAC (REWRITE_RULE[
NOT_LE;GSYM
REAL_LT]);
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
POP_ASSUM MP_TAC THEN ANTS_TAC;
REWRITE_TAC[nmax];
ARITH_TAC;
ASM_MESON_TAC[ARITH_RULE `~(x < y /\ y < x)`;GSYM REAL_OF_NUM_ADD];
]);;
(* }}} *)
let POLY_LAST_LT = prove_by_refinement(
`!p. normal p /\ (?X. !x. X < x ==> poly p x < &0) ==>
LAST p < &0`,
(* {{{ Proof *)
[
GEN_TAC;
CASES_ON `
LENGTH p = 1`;
RULE_ASSUM_TAC (REWRITE_RULE[
LENGTH_1]);
POP_ASSUM MP_TAC THEN STRIP_TAC;
ASM_REWRITE_TAC[
LAST_SING;
POLY_SING];
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
EXISTS_TAC `X + &1`;
REAL_ARITH_TAC;
(* *)
REWRITE_TAC[AND_IMP_THM;];
DISCH_THEN (fun x -> MP_TAC (MATCH_MP
LIM_POLY2 x) THEN ASSUME_TAC x);
REPEAT STRIP_TAC;
DISJ_CASES_TAC (ISPECL [`&0`;`
LAST (p:real list)`]
REAL_LT_TOTAL);
ASM_MESON_TAC[
NORMAL_ID];
POP_ASSUM DISJ_CASES_TAC THENL [ALL_TAC;FIRST_ASSUM MATCH_ACCEPT_TAC];
(* save *)
CLAIM `
mono_unbounded_above (\n.
LAST p * &n pow degree p)`;
MATCH_MP_TAC
POW_UNB_CON;
REWRITE_TAC[degree];
CONJ_TAC THENL [ALL_TAC;FIRST_ASSUM MATCH_ACCEPT_TAC];
CLAIM `normalize p = p`;
ASM_MESON_TAC[normal];
DISCH_THEN SUBST1_TAC;
CLAIM `~(
LENGTH p = 0)`;
ASM_MESON_TAC[normal;
LENGTH_EQ_NIL];
LABEL_ALL_TAC;
USE_THEN "Z-4" MP_TAC;
ARITH_TAC;
(* save *)
STRIP_TAC;
CLAIM `
mono_unbounded_above (\n. poly p (&n))`;
MATCH_MP_TAC
mua_quotient_limit;
BETA_TAC;
EXISTS_TAC `&1`;
EXISTS_TAC `(\n.
LAST p * &n pow degree p)`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
BETA_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
REWRITE_TAC[
mono_unbounded_above];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-3" MP_TAC;
POP_ASSUM MP_TAC;
POP_ASSUM_LIST (fun x -> ALL_TAC);
MP_TAC (ISPEC `X:real`
REAL_ARCH_SIMPLE);
STRIP_TAC;
DISCH_THEN (ASSUME_TAC o ISPEC `1 + nmax N n`);
DISCH_THEN (ASSUME_TAC o ISPEC `&1 + &(nmax N n)`);
POP_ASSUM MP_TAC THEN ANTS_TAC;
REWRITE_TAC[nmax];
COND_CASES_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
RULE_ASSUM_TAC (REWRITE_RULE[
NOT_LE;GSYM
REAL_LT]);
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
POP_ASSUM MP_TAC THEN ANTS_TAC;
REWRITE_TAC[nmax];
ARITH_TAC;
ASM_MESON_TAC[ARITH_RULE `~(x < y /\ y < x)`;GSYM REAL_OF_NUM_ADD];
]);;
(* }}} *)
(* }}} *)
let DEGREE_SING = prove_by_refinement(
`!x. (degree [x] = 0)`,
(* {{{ Proof *)
[
REWRITE_TAC[degree];
STRIP_TAC;
CASES_ON `x = &0`;
ASM_REWRITE_TAC[normalize;
LENGTH];
ARITH_TAC;
CLAIM `normalize [x] = [x]`;
ASM_MESON_TAC[
NORMALIZE_SING];
DISCH_THEN SUBST1_TAC;
REWRITE_TAC[
LENGTH];
ARITH_TAC;
]);;
(* }}} *)
let DEGREE_CONS = prove_by_refinement(
`!h t. normal t ==> (degree (CONS h t) = 1 + degree t)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
CLAIM `normal (CONS h t)`;
ASM_MESON_TAC[
NORMAL_CONS];
REWRITE_TAC[normal;degree];
STRIP_TAC;
ASM_REWRITE_TAC[];
RULE_ASSUM_TAC (REWRITE_RULE[normal]);
CLAIM `~(
LENGTH t = 0)`;
ASM_MESON_TAC[
LENGTH_0];
STRIP_TAC;
ASM_REWRITE_TAC[
LENGTH];
POP_ASSUM MP_TAC THEN ARITH_TAC;
]);;
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Now the derivative *)
(* ---------------------------------------------------------------------- *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let NONCONSTANT_DEGREE = prove_by_refinement(
`!p. nonconstant p ==> 0 < degree p`,
(* {{{ Proof *)
[
GEN_TAC;
DISCH_THEN (fun x -> ASSUME_TAC x THEN MP_TAC x);
REWRITE_TAC[nonconstant;degree];
REPEAT STRIP_TAC;
CLAIM `normalize p = p`;
ASM_MESON_TAC[normal];
STRIP_TAC;
ASM_REWRITE_TAC[];
CLAIM `1 <
LENGTH p`;
ASM_MESON_TAC[
NONCONSTANT_LENGTH];
ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
let NONCONSTANT_DIFF_0 = prove_by_refinement(
`!p. nonconstant p ==> ~(
poly_diff p = [&0])`,
(* {{{ Proof *)
[
STRIP_TAC;
DISCH_THEN (fun x -> MP_TAC x THEN ASSUME_TAC x);
REWRITE_TAC[nonconstant];
REPEAT STRIP_TAC;
CLAIM `~(p = [])`;
ASM_MESON_TAC[normal];
DISCH_THEN (fun x -> RULE_ASSUM_TAC (REWRITE_RULE[x]) THEN ASSUME_TAC x);
CLAIM `~(
LAST p = &0)`;
MATCH_MP_TAC
NORMAL_LAST_NONZERO;
FIRST_ASSUM MATCH_ACCEPT_TAC;
STRIP_TAC;
CLAIM `
LAST p * &(degree p) = &0`;
ASM_SIMP_TAC[GSYM
POLY_DIFF_LAST_LEM];
REWRITE_TAC[
LAST];
STRIP_TAC;
CLAIM `(
LAST p = &0) \/ (&(degree p) = &0)`;
ASM_MESON_TAC[
REAL_ENTIRE];
STRIP_TAC;
ASM_MESON_TAC[];
CLAIM `?h t. p = CONS h t`;
ASM_MESON_TAC[
list_CASES];
STRIP_TAC;
CLAIM `normal t`;
ASM_MESON_TAC[
NORMAL_TAIL];
STRIP_TAC;
FIRST_ASSUM (MP_TAC o (MATCH_MP (ISPECL [`h:real`;`t:real list`]
DEGREE_CONS)));
STRIP_TAC;
CLAIM `degree p = 0`;
ASM_MESON_TAC [REAL_OF_NUM_EQ];
ASM_REWRITE_TAC[];
ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Finally, the positive theorems *)
(* ---------------------------------------------------------------------- *)
let POLY_DIFF_UP_RIGHT = prove_by_refinement(
`nonconstant p /\ (?X. !x. X < x ==> &0 < poly (
poly_diff p) x) ==>
(?Y. !y. Y < y ==> &0 < poly p y)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
CLAIM `
mono_unbounded_above (\n. poly p (&n))`;
MATCH_MP_TAC
LAST_UNB;
ASM_MESON_TAC[
PDIFF_POS_LAST];
REWRITE_TAC[
mono_unbounded_above];
DISCH_THEN (MP_TAC o (ISPEC `&0`));
STRIP_TAC;
CLAIM `?K. max X (&N) < &K`;
ASM_MESON_TAC[
REAL_ARCH_SIMPLE_LT];
STRIP_TAC;
EXISTS_TAC `&K`;
REPEAT STRIP_TAC;
CCONTR_TAC;
REWRITE_ASSUMS[
REAL_NOT_LT];
CLAIM `&N < y /\ X < y`;
ASM_MESON_TAC([
REAL_MAX_MAX] @ !REAL_REWRITES);
REPEAT STRIP_TAC;
MP_TAC (ISPECL [`p:real list`;`&K`;`y:real`]
POLY_MVT);
ANTS_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
STRIP_TAC;
CLAIM `poly p y - poly p (&K) <= &0`;
MATCH_MP_TAC (REAL_ARITH `x <= &0 /\ &0 < y ==> x - y <= &0`);
ASM_REWRITE_TAC[];
FIRST_ASSUM MATCH_MP_TAC;
CLAIM `&N < &K`;
ASM_MESON_TAC [
REAL_MAX_MAX;
REAL_LET_TRANS];
STRIP_TAC;
CLAIM `N:num < K`;
ASM_MESON_TAC [
REAL_OF_NUM_LT];
ARITH_TAC;
STRIP_TAC;
CLAIM `&0 < y - &K`;
LABEL_ALL_TAC;
USE_THEN "Z-7" MP_TAC;
REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `&0 < poly (
poly_diff p) x`;
FIRST_ASSUM MATCH_MP_TAC;
ASM_MESON_TAC[
REAL_MAX_MAX;
REAL_LET_TRANS;
REAL_LT_TRANS];
STRIP_TAC;
CLAIM `&0 < (y - &K) * poly (
poly_diff p) x`;
ONCE_REWRITE_TAC [ARITH_RULE `&0 = &0 * &0`];
MATCH_MP_TAC
REAL_LT_MUL2 THEN REPEAT STRIP_TAC THEN TRY REAL_ARITH_TAC THEN FIRST_ASSUM MATCH_ACCEPT_TAC;
STRIP_TAC;
REAL_SOLVE_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)
let POLY_DIFF_DOWN_RIGHT = prove_by_refinement(
`nonconstant p /\ (?X. !x. X < x ==> poly (
poly_diff p) x < &0) ==>
(?Y. !y. Y < y ==> poly p y < &0)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
CLAIM `
mono_unbounded_below (\n. poly p (&n))`;
MATCH_MP_TAC
LAST_UNB_NEG;
ASM_MESON_TAC[
PDIFF_NEG_LAST];
REWRITE_TAC[
mono_unbounded_below];
DISCH_THEN (MP_TAC o (ISPEC `&0`));
STRIP_TAC;
CLAIM `?K. max X (&N) < &K`;
ASM_MESON_TAC[
REAL_ARCH_SIMPLE_LT];
STRIP_TAC;
EXISTS_TAC `&K`;
REPEAT STRIP_TAC;
CCONTR_TAC;
REWRITE_ASSUMS[
REAL_NOT_LT];
CLAIM `&N < y /\ X < y`;
ASM_MESON_TAC([
REAL_MAX_MAX] @ !REAL_REWRITES);
REPEAT STRIP_TAC;
MP_TAC (ISPECL [`p:real list`;`&K`;`y:real`]
POLY_MVT);
ANTS_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
STRIP_TAC;
CLAIM `&0 <= poly p y - poly p (&K)`;
MATCH_MP_TAC (REAL_ARITH `&0 <= x /\ y < &0 ==> &0 <= x - y`);
ASM_REWRITE_TAC[];
FIRST_ASSUM MATCH_MP_TAC;
CLAIM `&N < &K`;
ASM_MESON_TAC (!REAL_REWRITES @ !NUM_REWRITES);
STRIP_TAC;
CLAIM `N:num < K`;
ASM_MESON_TAC [
REAL_OF_NUM_LT];
ARITH_TAC;
STRIP_TAC;
CLAIM `&0 < y - &K`;
LABEL_ALL_TAC;
USE_THEN "Z-7" MP_TAC;
REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `poly (
poly_diff p) x < &0`;
FIRST_ASSUM MATCH_MP_TAC;
REAL_SOLVE_TAC;
STRIP_TAC;
CLAIM `(y - &K) * poly (
poly_diff p) x < &0`;
ASM_MESON_TAC[
REAL_MUL_LT];
REPEAT STRIP_TAC;
REAL_SOLVE_TAC;
]);;
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* Now the negative ones *)
(* ---------------------------------------------------------------------- *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let MUA_DIV_CONST = prove_by_refinement(
`!a b p.
mono_unbounded_above (\n. p n) ==> (\n. a / (b + p n)) --> &0`,
(* {{{ Proof *)
[
REWRITE_TAC[
mono_unbounded_above;
SEQ];
REPEAT STRIP_TAC;
REAL_SIMP_TAC;
CASES_ON `a = &0`;
ASM_REWRITE_TAC[
real_div;
REAL_MUL_LZERO;
ABS_0];
ABBREV_TAC `k = (max (&1) (abs a / e - b))`;
FIRST_ASSUM (MP_TAC o (ISPEC `k:real`));
STRIP_TAC;
EXISTS_TAC `N`;
REPEAT STRIP_TAC;
REWRITE_ASSUMS (!REAL_REWRITES @ !NUM_REWRITES);
POP_ASSUM (fun x -> POP_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x)));
REWRITE_TAC[
REAL_ABS_DIV];
MATCH_MP_TAC
REAL_LTE_TRANS;
EXISTS_TAC `abs a / (b + k)`;
STRIP_TAC;
MATCH_MP_TAC
REAL_DIV_DENOM_LT;
REPEAT STRIP_TAC;
ASM_MESON_TAC[
REAL_ABS_NZ];
LABEL_ALL_TAC;
CLAIM `(abs a / e - b) <= k`;
ASM_MESON_TAC[
REAL_MAX_MAX];
STRIP_TAC;
CLAIM `&0 < abs a / e`;
REWRITE_TAC[
real_div];
MATCH_MP_TAC
REAL_LT_MUL;
ASM_MESON_TAC[
REAL_INV_POS;
REAL_ABS_NZ];
STRIP_TAC;
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
CLAIM `-- b < p n`;
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `k`;
ASM_REWRITE_TAC[];
CLAIM `(abs a / e - b) <= k`;
ASM_MESON_TAC[
REAL_MAX_MAX];
STRIP_TAC;
CLAIM `&0 < abs a / e`;
REWRITE_TAC[
real_div];
MATCH_MP_TAC
REAL_LT_MUL;
ASM_MESON_TAC[
REAL_INV_POS;
REAL_ABS_NZ];
STRIP_TAC;
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `abs (b + p n) = b + p n`;
MATCH_EQ_MP_TAC
REAL_ABS_REFL;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
DISCH_THEN SUBST1_TAC;
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
CLAIM `(abs a / e - b) <= k`;
ASM_MESON_TAC[
REAL_MAX_MAX];
STRIP_TAC;
CLAIM `&0 < abs a / e`;
REWRITE_TAC[
real_div];
MATCH_MP_TAC
REAL_LT_MUL;
ASM_MESON_TAC[
REAL_INV_POS;
REAL_ABS_NZ];
STRIP_TAC;
LABEL_ALL_TAC;
CLAIM `abs a / e <= b + k`;
USE_THEN "Z-1" MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CASES_ON `&1 <= abs a / e - b`;
CLAIM `k = abs a / e - b`;
USE_THEN "Z-3" (SUBST1_TAC o GSYM);
ASM_REWRITE_TAC[
real_max];
ASM_MESON_TAC[
real_max];
DISCH_THEN SUBST1_TAC;
REWRITE_TAC[ARITH_RULE `b + a - b = a`];
REWRITE_TAC[
real_div;];
REAL_SIMP_TAC;
REWRITE_TAC[REAL_MUL_ASSOC];
CLAIM `~(abs a = &0)`;
ASM_MESON_TAC[
REAL_ABS_NZ;
REAL_LT_LE];
STRIP_TAC;
ASM_SIMP_TAC[
REAL_MUL_RINV];
REAL_SIMP_TAC;
(* save *)
REWRITE_ASSUMS !REAL_REWRITES;
CLAIM `k = &1`;
ASM_MESON_TAC([
real_max] @ !REAL_REWRITES);
STRIP_TAC;
CLAIM `&0 < b + k`;
MATCH_MP_TAC
REAL_LTE_TRANS;
EXISTS_TAC `abs a / e`;
ASM_MESON_TAC[];
STRIP_TAC;
MATCH_MP_TAC
REAL_LE_RCANCEL_IMP;
EXISTS_TAC `b + k`;
ASM_REWRITE_TAC[];
REWRITE_TAC[
real_div];
REWRITE_TAC[GSYM REAL_MUL_ASSOC];
CLAIM `inv (b + &1) * (b + &1) = &1`;
LABEL_ALL_TAC;
POP_ASSUM MP_TAC;
ASM_REWRITE_TAC[];
STRIP_TAC;
ASM_MESON_TAC[REAL_MUL_LINV;
REAL_LT_LE];
DISCH_THEN SUBST1_TAC;
REWRITE_TAC[
REAL_MUL_RID];
MATCH_MP_TAC
REAL_LE_LCANCEL_IMP;
EXISTS_TAC `inv e`;
REPEAT STRIP_TAC;
USE_THEN "Z-5" MP_TAC;
MESON_TAC[
REAL_INV_POS;
REAL_LT_LE];
REWRITE_TAC[REAL_MUL_ASSOC];
CLAIM `~(e = &0)`;
ASM_MESON_TAC[REAL_INV_NZ;
REAL_LT_LE];
STRIP_TAC;
ASM_SIMP_TAC[REAL_MUL_LINV];
REAL_SIMP_TAC;
ASM_MESON_TAC[
real_div;REAL_MUL_SYM]
]);;
(* }}} *)
let SEQ_0_NEG = prove_by_refinement(
`!p. (\n. p n) --> &0 <=> (\n. -- p n) --> &0`,
(* {{{ Proof *)
[
REWRITE_TAC[
SEQ];
GEN_TAC THEN EQ_TAC;
REPEAT STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-0" (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
STRIP_TAC;
EXISTS_TAC `N`;
REPEAT STRIP_TAC;
POP_ASSUM (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
REAL_SIMP_TAC;
STRIP_TAC;
ASM_MESON_TAC[
REAL_ABS_NEG];
REPEAT STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-0" (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
STRIP_TAC;
EXISTS_TAC `N`;
REPEAT STRIP_TAC;
POP_ASSUM (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
REAL_SIMP_TAC;
STRIP_TAC;
ASM_MESON_TAC[
REAL_ABS_NEG];
]);;
(* }}} *)
let lem = prove_by_refinement(
`!x y z. --(x / (y + z)) = x / (-- y + -- z)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
REWRITE_TAC[
real_div];
REWRITE_TAC[ARITH_RULE `--(x * y) = x * -- y`];
REWRITE_TAC[ARITH_RULE `-- y + -- z = --(y + z)`];
REWRITE_TAC[
REAL_INV_NEG];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
let MUA_MUA = prove_by_refinement(
`!p q.
mono_unbounded_above (\n. p n) /\
mono_unbounded_above (\n. q n) ==>
mono_unbounded_above (\n. p n * q n)`,
(* {{{ Proof *)
[
REWRITE_TAC[
mono_unbounded_above_pos];
REPEAT STRIP_TAC;
CLAIM `&0 <= max c (&1)`;
REWRITE_TAC[
real_max];
COND_CASES_TAC;
REAL_ARITH_TAC;
ASM_REWRITE_TAC[];
DISCH_THEN (fun y -> POP_ASSUM (fun x -> RULE_ASSUM_TAC (C MATCH_MP y) THEN ASSUME_TAC x));
EVERY_ASSUM MP_TAC THEN REPEAT STRIP_TAC;
EXISTS_TAC `nmax N N'`;
REPEAT STRIP_TAC;
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `max c (&1)`;
ASM_REWRITE_TAC[
REAL_MAX_MAX];
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `max c (&1) * max c (&1)`;
REPEAT STRIP_TAC;
CONV_TAC (LAND_CONV (ONCE_REWRITE_CONV [GSYM
REAL_MUL_RID]));
MATCH_MP_TAC
REAL_LE_MUL2;
REPEAT STRIP_TAC;
REAL_SOLVE_TAC;
REAL_SIMP_TAC;
REAL_ARITH_TAC;
REAL_SOLVE_TAC;
MATCH_MP_TAC
REAL_LT_MUL2;
REPEAT STRIP_TAC;
REAL_SOLVE_TAC;
CLAIM `N <= n /\ N' <= (n:num)`;
POP_ASSUM MP_TAC;
REWRITE_TAC[nmax];
COND_CASES_TAC;
REPEAT STRIP_TAC;
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
REAL_SOLVE_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REWRITE_TAC[nmax] THEN ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* ---------------------------------------------------------------------- *)
(* A polynomial applied to a negative argument *)
(* ---------------------------------------------------------------------- *)
(* }}} *)
(* }}} *)
(* }}} *)
let POLY_PNEG_AUX = prove_by_refinement(
`!k p n.
EVEN n ==> (poly p (-- k) = poly (
pneg_aux n p) k)`,
(* {{{ Proof *)
[
STRIP_TAC;
LIST_INDUCT_TAC;
REPEAT STRIP_TAC;
REWRITE_TAC[
pneg_aux;poly];
REPEAT STRIP_TAC;
POP_ASSUM (fun x -> RULE_ASSUM_TAC (fun y -> MATCH_MP y x) THEN ASSUME_TAC x);
REWRITE_TAC[poly;
pneg_aux];
REAL_SIMP_TAC;
ASM_REWRITE_TAC[];
REAL_SIMP_TAC;
CLAIM `-- &1 pow n = &1`;
REWRITE_TAC[
REAL_POW_NEG];
ASM_REWRITE_TAC[];
REAL_SIMP_TAC;
DISCH_THEN SUBST1_TAC;
REAL_SIMP_TAC;
AP_TERM_TAC;
CONV_TAC (LAND_CONV (ONCE_REWRITE_CONV[GSYM
POLY_PNEG_NEG]));
REWRITE_TAC[
POLY_NEG];
REAL_SIMP_TAC;
]);;
(* }}} *)
let POLY_PNEG = prove_by_refinement(
`!p x. poly p (-- x) = poly (pneg p) x`,
(* {{{ Proof *)
[
LIST_INDUCT_TAC;
REWRITE_TAC[pneg;poly];
REWRITE_TAC[pneg;poly];
REPEAT STRIP_TAC;
CLAIM `poly (
pneg_aux 0 (CONS h t)) x = poly (CONS h t) (--x)`;
ASM_MESON_TAC[
POLY_PNEG_AUX;
EVEN];
DISCH_THEN SUBST1_TAC;
REWRITE_TAC[poly];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let PNEG_LAST = prove_by_refinement(
`!p. ~(p = []) ==> (
LAST (pneg p) =
LAST p) \/ (
LAST (pneg p) = --
LAST p)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
CASES_ON `normal p`;
MP_TAC (ISPEC `p:real list`
POLY_PNEG_LAST);
ASM_REWRITE_TAC[];
STRIP_TAC;
DISJ_CASES_TAC (ISPEC `degree p`
EVEN_OR_ODD);
ASM_MESON_TAC[];
ASM_MESON_TAC !REAL_REWRITES;
REWRITE_ASSUMS[
NORMAL_ID;DE_MORGAN_THM;];
POP_ASSUM MP_TAC THEN STRIP_TAC;
CLAIM `
LENGTH p = 0`;
POP_ASSUM MP_TAC THEN ARITH_TAC;
ASM_MESON_TAC[
LENGTH_0];
ASM_REWRITE_TAC[];
DISJ1_TAC;
ASM_MESON_TAC[
LAST_PNEG_0];
]);;
(* }}} *)
let NORMAL_PNEG = prove_by_refinement(
`!p. normal p = normal (pneg p)`,
(* {{{ Proof *)
[
REWRITE_TAC[
NORMAL_ID];
REPEAT STRIP_TAC;
EQ_TAC;
REPEAT STRIP_TAC;
ASM_MESON_TAC[
PNEG_LENGTH];
MP_TAC (ISPEC `p:real list`
PNEG_LAST);
CLAIM `~(p = [])`;
ASM_MESON_TAC[
LENGTH_NZ];
STRIP_TAC;
ASM_REWRITE_TAC[];
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
(* save *)
REPEAT STRIP_TAC;
ONCE_REWRITE_TAC[GSYM
PNEG_LENGTH];
ASM_REWRITE_TAC[];
MP_TAC (ISPEC `p:real list`
PNEG_LAST);
CLAIM `~(p = [])`;
ASM_MESON_TAC[
LENGTH_NZ;
PNEG_LENGTH];
STRIP_TAC;
ASM_REWRITE_TAC[];
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
"Z-0"];
CLAIM `~(-- &1 pow n = &0)`;
MATCH_MP_TAC REAL_POW_NZ;
REAL_ARITH_TAC;
STRIP_TAC;
ASM_MESON_TAC[REAL_ENTIRE];
ASM_MESON_TAC[LENGTH_0];
CLAIM `~(-- &1 pow n = &0)`;
MATCH_MP_TAC REAL_POW_NZ;
REAL_ARITH_TAC;
STRIP_TAC;
ASM_MESON_TAC[REAL_ENTIRE];
ASM_MESON_TAC[LENGTH_0];
ASM_MESON_TAC[LENGTH_0];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
let PNEG_SING = prove_by_refinement(
`!p. (pneg p = [x]) <=> (p = [x])`,
(* {{{ Proof *)
[
LIST_INDUCT_TAC;
REWRITE_TAC[pneg;
pneg_aux];
EQ_TAC;
REPEAT STRIP_TAC;
LIST_SIMP_TAC;
STRIP_TAC;
REWRITE_ASSUMS[pneg;
pneg_aux];
POP_ASSUM MP_TAC;
REAL_SIMP_TAC;
LIST_SIMP_TAC;
MESON_TAC[];
POP_ASSUM MP_TAC;
REWRITE_TAC[pneg;
pneg_aux];
LIST_SIMP_TAC;
ASM_MESON_TAC[
PNEG_AUX_NIL];
REWRITE_TAC[pneg;
pneg_aux];
REAL_SIMP_TAC;
LIST_SIMP_TAC;
STRIP_TAC;
ASM_MESON_TAC[
pneg_aux];
]);;
(* }}} *)
let PNEG_NONCONSTANT = prove_by_refinement(
`!p. nonconstant (pneg p) = nonconstant p`,
(* {{{ Proof *)
[
REWRITE_TAC[nonconstant];
STRIP_TAC THEN EQ_TAC;
REPEAT STRIP_TAC;
ASM_MESON_TAC[
NORMAL_PNEG];
POP_ASSUM (REWRITE_ASSUMS o list);
REWRITE_ASSUMS[pneg;
pneg_aux];
POP_ASSUM MP_TAC;
REAL_SIMP_TAC;
MESON_TAC[];
REPEAT STRIP_TAC;
ASM_MESON_TAC[
NORMAL_PNEG];
ASM_MESON_TAC[
PNEG_SING];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let poly_diff_aux_odd = prove_by_refinement(
`!p n. nonconstant p ==>
(
EVEN (degree p) =
EVEN (degree (
poly_diff_aux n p))) /\
(
ODD (degree p) =
ODD (degree (
poly_diff_aux n p)))`,
(* {{{ Proof *)
[
LIST_INDUCT_TAC;
REWRITE_TAC[normal;nonconstant;];
STRIP_TAC;
DISCH_THEN (fun x -> ASSUME_TAC x THEN MP_TAC x);
REWRITE_TAC[nonconstant];
STRIP_TAC;
CASES_ON `t = []`;
ASM_MESON_TAC[nonconstant;normal];
REWRITE_TAC[
poly_diff_aux];
CLAIM `normal t`;
ASM_MESON_TAC[
NORMAL_TAIL];
STRIP_TAC;
CLAIM `normal (
poly_diff_aux (SUC n) t)`;
ASM_MESON_TAC[nonconstant;normal;
POLY_DIFF_AUX_NORMAL;
NOT_SUC];
STRIP_TAC;
CASES_ON `?x. t = [x]`;
POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[];
CLAIM `~(x = &0)`;
ASM_MESON_TAC[normal;normalize];
STRIP_TAC;
CLAIM `degree [h; x] = 1`;
CLAIM `normalize [h; x] = [h; x]`;
ASM_MESON_TAC[normal];
DISCH_THEN SUBST1_TAC;
CLAIM `
LENGTH [h; x] = 2`;
ASM_MESON_TAC[
LENGTH_PAIR];
STRIP_TAC;
REWRITE_TAC[degree];
CLAIM `normal [h; x]`;
ASM_MESON_TAC[normal;normalize];
DISCH_THEN (fun x -> ASSUME_TAC x THEN MP_TAC x);
REWRITE_TAC[normal];
STRIP_TAC;
ASM_REWRITE_TAC[];
ARITH_TAC;
STRIP_TAC;
ASM_REWRITE_TAC[
poly_diff_aux;];
CLAIM `~(&(SUC n) * x = &0)`;
ASM_MESON_TAC[normal;normalize;
REAL_ENTIRE;ARITH_RULE `~(SUC n = 0)`;
REAL_INJ];
STRIP_TAC;
CLAIM `degree [&n * h; &(SUC n) * x] = 1`;
REWRITE_TAC[degree];
ASM_REWRITE_TAC[normalize;
NOT_CONS_NIL;
LENGTH;];
ARITH_TAC;
STRIP_TAC;
ASM_REWRITE_TAC[];
ASM_SIMP_TAC[
DEGREE_CONS];
CLAIM `nonconstant t`;
ASM_MESON_TAC[nonconstant];
STRIP_TAC;
ONCE_REWRITE_TAC[
ADD_SYM];
REWRITE_TAC[GSYM
ADD1];
ASM_SIMP_TAC[
EVEN;
ODD];
ASM_MESON_TAC[
POLY_DIFF_AUX_DEGREE];
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let nmax_le = prove_by_refinement(
`!n m. n <= nmax n m /\ m <= nmax n m`,
(* {{{ Proof *)
[
REWRITE_TAC[nmax];
REPEAT STRIP_TAC;
COND_CASES_TAC;
ARITH_TAC;
ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_UP_LEFT = prove_by_refinement(
`!p. nonconstant p /\ (?X. !x. x < X ==> poly (
poly_diff p) x < &0) ==>
(?Y. !y. y < Y ==> &0 < poly p y)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
CLAIM `
mono_unbounded_above (\n. poly p (-- &n))`;
REWRITE_TAC[
POLY_PNEG];
DISJ_CASES_TAC (ISPEC `degree p`
EVEN_OR_ODD);
MATCH_MP_TAC
mua_quotient_limit;
EXISTS_TAC `&1`;
EXISTS_TAC `(\n.
LAST (pneg p) * &n pow degree (pneg p))`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
BETA_TAC;
MATCH_MP_TAC
LIM_POLY2;
MATCH_EQ_MP_TAC
NORMAL_PNEG;
ASM_MESON_TAC[nonconstant];
MATCH_MP_TAC
POW_UNB_CON;
STRIP_TAC;
REWRITE_TAC[
DEGREE_PNEG];
REWRITE_TAC[degree];
CLAIM `normalize p = p`;
ASM_MESON_TAC[nonconstant;normal];
DISCH_THEN SUBST1_TAC;
CLAIM `~(
LENGTH p = 0)`;
ASM_MESON_TAC[nonconstant;normal;
LENGTH_NZ;
LENGTH_0;degree];
STRIP_TAC;
CLAIM `~(
LENGTH p = 1)`;
ASM_MESON_TAC[nonconstant;normal;
LENGTH_NZ;
LENGTH_1;degree];
POP_ASSUM MP_TAC THEN ARITH_TAC;
(* save *)
CLAIM `
LAST (pneg p) =
LAST p`;
ASM_MESON_TAC[GSYM
POLY_PNEG_LAST;nonconstant;];
DISCH_THEN SUBST1_TAC;
ONCE_REWRITE_TAC[REAL_ARITH `x < y <=> ~(x = y) /\ ~(y < x)`];
STRIP_TAC;
ASM_MESON_TAC[
NORMAL_ID;nonconstant];
STRIP_TAC;
CLAIM `
ODD (degree (
poly_diff p))`;
ASM_SIMP_TAC[
poly_diff_parity2];
STRIP_TAC;
CLAIM `nonconstant (
poly_diff p)`;
MATCH_MP_TAC
normal_nonconstant;
STRIP_TAC;
MATCH_MP_TAC
NONCONSTANT_DIFF_NORMAL;
FIRST_ASSUM MATCH_ACCEPT_TAC;
POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
CLAIM `
mono_unbounded_above (\n. poly (
poly_diff p) (-- &n))`;
MATCH_MP_TAC
LAST_UNB_ODD_NEG;
ASM_REWRITE_TAC[];
ASM_MESON_TAC[
POLY_DIFF_LAST_LT];
REWRITE_TAC[
mono_unbounded_above];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
(* save *)
MP_TAC (ISPEC `-- (X - &1)`
REAL_ARCH_SIMPLE);
DISCH_THEN (X_CHOOSE_TAC `M:num`);
CLAIM `-- &M <= X - &1`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-2" (MP_TAC o ISPEC `nmax M N`);
STRIP_TAC;
CLAIM `N <= nmax M N`;
REWRITE_TAC[
nmax_le];
DISCH_THEN (REWRITE_ASSUMS o list);
CLAIM `-- &(nmax M N) < X`;
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `-- &M`;
STRIP_TAC;
REWRITE_TAC[nmax];
REWRITE_TAC[
REAL_LE_NEG2; REAL_OF_NUM_LE] THEN ARITH_TAC;
USE_THEN "Z-0" MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ASM_MESON_TAC[ARITH_RULE `~(x < &0 /\ &0 < x)`];
(* save *)
REWRITE_TAC[GSYM
POLY_PNEG];
MATCH_MP_TAC
LAST_UNB_ODD_NEG;
ASM_REWRITE_TAC[];
ASM_SIMP_TAC[GSYM
POLY_DIFF_LAST_LT];
CASES_ON `?x.
poly_diff p = [x]`;
POP_ASSUM MP_TAC THEN STRIP_TAC;
ASM_REWRITE_TAC[
LAST];
LABEL_ALL_TAC;
USE_THEN "Z-2" MP_TAC;
POP_ASSUM (fun x -> REWRITE_TAC[x] THEN ASSUME_TAC x);
REWRITE_TAC[poly];
REAL_SIMP_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
EXISTS_TAC `X - &1`;
REAL_ARITH_TAC;
CLAIM `nonconstant (
poly_diff p)`;
REWRITE_TAC[nonconstant];
STRIP_TAC;
MATCH_MP_TAC
POLY_DIFF_NORMAL;
FIRST_ASSUM MATCH_ACCEPT_TAC;
ASM_MESON_TAC[];
STRIP_TAC;
CLAIM `
EVEN (degree (
poly_diff p))`;
ASM_MESON_TAC[
poly_diff_parity];
STRIP_TAC;
ONCE_REWRITE_TAC[ARITH_RULE `x < y <=> ~(y < x) /\ ~(y = x)`];
REPEAT STRIP_TAC;
CLAIM `
mono_unbounded_above (\n. poly (
poly_diff p) (-- (&n)))`;
MATCH_MP_TAC
LAST_UNB_EVEN_POS;
ASM_REWRITE_TAC[];
REWRITE_TAC[
mono_unbounded_above];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
(* save *)
MP_TAC (ISPEC `-- (X - &1)`
REAL_ARCH_SIMPLE);
DISCH_THEN (X_CHOOSE_TAC `M:num`);
CLAIM `-- &M <= X - &1`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-2" (MP_TAC o ISPEC `nmax M N`);
STRIP_TAC;
CLAIM `N <= nmax M N`;
REWRITE_TAC[
nmax_le];
DISCH_THEN (REWRITE_ASSUMS o list);
CLAIM `-- &(nmax M N) < X`;
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `-- &M`;
STRIP_TAC;
REWRITE_TAC[nmax];
REWRITE_TAC[
REAL_LE_NEG2; REAL_OF_NUM_LE] THEN ARITH_TAC;
USE_THEN "Z-0" MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ASM_MESON_TAC[ARITH_RULE `~(x < &0 /\ &0 < x)`];
ASM_MESON_TAC[nonconstant;
NORMAL_ID];
(* save xxx *)
REWRITE_TAC[
mono_unbounded_above];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
MP_TAC (ISPEC `-- (X - &1)`
REAL_ARCH_SIMPLE);
DISCH_THEN (X_CHOOSE_TAC `M:num`);
ABBREV_TAC `k = nmax N M`;
EXISTS_TAC `-- &k`;
REPEAT STRIP_TAC;
REWRITE_TAC [ARITH_RULE `x < y <=> ~(y <= x)`];
STRIP_TAC;
MP_TAC (ISPECL [`p:real list`;`y:real`;`-- &k`]
POLY_MVT);
ASM_REWRITE_TAC[];
STRIP_TAC;
LABEL_ALL_TAC;
CLAIM `&0 < (-- &k) - y`;
USE_THEN "Z-4" MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `poly (
poly_diff p) x < &0`;
FIRST_ASSUM MATCH_MP_TAC;
MATCH_MP_TAC
REAL_LTE_TRANS;
EXISTS_TAC `-- &k`;
ASM_REWRITE_TAC[];
MATCH_MP_TAC
REAL_LE_TRANS;
EXISTS_TAC `-- &M`;
STRIP_TAC;
USE_THEN "Z-5" (SUBST1_TAC o GSYM);
REWRITE_TAC[nmax];
REWRITE_TAC[
REAL_LE_NEG2; REAL_OF_NUM_LE] THEN ARITH_TAC;
USE_THEN "Z-6" MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
(* save *)
CLAIM `N <= k:num`;
USE_THEN "Z-5" (SUBST1_TAC o GSYM);
REWRITE_TAC[nmax] THEN ARITH_TAC;
STRIP_TAC;
CLAIM `&0 < poly p (-- &k)`;
ASM_MESON_TAC[];
STRIP_TAC;
CLAIM `&0 < poly p (-- &k) - poly p y`;
LABEL_ALL_TAC;
USE_ASSUM_LIST ["Z-10";
"Z-3"] MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `(-- &k - y) * poly (poly_diff p) x < &0`;
REWRITE_TAC[REAL_MUL_LT];
ASM_REWRITE_TAC[];
POP_ASSUM MP_TAC;
USE_THEN "Z-0" MP_TAC;
REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_DOWN_LEFT = prove_by_refinement(
`!p. nonconstant p /\ (?X. !x. x < X ==> &0 < poly (
poly_diff p) x) ==>
(?Y. !y. y < Y ==> poly p y < &0)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
CLAIM `
mono_unbounded_below (\n. poly p (-- &n))`;
REWRITE_TAC[
POLY_PNEG];
DISJ_CASES_TAC (ISPEC `degree p`
EVEN_OR_ODD);
MATCH_MP_TAC
mua_quotient_limit_neg;
EXISTS_TAC `&1`;
EXISTS_TAC `(\n.
LAST (pneg p) * &n pow degree (pneg p))`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
BETA_TAC;
MATCH_MP_TAC
LIM_POLY2;
MATCH_EQ_MP_TAC
NORMAL_PNEG;
ASM_MESON_TAC[nonconstant];
MATCH_MP_TAC
POW_UNBB_CON;
STRIP_TAC;
REWRITE_TAC[
DEGREE_PNEG];
REWRITE_TAC[degree];
CLAIM `normalize p = p`;
ASM_MESON_TAC[nonconstant;normal];
DISCH_THEN SUBST1_TAC;
CLAIM `~(
LENGTH p = 0)`;
ASM_MESON_TAC[nonconstant;normal;
LENGTH_NZ;
LENGTH_0;degree];
STRIP_TAC;
CLAIM `~(
LENGTH p = 1)`;
ASM_MESON_TAC[nonconstant;normal;
LENGTH_NZ;
LENGTH_1;degree];
POP_ASSUM MP_TAC THEN ARITH_TAC;
(* save *)
CLAIM `
LAST (pneg p) =
LAST p`;
ASM_MESON_TAC[GSYM
POLY_PNEG_LAST;nonconstant;];
DISCH_THEN SUBST1_TAC;
ONCE_REWRITE_TAC[REAL_ARITH `x < y <=> ~(x = y) /\ ~(y < x)`];
STRIP_TAC;
ASM_MESON_TAC[
NORMAL_ID;nonconstant];
STRIP_TAC;
CLAIM `
ODD (degree (
poly_diff p))`;
ASM_SIMP_TAC[
poly_diff_parity2];
STRIP_TAC;
CLAIM `nonconstant (
poly_diff p)`;
MATCH_MP_TAC
normal_nonconstant;
STRIP_TAC;
MATCH_MP_TAC
NONCONSTANT_DIFF_NORMAL;
FIRST_ASSUM MATCH_ACCEPT_TAC;
POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
CLAIM `
mono_unbounded_below (\n. poly (
poly_diff p) (-- &n))`;
MATCH_MP_TAC
LAST_UNB_ODD_POS;
ASM_REWRITE_TAC[];
ASM_MESON_TAC[
POLY_DIFF_LAST_GT];
REWRITE_TAC[
mono_unbounded_below];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
(* save *)
MP_TAC (ISPEC `-- (X - &1)`
REAL_ARCH_SIMPLE);
DISCH_THEN (X_CHOOSE_TAC `M:num`);
CLAIM `-- &M <= X - &1`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-2" (MP_TAC o ISPEC `nmax M N`);
STRIP_TAC;
CLAIM `N <= nmax M N`;
REWRITE_TAC[
nmax_le];
DISCH_THEN (REWRITE_ASSUMS o list);
CLAIM `-- &(nmax M N) < X`;
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `-- &M`;
STRIP_TAC;
REWRITE_TAC[nmax];
REWRITE_TAC[
REAL_LE_NEG2; REAL_OF_NUM_LE] THEN ARITH_TAC;
USE_THEN "Z-0" MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ASM_MESON_TAC[ARITH_RULE `~(x < &0 /\ &0 < x)`];
(* save *)
REWRITE_TAC[GSYM
POLY_PNEG];
MATCH_MP_TAC
LAST_UNB_ODD_POS;
ASM_REWRITE_TAC[];
ASM_SIMP_TAC[GSYM
POLY_DIFF_LAST_GT];
CASES_ON `?x.
poly_diff p = [x]`;
POP_ASSUM MP_TAC THEN STRIP_TAC;
ASM_REWRITE_TAC[
LAST];
LABEL_ALL_TAC;
USE_THEN "Z-2" MP_TAC;
POP_ASSUM (fun x -> REWRITE_TAC[x] THEN ASSUME_TAC x);
REWRITE_TAC[poly];
REAL_SIMP_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
EXISTS_TAC `X - &1`;
REAL_ARITH_TAC;
CLAIM `nonconstant (
poly_diff p)`;
REWRITE_TAC[nonconstant];
STRIP_TAC;
MATCH_MP_TAC
POLY_DIFF_NORMAL;
FIRST_ASSUM MATCH_ACCEPT_TAC;
ASM_MESON_TAC[];
STRIP_TAC;
CLAIM `
EVEN (degree (
poly_diff p))`;
ASM_MESON_TAC[
poly_diff_parity];
STRIP_TAC;
ONCE_REWRITE_TAC[ARITH_RULE `x < y <=> ~(y < x) /\ ~(y = x)`];
REPEAT STRIP_TAC;
CLAIM `
mono_unbounded_below (\n. poly (
poly_diff p) (-- (&n)))`;
MATCH_MP_TAC
LAST_UNBB_EVEN_NEG;
ASM_REWRITE_TAC[];
REWRITE_TAC[
mono_unbounded_below];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
(* save *)
MP_TAC (ISPEC `-- (X - &1)`
REAL_ARCH_SIMPLE);
DISCH_THEN (X_CHOOSE_TAC `M:num`);
CLAIM `-- &M <= X - &1`;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
LABEL_ALL_TAC;
USE_THEN "Z-2" (MP_TAC o ISPEC `nmax M N`);
STRIP_TAC;
CLAIM `N <= nmax M N`;
REWRITE_TAC[
nmax_le];
DISCH_THEN (REWRITE_ASSUMS o list);
CLAIM `-- &(nmax M N) < X`;
MATCH_MP_TAC
REAL_LET_TRANS;
EXISTS_TAC `-- &M`;
STRIP_TAC;
REWRITE_TAC[nmax];
REWRITE_TAC[
REAL_LE_NEG2; REAL_OF_NUM_LE] THEN ARITH_TAC;
USE_THEN "Z-0" MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ASM_MESON_TAC[ARITH_RULE `~(x < &0 /\ &0 < x)`];
ASM_MESON_TAC[nonconstant;
NORMAL_ID];
(* save *)
REWRITE_TAC[
mono_unbounded_below];
DISCH_THEN (MP_TAC o ISPEC `&0`);
STRIP_TAC;
MP_TAC (ISPEC `-- (X - &1)`
REAL_ARCH_SIMPLE);
DISCH_THEN (X_CHOOSE_TAC `M:num`);
ABBREV_TAC `k = nmax N M`;
EXISTS_TAC `-- &k`;
REPEAT STRIP_TAC;
REWRITE_TAC [ARITH_RULE `x < y <=> ~(y <= x)`];
STRIP_TAC;
MP_TAC (ISPECL [`p:real list`;`y:real`;`-- &k`]
POLY_MVT);
ASM_REWRITE_TAC[];
STRIP_TAC;
LABEL_ALL_TAC;
CLAIM `&0 < (-- &k) - y`;
USE_THEN "Z-4" MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `&0 < poly (
poly_diff p) x`;
FIRST_ASSUM MATCH_MP_TAC;
MATCH_MP_TAC
REAL_LTE_TRANS;
EXISTS_TAC `-- &k`;
ASM_REWRITE_TAC[];
MATCH_MP_TAC
REAL_LE_TRANS;
EXISTS_TAC `-- &M`;
STRIP_TAC;
USE_THEN "Z-5" (SUBST1_TAC o GSYM);
REWRITE_TAC[nmax];
REWRITE_TAC[
REAL_LE_NEG2; REAL_OF_NUM_LE] THEN ARITH_TAC;
USE_THEN "Z-6" MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
(* save *)
CLAIM `N <= k:num`;
USE_THEN "Z-5" (SUBST1_TAC o GSYM);
REWRITE_TAC[nmax] THEN ARITH_TAC;
STRIP_TAC;
CLAIM `poly p (-- &k) < &0`;
ASM_MESON_TAC[];
STRIP_TAC;
CLAIM `poly p (-- &k) - poly p y < &0`;
LABEL_ALL_TAC;
USE_ASSUM_LIST ["Z-10";
"Z-3"] MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `&0 < (-- &k - y) * poly (poly_diff p) x`;
REWRITE_TAC[REAL_MUL_GT];
ASM_REWRITE_TAC[];
POP_ASSUM MP_TAC;
USE_THEN "Z-0" MP_TAC;
REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_DOWN_LEFT2 = prove_by_refinement(
`!p X. nonconstant p /\ (!x. x < X ==> &0 < poly (
poly_diff p) x) ==>
(?Y. Y < X /\ (!y. y < Y ==> poly p y < &0))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPEC `p:real list`
POLY_DIFF_DOWN_LEFT);
ASM_REWRITE_TAC[];
ANTS_TAC;
ASM_MESON_TAC[];
STRIP_TAC;
EXISTS_TAC `min X Y - &1`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_UP_LEFT2 = prove_by_refinement(
`!p X. nonconstant p /\ (!x. x < X ==> poly (
poly_diff p) x < &0) ==>
(?Y. Y < X /\ (!y. y < Y ==> &0 < poly p y))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPEC `p:real list`
POLY_DIFF_UP_LEFT);
ASM_REWRITE_TAC[];
ANTS_TAC;
ASM_MESON_TAC[];
STRIP_TAC;
EXISTS_TAC `min X Y - &1`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_DOWN_LEFT3 = prove_by_refinement(
`!p p' X. nonconstant p ==> (
poly_diff p = p') ==>
(!x. x < X ==> &0 < poly p' x) ==>
(?Y. Y < X /\ (!y. y < Y ==> poly p y < &0))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPEC `p:real list`
POLY_DIFF_DOWN_LEFT);
ASM_REWRITE_TAC[];
ANTS_TAC;
ASM_MESON_TAC[];
STRIP_TAC;
EXISTS_TAC `min X Y - &1`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_UP_LEFT3 = prove_by_refinement(
`!p p' X. nonconstant p ==> (
poly_diff p = p') ==>
(!x. x < X ==> poly p' x < &0) ==>
(?Y. Y < X /\ (!y. y < Y ==> &0 < poly p y))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPEC `p:real list`
POLY_DIFF_UP_LEFT);
ASM_REWRITE_TAC[];
ANTS_TAC;
ASM_MESON_TAC[];
STRIP_TAC;
EXISTS_TAC `min X Y - &1`;
REPEAT STRIP_TAC;
REAL_ARITH_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_DOWN_LEFT4 = prove_by_refinement(
`!p p' X. nonconstant p ==> (
poly_diff p = p') ==>
(!x. x < X ==> &0 < poly p' x) ==>
(?Y. Y < X /\ (!y. y <= Y ==> poly p y < &0))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPECL[ `p:real list`;`p':real list`;`X:real`]
POLY_DIFF_DOWN_LEFT3);
ASM_REWRITE_TAC[];
REPEAT STRIP_TAC;
EXISTS_TAC `Y - &1`;
STRIP_TAC;
POP_ASSUM IGNORE;
POP_ASSUM MP_TAC;
REAL_ARITH_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_UP_LEFT4 = prove_by_refinement(
`!p p' X. nonconstant p ==> (
poly_diff p = p') ==>
(!x. x < X ==> poly p' x < &0) ==>
(?Y. Y < X /\ (!y. y <= Y ==> &0 < poly p y))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPECL[ `p:real list`;`p':real list`;`X:real`]
POLY_DIFF_UP_LEFT3);
ASM_REWRITE_TAC[];
REPEAT STRIP_TAC;
EXISTS_TAC `Y - &1`;
STRIP_TAC;
POP_ASSUM IGNORE;
POP_ASSUM MP_TAC;
REAL_ARITH_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let POLY_DIFF_UP_RIGHT2 = prove_by_refinement(
`!p p' X. nonconstant p ==> (
poly_diff p = p') ==>
(!x. X < x ==> &0 < poly p' x) ==>
(?Y. X < Y /\ (!y. Y <= y ==> &0 < poly p y))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPECL[ `p:real list`] (GEN_ALL
POLY_DIFF_UP_RIGHT));
ASM_REWRITE_TAC[];
ANTS_TAC;
ASM_MESON_TAC[];
REPEAT STRIP_TAC;
EXISTS_TAC `(max X Y) + &1`;
STRIP_TAC;
REAL_ARITH_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
let POLY_DIFF_DOWN_RIGHT2 = prove_by_refinement(
`!p p' X. nonconstant p ==> (
poly_diff p = p') ==>
(!x. X < x ==> poly p' x < &0) ==>
(?Y. X < Y /\ (!y. Y <= y ==> poly p y < &0))`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
MP_TAC (ISPECL[ `p:real list`] (GEN_ALL
POLY_DIFF_DOWN_RIGHT));
ASM_REWRITE_TAC[];
ANTS_TAC;
ASM_MESON_TAC[];
REPEAT STRIP_TAC;
EXISTS_TAC `(max X Y) + &1`;
STRIP_TAC;
REAL_ARITH_TAC;
REPEAT STRIP_TAC;
FIRST_ASSUM MATCH_MP_TAC;
POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)