(* ========================================================================== *) (* FLYSPECK - BOOK FORMALIZATION *) (* *) (* Chapter: Jordan *) (* Copied from HOL Light jordan directory *) (* Author: Thomas C. Hales *) (* Date: 2010-07-08 *) (* ========================================================================== *) module Real_ext = struct open Parse_ext_override_interface;; (* open Tactics_jordan;; *) (* ------------------------------------------------------------------ *) (* Theorems that construct and propagate equality and inequality *) (* ------------------------------------------------------------------ *) (* ------------------------------------------------------------------ *) (* Propagation of =EQUAL= *) (* ------------------------------------------------------------------ *) unambiguous_interface();; prioritize_num();; let REAL_LE = REAL_OF_NUM_LE;; let pow = real_pow;; let REAL_INV2 = prove( `(inv(&. 2)*(&. 2) = (&.1)) /\ ((&. 2)*inv(&. 2) = (&.1))`, SUBGOAL_THEN `~((&.2) = (&.0))` MP_TAC THENL[ REAL_ARITH_TAC; SIMP_TAC[REAL_MUL_RINV;REAL_MUL_LINV]]);; let REAL_MUL_LTIMES = prove (`!x a b. (x*.a = x*.b) ==> (~(x=(&.0))) ==> (a =b)`, MESON_TAC[REAL_EQ_MUL_LCANCEL]);; let REAL_MUL_RTIMES = prove (`!x a b. (a*.x = b*.x) ==> (~(x=(&.0))) ==> (a =b)`, MESON_TAC[REAL_EQ_MUL_RCANCEL]);; let REAL_PROP_EQ_LMUL = REAL_MUL_LTIMES;; let REAL_PROP_EQ_RMUL = REAL_MUL_RTIMES;; let REAL_PROP_EQ_LMUL_' = REAL_EQ_MUL_LCANCEL (* |- !x y z. (x * y = x * z) = (x = &0) \/ (y = z) *);; let REAL_PROP_EQ_RMUL_' = REAL_EQ_MUL_LCANCEL (* |- !x y z. (x * z = y * z) = (x = y) \/ (z = &0) *);; (* see also minor variations REAL_LT_LMUL_EQ, REAL_LT_RMUL_EQ *) let REAL_PROP_EQ_SQRT = SQRT_INJ_COMPAT;; (* |- !x y. &0 <= x /\ &0 <= y ==> ((sqrt x = sqrt y) = x = y) *) (* ------------------------------------------------------------------ *) (* Construction of <=. *) (* ------------------------------------------------------------------ *) let REAL_MK_LE_SQUARE = REAL_LE_POW_2 ;; (* |- !x. &0 <= x pow 2 *) (* ------------------------------------------------------------------ *) (* Propagation of <=. *) (* ------------------------------------------------------------------ *) let REAL_MUL_LTIMES_LE = prove (`!x a b. (x*.a <=. x*.b) ==> (&.0 < x) ==> (a <=. b)`, MESON_TAC[REAL_LE_LMUL_EQ]);; (* virtually identical to REAL_LE_LCANCEL_IMP, REAL_LE_LMUL_EQ *) let REAL_MUL_RTIMES_LE = prove (`!x a b. (a*.x <=. b*.x) ==> (&.0 < x) ==> (a <=. b)`, MESON_TAC[REAL_LE_RMUL_EQ]);; (* virtually identical to REAL_LE_RCANCEL_IMP, REAL_LE_RMUL_EQ *) let REAL_PROP_LE_LCANCEL = REAL_MUL_LTIMES_LE;; let REAL_PROP_LE_RCANCEL = REAL_MUL_RTIMES_LE;; let REAL_PROP_LE_LMUL = REAL_LE_LMUL (* |- !x y z. &0 <= x /\ y <= z ==> x * y <= x * z *);; let REAL_PROP_LE_RMUL = REAL_LE_RMUL (* |- !x y z. x <= y /\ &0 <= z ==> x * z <= y * z *);; let REAL_PROP_LE_LRMUL = REAL_LE_MUL2;; (* |- !w x y z. &0 <= w /\ w <= x /\ &0 <= y /\ y <= z ==> w * y <= x * z *) let REAL_PROP_LE_POW = REAL_POW_LE2;; (* 2010-07-08 thales: POW_LE;; *) (* |- !n x y. &0 <= x /\ x <= y ==> x pow n <= y pow n *) let REAL_PROP_LE_SQRT = SQRT_MONO_LE_EQ_COMPAT;; (* |- !x y. &0 <= x /\ &0 <= y ==> (sqrt x <= sqrt y = x <= y) *) (* ------------------------------------------------------------------ *) (* Construction of LT *) (* ------------------------------------------------------------------ *) let REAL_MK_LT_SQUARE = REAL_LT_SQUARE;; (* |- !x. &0 < x * x = ~(x = &0) *) (* ------------------------------------------------------------------ *) (* Propagation of LT *) (* ------------------------------------------------------------------ *) let REAL_PROP_LT_LCANCEL = REAL_LT_LCANCEL_IMP (* |- !x y z. &0 < x /\ x * y < x * z ==> y < z *);; let REAL_PROP_LT_RCANCEL = REAL_LT_RCANCEL_IMP (* |- !x y z. &0 < z /\ x * z < y * z ==> x < y *);; let REAL_PROP_LT_LMUL = REAL_LT_LMUL (* |- !x y z. &0 < x /\ y < z ==> x * y < x * z *);; let REAL_PROP_LT_RMUL = REAL_LT_RMUL (* |- !x y z. x < y /\ &0 < z ==> x * z < y * z *);; (* minor variation REAL_LT_LMUL_IMP, REAL_LT_RMUL_IMP *) let REAL_PROP_LT_LRMUL= REAL_LT_MUL2;; (* |- !w x y z. &0 <= w /\ w < x /\ &0 <= y /\ y < z ==> w * y < x * z *) let REAL_PROP_LT_SQRT = SQRT_MONO_LT_EQ_COMPAT;; (* |- !x y. &0 <= x /\ &0 <= y ==> (sqrt x < sqrt y = x < y) *) (* ------------------------------------------------------------------ *) (* Constructors of Non-negative *) (* ------------------------------------------------------------------ *) let REAL_MK_NN_SQUARE = REAL_LE_SQUARE;; (* |- !x. &0 <= x * x *) let REAL_MK_NN_ABS = REAL_ABS_POS;; (* 2010 *) (* |- !x. &0 <= abs x *) (* moved here from float.hl *) (* from 778 *) let REAL_LE_LMUL_LOCAL = prove( `!x y z. &0 < x ==> ((x * y) <= (x * z) <=> y <= z)`, REPEAT GEN_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN AP_TERM_TAC THEN MATCH_MP_TAC REAL_LT_LMUL_EQ THEN ASM_REWRITE_TAC[]);; let ABS_TRIANGLE = prove( `!x y. abs(x + y) <= abs(x) + abs(y)`, REPEAT GEN_TAC THEN REWRITE_TAC[real_abs] THEN REPEAT COND_CASES_TAC THEN REWRITE_TAC[REAL_NEG_ADD; REAL_LE_REFL; REAL_LE_LADD; REAL_LE_RADD] THEN ASM_REWRITE_TAC[GSYM REAL_NEG_ADD; REAL_LE_NEGL; REAL_LE_NEGR] THEN RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN TRY(MATCH_MP_TAC REAL_LT_IMP_LE) THEN TRY(FIRST_ASSUM ACCEPT_TAC) THEN TRY(UNDISCH_TAC `(x + y) < &0`) THEN SUBST1_TAC(SYM(SPEC `&0` REAL_ADD_LID)) THEN REWRITE_TAC[REAL_NOT_LT] THEN MAP_FIRST MATCH_MP_TAC [REAL_LT_ADD2; REAL_LE_ADD2] THEN ASM_REWRITE_TAC[]);; let REAL_LE_LMUL_IMP = prove( `!x y z. &0 <= x /\ y <= z ==> (x * y) <= (x * z)`, REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN DISCH_THEN(DISJ_CASES_TAC o REWRITE_RULE[REAL_LE_LT]) THENL [FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP REAL_LE_LMUL_LOCAL th]); FIRST_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[REAL_MUL_LZERO] THEN MATCH_ACCEPT_TAC REAL_LE_REFL]);; (* from ? *) let ABS_POS = prove( `!x. &0 <= abs(x)`, GEN_TAC THEN ASM_CASES_TAC `&0 <= x` THENL [ALL_TAC; MP_TAC(SPEC `x:real` REAL_LE_NEGTOTAL) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC] THEN ASM_REWRITE_TAC[real_abs]);; let REAL_PROP_LE_LABS = prove( `!x y z. (y <=. z) ==> ((abs x)* y <=. (abs x) *z)`,(SIMP_TAC[REAL_LE_LMUL_IMP;ABS_POS]));; let REAL_LE_RMUL_IMP = prove( `!x y z. &0 <= x /\ y <= z ==> (y * x) <= (z * x)`, ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_ACCEPT_TAC REAL_LE_LMUL_IMP);; (* ------------------------------------------------------------------ *) (* Propagation of Non-negative *) (* ------------------------------------------------------------------ *) let REAL_PROP_NN_POS = prove(`! x y. x<. y ==> x <= y`,MESON_TAC[REAL_LT_LE]);; let REAL_PROP_NN_ADD2 = REAL_LE_ADD (* |- !x y. &0 <= x /\ &0 <= y ==> &0 <= x + y *);; let REAL_PROP_NN_DOUBLE = REAL_LE_DOUBLE (* |- !x. &0 <= x + x <=> &0 <= x *);; let REAL_PROP_NN_RCANCEL= prove(`!x y. &.0 <. x /\ (&.0) <=. y*.x ==> ((&.0) <=. y)`, MESON_TAC[REAL_PROP_LE_RCANCEL;REAL_MUL_LZERO]);; let REAL_PROP_NN_LCANCEL= prove(`!x y. &.0 <. x /\ (&.0) <=. x*.y ==> ((&.0) <=. y)`, MESON_TAC[REAL_PROP_LE_LCANCEL;REAL_MUL_RZERO]);; let REAL_PROP_NN_MUL2 = REAL_LE_MUL (* |- !x y. &0 <= x /\ &0 <= y ==> &0 <= x * y *);; let REAL_PROP_NN_POW = REAL_POW_LE (* |- !x n. &0 <= x ==> &0 <= x pow n *);; let REAL_PROP_NN_SQUARE = REAL_LE_POW_2;; (* |- !x. &0 <= x pow 2 *) let REAL_PROP_NN_SQRT = SQRT_POS_LE;; (* |- !x. &0 <= x ==> &0 <= sqrt x *) let REAL_PROP_NN_INV = REAL_LE_INV_EQ (* |- !x. &0 <= inv x = &0 <= x *);; let REAL_PROP_NN_SIN = SIN_POS_PI_LE;; (* |- !x. &0 <= x /\ x <= pi ==> &0 <= sin x *) let REAL_PROP_NN_ATN = ATN_POS_LE;; (* |- &0 <= atn x = &0 <= x *) (* ------------------------------------------------------------------ *) (* Constructor of POS *) (* ------------------------------------------------------------------ *) let REAL_MK_POS_ABS = REAL_ABS_NZ (* |- !x. ~(x = &0) = &0 < abs x *);; let REAL_MK_POS_EXP = REAL_EXP_POS_LT;; (* |- !x. &0 < exp x *) (* let REAL_MK_POS_LN = LN_POS_LT;; (* |- !x. &1 < x ==> &0 < ln x *) *) let REAL_MK_POS_PI = PI_POS;; (* |- &0 < pi *) (* ------------------------------------------------------------------ *) (* Propagation of POS *) (* ------------------------------------------------------------------ *) let REAL_PROP_POS_ADD2 = REAL_LT_ADD (* |- !x y. &0 < x /\ &0 < y ==> &0 < x + y *);; let REAL_PROP_POS_LADD = REAL_LET_ADD (* |- !x y. &0 <= x /\ &0 < y ==> &0 < x + y *);; let REAL_PROP_POS_RADD = REAL_LTE_ADD (* |- !x y. &0 < x /\ &0 <= y ==> &0 < x + y *);; let REAL_PROP_POS_LMUL = REAL_LT_MUL_EQ;; (* REAL_LT_LMUL_0;; *) (* |- !x y. &0 < x ==> (&0 < x * y = &0 < y) *) let REAL_PROP_POS_RMUL = REAL_LT_MUL_EQ;; (* REAL_LT_RMUL_0;; *) (* |- !x y. &0 < y ==> (&0 < x * y = &0 < x) *) let REAL_PROP_POS_MUL2 = REAL_LT_MUL (* |- !x y. &0 < x /\ &0 < y ==> &0 < x * y *);; let REAL_PROP_POS_SQRT = SQRT_POS_LT;; (* |- !x. &0 < x ==> &0 < sqrt x *) let REAL_PROP_POS_POW = REAL_POW_LT (* |- !x n. &0 < x ==> &0 < x pow n *);; let REAL_PROP_POS_INV = REAL_LT_INV (* |- !x. &0 < x ==> &0 < inv x *);; let REAL_PROP_POS_SIN = SIN_POS_PI;; (* |- !x. &0 < x /\ x < pi ==> &0 < sin x *) let REAL_PROP_POS_TAN = TAN_POS_PI2;; (* |- !x. &0 < x /\ x < pi / &2 ==> &0 < tan x *) let REAL_PROP_POS_ATN = ATN_POS_LT;; (* |- &0 < atn x = &0 < x *) (* ------------------------------------------------------------------ *) (* Construction of NZ *) (* ------------------------------------------------------------------ *) (* renamed from REAL_MK_NZ_OF_POS *) let REAL_MK_NZ_POS = REAL_POS_NZ (* |- !x. &0 < x ==> ~(x = &0) *);; let REAL_MK_NZ_EXP = REAL_EXP_NZ;; (* |- !x. ~(exp x = &0) *) (* ------------------------------------------------------------------ *) (* Propagation of NZ *) (* ------------------------------------------------------------------ *) (* renamed from REAL_ABS_NZ, moved from float.ml *) let REAL_PROP_NZ_ABS = prove(`!x. (~(x = (&.0))) ==> (~(abs(x) = (&.0)))`, REWRITE_TAC[REAL_ABS_ZERO]);; let REAL_PROP_NZ_POW = REAL_POW_NZ (* |- !x n. ~(x = &0) ==> ~(x pow n = &0) *);; (* let REAL_PROP_NZ_INV = REAL_INV_NZ;; (* |- !x. ~(x = &0) ==> ~(inv x = &0) *) *) (* ------------------------------------------------------------------ *) (* Propagation of ZERO *) (* ------------------------------------------------------------------ *) let REAL_PROP_ZERO_ABS = REAL_ABS_ZERO (* |- !x. (abs x = &0) = x = &0); *);; (* let REAL_PROP_ZERO_NEG = REAL_NEG_EQ_0 ;; (* |- !x. (--x = &0) = x = &0 *) *) let REAL_PROP_ZERO_INV = REAL_INV_EQ_0 (* |- !x. (inv x = &0) = x = &0 *);; (* let REAL_PROP_ZERO_NEG = REAL_NEG_EQ0;; (* |- !x. (--x = &0) = x = &0 *) *) (* let REAL_PROP_ZERO_SUMSQ = REAL_SUMSQ;; (* |- !x y. (x * x + y * y = &0) = (x = &0) /\ (y = &0) *) *) let REAL_PROP_ZERO_POW = REAL_POW_EQ_0;; (* |- !x n. (x pow n = &0) = (x = &0) /\ ~(n = 0) *) let REAL_PROP_ZERO_SQRT = SQRT_EQ_0_COMPAT;; (* |- !x. &0 <= x ==> (x / sqrt x = sqrt x) *) (* ------------------------------------------------------------------ *) (* Special values of functions *) (* ------------------------------------------------------------------ *) let REAL_SV_LADD_0 = REAL_ADD_LID (* |- !x. &0 + x = x); *);; let REAL_SV_INV_0 = REAL_INV_0 (* |- inv (&0) = &0 *);; let REAL_SV_RMUL_0 = REAL_MUL_RZERO (* |- !x. x * &0 = &0 *);; let REAL_SV_LMUL_0 = REAL_MUL_LZERO (* |- !x. &0 * x = &0 *);; let REAL_SV_NEG_0 = REAL_NEG_0 (* |- -- &0 = &0 *);; let REAL_SV_ABS_0 = REAL_ABS_0 (* |- abs (&0) = &0 *);; let REAL_SV_EXP_0 = REAL_EXP_0;; (* |- exp (&0) = &1 *) (* let REAL_SV_LN_1 = LN_1;; (* |- ln (&1) = &0 *) *) let REAL_SV_SQRT_0 = SQRT_0;; (* |- sqrt (&0) = &0 *) let REAL_SV_TAN_0 = TAN_0;; (* |- tan (&0) = &0 *) let REAL_SV_TAN_PI = TAN_PI;; (* |- tan pi = &0 *) (* ------------------------------------------------------------------ *) (* A tactic that multiplies a real on the left *) (* ------------------------------------------------------------------ *) (** #g `a:real = b:real`;; #e (REAL_LMUL_TAC `c:real`);; it : goalstack = 2 subgoals (2 total) `~(c = &0)` `c * a = c * b` 0 [`~(c = &0)`] # **) (* ------------------------------------------------------------------ *) let REAL_LMUL_TAC t = let REAL_MUL_LTIMES = prove ((`!x a b. (((~(x=(&0)) ==> (x*a = x*b)) /\ ~(x=(&0))) ==> (a = b))`), MESON_TAC[REAL_EQ_MUL_LCANCEL]) in (MATCH_MP_TAC (SPEC t REAL_MUL_LTIMES)) THEN CONJ_TAC THENL [DISCH_TAC; ALL_TAC];; (* ------------------------------------------------------------------ *) (* Right multiply by a real *) (* ------------------------------------------------------------------ *) let REAL_RMUL_TAC t = let REAL_MUL_RTIMES = prove (`!x a b. ((~(x=(&0))==>(a*x = b*x)) /\ ~(x=(&0))) ==> (a = b)`, MESON_TAC[REAL_EQ_MUL_RCANCEL]) in (MATCH_MP_TAC (SPEC t REAL_MUL_RTIMES)) THEN CONJ_TAC THENL [DISCH_TAC; ALL_TAC];; pop_priority();; end;;