1 (* =========================================================== *)
\r
2 (* Theoretical results for floating point arithmetic *)
\r
3 (* Author: Alexey Solovyev *)
\r
4 (* Date: 2012-10-27 *)
\r
5 (* =========================================================== *)
\r
9 needs "arith/nat.hl";;
\r
10 needs "arith/num_exp_theory.hl";;
\r
12 module Float_theory = struct
\r
14 open Num_exp_theory;;
\r
17 (* Fix the minimal exponent *)
\r
18 let min_exp = !Arith_options.min_exp;;
\r
20 (* The main definition *)
\r
21 let min_exp_num_const = rand (mk_small_numeral_array min_exp);;
\r
22 let min_exp_const = mk_small_numeral min_exp;;
\r
24 let min_exp_def = new_definition (mk_eq(`min_exp:num`, min_exp_const));;
\r
26 let float_tm = `float_num s n e = (if s then (-- &1) else &1) * &(num_exp n e) / &(num_exp 1 min_exp)`;;
\r
27 let float = new_definition float_tm;;
\r
29 let FLOAT_OF_NUM = (GEN_ALL o prove)(`&n = float_num F n min_exp`,
\r
30 REWRITE_TAC[float; num_exp; REAL_MUL_LID] THEN
\r
31 REWRITE_TAC[GSYM REAL_OF_NUM_MUL; REAL_MUL_LID; real_div] THEN
\r
32 SUBGOAL_THEN (mk_comb(`(~)`, mk_eq(mk_comb(`&`, mk_binop `EXP` base_const `min_exp`), `&0`))) ASSUME_TAC THENL
\r
34 REWRITE_TAC[REAL_OF_NUM_EQ; EXP_EQ_0] THEN ARITH_TAC;
\r
37 ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_MUL_RINV; REAL_MUL_RID]);;
\r
39 let FLOAT_NEG = prove(`!s n e. --float_num s n e = float_num (~s) n e`,
\r
40 REWRITE_TAC[float] THEN REAL_ARITH_TAC);;
\r
42 let FLOAT_NEG_F = (GSYM o REWRITE_RULE[] o SPEC `T`) FLOAT_NEG;;
\r
43 let FLOAT_NEG_T = (GSYM o REWRITE_RULE[] o SPEC `F`) FLOAT_NEG;;
\r
45 let FLOAT_F_POS = prove(`!n e. &0 <= float_num F n e`,
\r
46 REPEAT GEN_TAC THEN REWRITE_TAC[float; REAL_MUL_LID; real_div] THEN
\r
47 MATCH_MP_TAC REAL_LE_MUL THEN
\r
48 REWRITE_TAC[REAL_POS; REAL_LE_INV_EQ]);;
\r
50 let FLOAT_T_NEG = prove(`!n e. float_num T n e <= &0`,
\r
51 REPEAT GEN_TAC THEN REWRITE_TAC[float; real_div] THEN
\r
52 REWRITE_TAC[REAL_ARITH `-- &1 * a * b <= &0 <=> &0 <= a * b`] THEN
\r
53 MATCH_MP_TAC REAL_LE_MUL THEN
\r
54 REWRITE_TAC[REAL_POS; REAL_LE_INV_EQ]);;
\r
56 let FLOAT_EQ_0 = prove(`!s n e. float_num s n e = &0 <=> n = 0`,
\r
57 REPEAT GEN_TAC THEN REWRITE_TAC[float; real_div] THEN
\r
58 REWRITE_TAC[REAL_ENTIRE] THEN
\r
61 STRIP_TAC THEN POP_ASSUM MP_TAC THENL
\r
63 COND_CASES_TAC THEN REAL_ARITH_TAC;
\r
64 REWRITE_TAC[REAL_OF_NUM_EQ; NUM_EXP_EQ_0];
\r
65 REWRITE_TAC[REAL_INV_EQ_0; REAL_OF_NUM_EQ; NUM_EXP_EQ_0] THEN
\r
70 DISJ2_TAC THEN DISJ1_TAC THEN
\r
71 ASM_REWRITE_TAC[REAL_OF_NUM_EQ; NUM_EXP_EQ_0]
\r
74 let FLOAT_F_bound = (GEN_ALL o prove)(`num_exp n1 e1 <= num_exp n2 e2
\r
75 ==> float_num F n1 e1 <= float_num F n2 e2`,
\r
77 REWRITE_TAC[float; REAL_MUL_LID; real_div] THEN
\r
78 MATCH_MP_TAC REAL_LE_RMUL THEN
\r
79 ASM_REWRITE_TAC[REAL_OF_NUM_LE; REAL_LE_INV_EQ; REAL_POS]);;
\r
81 let FLOAT_T_bound = (GEN_ALL o prove)(`num_exp n1 e1 <= num_exp n2 e2
\r
82 ==> float_num T n2 e2 <= float_num T n1 e1`,
\r
83 REWRITE_TAC[FLOAT_NEG_T; REAL_LE_NEG; FLOAT_F_bound]);;
\r