(
  `!x y p. x < y /\ &0 < poly p x /\ poly p y < &0 /\ 
            (!z. x < z /\ z < y ==> ~(poly (
 p) z = &0)) ==> 
            ?X. x < X /\ X < y /\ (poly p X = &0) /\ 
              (!z. x < z /\ z < X ==> &0 < poly p z) /\ 
              (!z. X < z /\ z < y ==> poly p z < &0)`,
(* {{{ Proof *)
[
  REPEAT STRIP_TAC;
  MP_TAC (ISPECL [`p:real list`;`x:real`;`y:real`] 
POLY_IVT_NEG);
  REWRITE_TAC[
real_gt];
  ASM_REWRITE_TAC[];
  DISCH_THEN (X_CHOOSE_TAC `X:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  EXISTS_TAC `X`;
  ASM_REWRITE_TAC[];
  STRIP_TAC;
  REPEAT STRIP_TAC;
  (* save *) 
  ONCE_REWRITE_TAC[ARITH_RULE `x < y <=> ~(y < x \/ (x = y))`];
  STRIP_TAC;
  MP_TAC (ISPECL [`p:real list`;`x:real`;`z:real`] 
POLY_MVT);
  ASM_REWRITE_TAC[];
  DISCH_THEN (X_CHOOSE_TAC `N:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  CLAIM `poly p z - poly p x < &0`;
  LABEL_ALL_TAC;
  USE_THEN "Z-3" MP_TAC;
  USE_THEN "Z-11" MP_TAC;
  REAL_ARITH_TAC;
  STRIP_TAC;
  CLAIM `(z - x) * poly (
poly_diff p) N < &0`;
  REPEAT_N 2 (POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC;
  ASM_REWRITE_TAC[
REAL_MUL_LT];
  REPEAT STRIP_TAC;
  CLAIM `&0 < z - x`;
  LABEL_ALL_TAC;
  USE_THEN "Z-8" MP_TAC THEN REAL_ARITH_TAC;
  LABEL_ALL_TAC;
  USE_THEN "Z-1" MP_TAC THEN REAL_ARITH_TAC;
  (* save *) 
  MP_TAC (ISPECL [`p:real list`;`z:real`;`X:real`] 
POLY_MVT);
  ASM_REWRITE_TAC[];
  DISCH_THEN (X_CHOOSE_TAC `M:real`);  
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  CLAIM `&0 < &0 - poly p z`;
  LABEL_ALL_TAC;
  USE_THEN "Z-9" MP_TAC;
  REAL_ARITH_TAC;
  STRIP_TAC;
  CLAIM `&0 < X - z`;
  LABEL_ALL_TAC;
  USE_THEN "Z-11" MP_TAC THEN REAL_ARITH_TAC;
  STRIP_TAC;
  CLAIM `&0 < (X - z) * poly (
poly_diff p) M`;
  POP_ASSUM IGNORE;
  POP_ASSUM MP_TAC;
  POP_ASSUM MP_TAC;
  REAL_ARITH_TAC;
  REWRITE_TAC[
REAL_MUL_GT];
  REPEAT STRIP_TAC;
  POP_ASSUM IGNORE;
  POP_ASSUM MP_TAC;
  POP_ASSUM MP_TAC;
  REAL_ARITH_TAC;
  CLAIM `N < M`;
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `z`;
  ASM_REWRITE_TAC[];
  STRIP_TAC;
  MP_TAC (ISPECL [`
poly_diff p`;`N:real`;`M:real`] (REWRITE_RULE[
real_gt] 
POLY_IVT_POS));
  ASM_REWRITE_TAC[];
  DISCH_THEN (X_CHOOSE_TAC `K:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  (* save *) 
  CLAIM `x < K /\  K < y`;
  STRIP_TAC;
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `N`;
  ASM_REWRITE_TAC[];
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `M`;
  ASM_REWRITE_TAC[];
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `X`;
  ASM_REWRITE_TAC[];
  ASM_MESON_TAC[];
  (* save *) 
  POP_ASSUM (ASSUME_TAC o GSYM);
  MP_TAC (ISPECL [`p:real list`;`z:real`;`X:real`] 
POLY_MVT);
  ASM_REWRITE_TAC[];
  REAL_SIMP_TAC;
  ONCE_REWRITE_TAC[REAL_ARITH `(x:real = y) <=> (y = x)`];
  ASM_REWRITE_TAC[
REAL_ENTIRE];
  DISCH_THEN (X_CHOOSE_TAC `M:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  LABEL_ALL_TAC;
  POP_ASSUM MP_TAC;
  USE_THEN "Z-4" MP_TAC THEN REAL_ARITH_TAC;
  CLAIM `x < M /\  M < y`;
  STRIP_TAC;
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `z`;
  ASM_REWRITE_TAC[];
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `X`;
  ASM_REWRITE_TAC[];
  ASM_MESON_TAC[];
  (* save *) 
  REPEAT STRIP_TAC;
  ONCE_REWRITE_TAC[ARITH_RULE `x < y <=> ~(y < x \/ (x = y))`];
  STRIP_TAC;
  MP_TAC (ISPECL [`p:real list`;`X:real`;`z:real`] 
POLY_MVT);
  ASM_REWRITE_TAC[];
  DISCH_THEN (X_CHOOSE_TAC `N:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  POP_ASSUM MP_TAC;
  REAL_SIMP_TAC;
  STRIP_TAC;
  CLAIM `&0 < (z - X) * poly (
poly_diff p) N`;
  LABEL_ALL_TAC;
  USE_THEN "Z-3" MP_TAC;
  POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
  ASM_REWRITE_TAC[
REAL_MUL_GT];
  REPEAT STRIP_TAC;
  CLAIM `&0 < z - X`;
  LABEL_ALL_TAC;
  USE_THEN "Z-7" MP_TAC THEN REAL_ARITH_TAC;
  LABEL_ALL_TAC;
  USE_THEN "Z-1" MP_TAC THEN REAL_ARITH_TAC;
  (* save *) 
  MP_TAC (ISPECL [`p:real list`;`z:real`;`y:real`] 
POLY_MVT);
  LABEL_ALL_TAC;
  USE_THEN "Z-6" (REWRITE_TAC o list);
  DISCH_THEN (X_CHOOSE_TAC `M:real`);  
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  CLAIM `poly p y - poly p z < &0`;
  LABEL_ALL_TAC;
  USE_THEN "Z-12" MP_TAC;
  USE_THEN "Z-5" MP_TAC;
  REAL_ARITH_TAC;
  STRIP_TAC;
  CLAIM `&0 < y - z`;
  LABEL_ALL_TAC;
  USE_THEN "Z-6" MP_TAC THEN REAL_ARITH_TAC;
  STRIP_TAC;
  CLAIM `(y - z) * poly (
poly_diff p) M < &0`;
  POP_ASSUM IGNORE;
  POP_ASSUM MP_TAC;
  POP_ASSUM MP_TAC;
  REAL_ARITH_TAC;
  REWRITE_TAC[
REAL_MUL_LT];
  REPEAT STRIP_TAC;
  POP_ASSUM IGNORE;
  POP_ASSUM MP_TAC;
  POP_ASSUM MP_TAC;
  REAL_ARITH_TAC;
  CLAIM `N < M`;
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `z`;
  ASM_REWRITE_TAC[];
  STRIP_TAC;
  MP_TAC (ISPECL [`
poly_diff p`;`N:real`;`M:real`] (REWRITE_RULE[
real_gt] 
POLY_IVT_NEG));
  ASM_REWRITE_TAC[];
  DISCH_THEN (X_CHOOSE_TAC `K:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  (* save *) 
  CLAIM `x < K /\  K < y`;
  STRIP_TAC;
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `N`;
  ASM_REWRITE_TAC[];
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `X`;
  ASM_REWRITE_TAC[];
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `M`;
  ASM_REWRITE_TAC[];
  ASM_MESON_TAC[];
  (* save *) 
  MP_TAC (ISPECL [`p:real list`;`X:real`;`z:real`] 
POLY_MVT);
  ASM_REWRITE_TAC[];
  REAL_SIMP_TAC;
  ONCE_REWRITE_TAC[REAL_ARITH `(x:real = y) <=> (y = x)`];
  ASM_REWRITE_TAC[
REAL_ENTIRE];
  DISCH_THEN (X_CHOOSE_TAC `M:real`);
  POP_ASSUM MP_TAC THEN STRIP_TAC;
  LABEL_ALL_TAC;
  POP_ASSUM MP_TAC;
  USE_THEN "Z-5" MP_TAC THEN REAL_ARITH_TAC;
  CLAIM `x < M /\  M < y`;
  STRIP_TAC;
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `X`;
  ASM_REWRITE_TAC[];
  MATCH_MP_TAC 
REAL_LT_TRANS;
  EXISTS_TAC `z`;
  ASM_REWRITE_TAC[];
  ASM_MESON_TAC[];
]);;