(* ---------------------------------------------------------------------- *)
(* Reals *)
(* ---------------------------------------------------------------------- *)
let real_ty = `:real`;;
let rx = `x:real`;;
let ry = `y:real`;;
let rz = `z:real`;;
let rzero = `&0`;;
let req = `(=):real->real->bool`;;
let rneq = `(<>):real->real->bool`;;
let rlt = `(<):real->real->bool`;;
let rgt = `(>):real->real->bool`;;
let rle = `(<=):real->real->bool`;;
let rge = `(>=):real->real->bool`;;
let rm = `( * ):real->real->real`;;
let rs = `(-):real->real->real`;;
let rn = `(--):real->real`;;
let rd = `(/):real->real->real`;;
let rp = `(+):real->real->real`;;
let rzero = `&0`;;
let rone = `&1`;;
let rlast = `LAST:(real) list -> real`;;
let rappend = `APPEND:(real) list -> real list -> real list`;;
let mk_rlist l = mk_list (l,real_ty);;
let diffl_tm = `(diffl)`;;
let dest_diffl tm =
try
let l,var = dest_comb tm in
let dp,p' = dest_comb l in
let d,p = dest_comb dp in
if not (d = diffl_tm) then failwith "dest_diffl: not a diffl" else
let _,bod = dest_abs p in
bod,p'
with _ -> failwith "dest_diffl";;
let dest_mult =
try
dest_binop rm
with _ -> failwith "dest_mult";;
let mk_mult = mk_binop rm;;
let pow_tm = `(pow)`;;
let dest_pow =
try
dest_binop pow_tm
with _ -> failwith "dest_pow";;
let mk_plus = mk_binop rp;;
let mk_negative = curry mk_comb rn;;
let dest_plus =
try
dest_binop rp
with _ -> failwith "dest_plus";;
let REAL_DENSE = prove(
`!x y. x < y ==> ?z. x < z /\ z < y`,
(* {{{ Proof *)
REPEAT STRIP_TAC THEN
CLAIM `&0 < y - x` THENL
[REWRITE_TAC[
REAL_LT_SUB_LADD;REAL_ADD_LID] THEN
POP_ASSUM MATCH_ACCEPT_TAC;
DISCH_THEN (ASSUME_TAC o (MATCH_MP
REAL_DOWN)) THEN
POP_ASSUM MP_TAC THEN STRIP_TAC THEN
EXISTS_TAC `e + x` THEN
STRIP_TAC THENL
[ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN
CONV_TAC (LAND_CONV (ONCE_REWRITE_CONV[GSYM
REAL_ADD_RID])) THEN
MATCH_MP_TAC
REAL_LET_ADD2 THEN
STRIP_TAC THENL
[MATCH_ACCEPT_TAC
REAL_LE_REFL;
FIRST_ASSUM MATCH_ACCEPT_TAC];
MATCH_EQ_MP_TAC ((GEN `y:real` (GEN `z:real` (ISPECL [`y:real`;`z:real`;`-- x`]
REAL_LT_RADD)))) THEN
REWRITE_TAC[GSYM REAL_ADD_ASSOC;
REAL_ADD_RINV;
REAL_ADD_RID] THEN
REWRITE_TAC[GSYM
real_sub] THEN
FIRST_ASSUM MATCH_ACCEPT_TAC]]);;
(* }}} *)
let REAL_LT_EXISTS = prove(
`!x. ?y. x < y`,
(* {{{ Proof *)
GEN_TAC THEN
EXISTS_TAC `x + &1` THEN
REAL_ARITH_TAC);;
(* }}} *)
let REAL_GT_EXISTS = prove(
`!x. ?y. y < x`,
(* {{{ Proof *)
GEN_TAC THEN
EXISTS_TAC `x - &1` THEN
REAL_ARITH_TAC);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
let BINOMIAL_LEMMA_LT = prove_by_refinement(
`!x y. &0 < x /\ &0 < y
==> !n. 0 < n ==> x pow n + y pow n <= (x + y) pow n`,
(* {{{ Proof *)
[
REPEAT GEN_TAC;
STRIP_TAC;
INDUCT_TAC;
ARITH_TAC;
REWRITE_TAC[
real_pow];
STRIP_TAC;
CASES_ON `n = 0`;
ASM_REWRITE_TAC[
real_pow;
REAL_MUL_RID;
REAL_LE_REFL];
CLAIM `0 < n`;
POP_ASSUM MP_TAC THEN ARITH_TAC;
DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x)));
MATCH_MP_TAC
REAL_LE_TRANS;
EXISTS_TAC `(x + y) * (x pow n + y pow n)`;
STRIP_TAC;
REWRITE_TAC[
REAL_ADD_RDISTRIB];
MATCH_MP_TAC
REAL_LE_ADD2;
CONJ_TAC;
MATCH_MP_TAC
REAL_LE_LMUL;
STRIP_TAC;
FIRST_ASSUM (fun x -> MP_TAC x THEN ARITH_TAC);
MATCH_MP_TAC (REAL_ARITH `&0 <= y ==> x <= x + y`);
MATCH_MP_TAC
REAL_POW_LE;
FIRST_ASSUM (fun x -> MP_TAC x THEN ARITH_TAC);
REWRITE_TAC[REAL_ADD_LDISTRIB];
MATCH_MP_TAC (REAL_ARITH `&0 <= y ==> x <= y + x`);
MATCH_MP_TAC
REAL_LE_MUL;
CONJ_TAC;
FIRST_ASSUM (fun x -> MP_TAC x THEN REAL_ARITH_TAC);
MATCH_MP_TAC (REAL_ARITH `x < y ==> x <= y`);
MATCH_MP_TAC
REAL_POW_LT;
FIRST_ASSUM MATCH_ACCEPT_TAC;
MATCH_MP_TAC
REAL_LE_LMUL;
CONJ_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
FIRST_ASSUM MATCH_ACCEPT_TAC;
]);;
(* }}} *)
let BINOMIAL_LEMMA = prove_by_refinement(
`!x y. &0 <= x /\ &0 <= y
==> !n. 0 < n ==> x pow n + y pow n <= (x + y) pow n`,
(* {{{ Proof *)
[
REPEAT GEN_TAC;
STRIP_TAC;
CASES_ON `(x = &0) \/ (y = &0)`;
POP_ASSUM DISJ_CASES_TAC;
ASM_REWRITE_TAC[
real_pow;REAL_ADD_LID;
POW_0];
REPEAT STRIP_TAC;
CLAIM `n = SUC (
PRE n)`;
POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ONCE_ASM_REWRITE_TAC[];
ASM_REWRITE_TAC[
POW_0;REAL_ADD_LID;
real_pow;
REAL_LE_REFL];
REPEAT STRIP_TAC;
CLAIM `n = SUC (
PRE n)`;
POP_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
ONCE_ASM_REWRITE_TAC[];
ASM_REWRITE_TAC[
POW_0;REAL_ADD_LID;
REAL_ADD_RID;
real_pow;
REAL_LE_REFL];
POP_ASSUM MP_TAC THEN REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC;
MATCH_MP_TAC
BINOMIAL_LEMMA_LT;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
let REAL_MUL_LT = prove_by_refinement(
`!x y. x * y < &0 <=> (x < &0 /\ &0 < y) \/ (&0 < x /\ y < &0)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
EQ_TAC;
REPEAT STRIP_TAC;
CCONTR_TAC;
REWRITE_ASSUMS ([
REAL_NOT_LT;DE_MORGAN_THM;] @ !REAL_REWRITES);
POP_ASSUM MP_TAC THEN STRIP_TAC;
CLAIM `x = &0`;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
DISCH_THEN (REWRITE_ASSUMS o list);
REWRITE_ASSUMS !REAL_REWRITES;
ASM_MESON_TAC !REAL_REWRITES;
CLAIM `&0 * &0 <= x * y`;
MATCH_MP_TAC
REAL_LE_MUL2;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
REAL_SIMP_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
CLAIM `&0 * &0 <= --x * --y`;
MATCH_MP_TAC
REAL_LE_MUL2;
REAL_SIMP_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
REAL_SIMP_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
CLAIM `y = &0`;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
DISCH_THEN (REWRITE_ASSUMS o list);
REWRITE_ASSUMS !REAL_REWRITES;
ASM_REWRITE_TAC[];
EVERY_ASSUM MP_TAC THEN ARITH_TAC;
(* save *)
REPEAT STRIP_TAC;
CLAIM `&0 < --x`;
EVERY_ASSUM MP_TAC THEN ARITH_TAC;
STRIP_TAC;
CLAIM `&0 * &0 < --x * y`;
MATCH_MP_TAC
REAL_LT_MUL2;
REAL_SIMP_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
REAL_SIMP_TAC;
REWRITE_TAC[REAL_ARITH `--y * x = --(y * x)`];
REAL_ARITH_TAC;
CLAIM `&0 < --y`;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
STRIP_TAC;
CLAIM `&0 * &0 < x * --y`;
MATCH_MP_TAC
REAL_LT_MUL2;
REAL_SIMP_TAC;
ASM_REWRITE_TAC[];
REAL_SIMP_TAC;
REWRITE_TAC[REAL_ARITH `x * --y = --(x * y)`];
REAL_ARITH_TAC;
]);;
(* }}} *)
let REAL_MUL_GT = prove_by_refinement(
`!x y. &0 < x * y <=> (x < &0 /\ y < &0) \/ (&0 < x /\ &0 < y)`,
(* {{{ Proof *)
[
REPEAT STRIP_TAC;
EQ_TAC;
REPEAT STRIP_TAC;
ONCE_REWRITE_ASSUMS[ARITH_RULE `x < y <=> -- y < -- x`];
REWRITE_ASSUMS[GSYM
REAL_MUL_RNEG];
REWRITE_ASSUMS[REAL_ARITH `-- &0 = &0`;
REAL_MUL_LT];
POP_ASSUM MP_TAC THEN REPEAT STRIP_TAC;
DISJ1_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
REPEAT STRIP_TAC;
ONCE_REWRITE_TAC [ARITH_RULE `x * y = --x * --y`];
ONCE_REWRITE_TAC [ARITH_RULE `&0 = &0 * &0`];
MATCH_MP_TAC
REAL_LT_MUL2;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
ONCE_REWRITE_TAC [ARITH_RULE `&0 = &0 * &0`];
MATCH_MP_TAC
REAL_LT_MUL2;
EVERY_ASSUM MP_TAC THEN REAL_ARITH_TAC;
]);;
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)
(* }}} *)