Commit c7ff0b5e authored by Heiko Becker's avatar Heiko Becker

WIP: Start working on HOL4 fixed-point checking

parent 8a64fbf4
......@@ -12,7 +12,7 @@ val (approxEnv_rules, approxEnv_ind, approxEnv_cases) = Hol_reln `
(!(E1:env) (E2:env) (defVars: num -> mType option) (A:analysisResult) (fVars:num_set) (dVars:num_set) v1 v2 x.
approxEnv E1 defVars A fVars dVars E2 /\
(defVars x = SOME m) /\
(abs (v1 - v2) <= abs v1 * (mTypeToQ m)) /\
(abs (v1 - v2) <= abs v1 * (mTypeToR m)) /\
(lookup x (union fVars dVars) = NONE) ==>
approxEnv (updEnv x v1 E1) (updDefVars x m defVars) A (insert x () fVars) dVars (updEnv x v2 E2)) /\
(!(E1:env) (E2:env) (defVars: num -> mType option) (A:analysisResult)
......@@ -58,7 +58,7 @@ val approxEnv_fVar_bounded = store_thm (
E2 x = SOME v2 /\
x IN (domain fVars) /\
Gamma x = SOME m ==>
abs (v - v2) <= (abs v) * (mTypeToQ m)``,
abs (v - v2) <= (abs v) * (mTypeToR m)``,
rpt strip_tac
\\ qspec_then
`\E1 Gamma absenv fVars dVars E2.
......@@ -67,7 +67,7 @@ val approxEnv_fVar_bounded = store_thm (
E2 x = SOME v2 /\
x IN (domain fVars) /\
Gamma x = SOME m ==>
abs (v - v2) <= (abs v) * (mTypeToQ m)`
abs (v - v2) <= (abs v) * (mTypeToR m)`
(fn thm => irule (SIMP_RULE std_ss [] thm))
approxEnv_ind
\\ rpt strip_tac
......
......@@ -17,10 +17,10 @@ val const_abs_err_bounded = store_thm ("const_abs_err_bounded",
``!(n:real) (nR:real) (nF:real) (E1 E2:env) (m:mType) (defVars: num -> mType option).
eval_exp E1 (toRMap defVars) (Const M0 n) nR M0 /\
eval_exp E2 defVars (Const m n) nF m ==>
abs (nR - nF) <= abs n * (mTypeToQ m)``,
abs (nR - nF) <= abs n * (mTypeToR m)``,
rpt strip_tac
\\ fs[eval_exp_cases]
\\ `perturb n delta = n` by (irule delta_0_deterministic \\ fs[mTypeToQ_def])
\\ `perturb n delta = n` by (irule delta_0_deterministic \\ fs[mTypeToR_def])
\\ simp[perturb_def, Rabs_err_simpl, REAL_ABS_MUL]
\\ irule REAL_LE_LMUL_IMP \\ REAL_ASM_ARITH_TAC);
......@@ -35,7 +35,7 @@ val add_abs_err_bounded = store_thm ("add_abs_err_bounded",
eval_exp (updEnv 2 e2F (updEnv 1 e1F emptyEnv)) (updDefVars 2 m2 (updDefVars 1 m1 defVars)) (Binop Plus (Var 1) (Var 2)) vF m /\
abs (e1R - e1F) <= err1 /\
abs (e2R - e2F) <= err2 ==>
abs (vR - vF) <= err1 + err2 + (abs (e1F + e2F) * (mTypeToQ m))``,
abs (vR - vF) <= err1 + err2 + (abs (e1F + e2F) * (mTypeToR m))``,
rpt strip_tac
\\ qpat_x_assum `eval_exp E1 _ (toREval (Binop Plus e1 e2)) _ _` (fn thm => assume_tac (ONCE_REWRITE_RULE [toREval_def] thm))
\\ fs []
......@@ -80,7 +80,7 @@ val subtract_abs_err_bounded = store_thm ("subtract_abs_err_bounded",
eval_exp (updEnv 2 e2F (updEnv 1 e1F emptyEnv)) (updDefVars 2 m2 (updDefVars 1 m1 defVars)) (Binop Sub (Var 1) (Var 2)) vF m /\
abs (e1R - e1F) <= err1 /\
abs (e2R - e2F) <= err2 ==>
abs (vR - vF) <= err1 + err2 + (abs (e1F - e2F) * (mTypeToQ m))``,
abs (vR - vF) <= err1 + err2 + (abs (e1F - e2F) * (mTypeToR m))``,
rpt strip_tac
\\ qpat_x_assum `eval_exp E1 _ (toREval (Binop Sub e1 e2)) _ _` (fn thm => assume_tac (ONCE_REWRITE_RULE [toREval_def] thm))
\\ fs []
......@@ -129,7 +129,7 @@ val mult_abs_err_bounded = store_thm ("mult_abs_err_bounded",
eval_exp (updEnv 2 e2F (updEnv 1 e1F emptyEnv)) (updDefVars 2 m2 (updDefVars 1 m1 defVars)) (Binop Mult (Var 1) (Var 2)) vF m /\
abs (e1R - e1F) <= err1 /\
abs (e2R - e2F) <= err2 ==>
abs (vR - vF) <= abs (e1R * e2R - e1F * e2F) + (abs (e1F * e2F) * (mTypeToQ m))``,
abs (vR - vF) <= abs (e1R * e2R - e1F * e2F) + (abs (e1F * e2F) * (mTypeToR m))``,
rpt strip_tac
\\ qpat_x_assum `eval_exp E1 _ (toREval (Binop Mult e1 e2)) _ _` (fn thm => assume_tac (ONCE_REWRITE_RULE [toREval_def] thm))
\\ fs []
......@@ -171,7 +171,7 @@ val div_abs_err_bounded = store_thm ("div_abs_err_bounded",
eval_exp (updEnv 2 e2F (updEnv 1 e1F emptyEnv)) (updDefVars 2 m2 (updDefVars 1 m1 defVars)) (Binop Div (Var 1) (Var 2)) vF m /\
abs (e1R - e1F) <= err1 /\
abs (e2R - e2F) <= err2 ==>
abs (vR - vF) <= abs (e1R / e2R - e1F / e2F) + (abs (e1F / e2F) * (mTypeToQ m))``,
abs (vR - vF) <= abs (e1R / e2R - e1F / e2F) + (abs (e1F / e2F) * (mTypeToR m))``,
rpt strip_tac
\\ qpat_x_assum `eval_exp E1 _ (toREval (Binop Div e1 e2)) _ _` (fn thm => assume_tac (ONCE_REWRITE_RULE [toREval_def] thm))
\\ fs []
......@@ -215,7 +215,7 @@ val fma_abs_err_bounded = store_thm ("fma_abs_err_bounded",
abs (e1R - e1F) <= err1 /\
abs (e2R - e2F) <= err2 /\
abs (e3R - e3F) <= err3 ==>
abs (vR - vF) <= abs ((e1R - e1F) + (e2R * e3R - e2F * e3F)) + abs (e1F + e2F * e3F) * (mTypeToQ m)``,
abs (vR - vF) <= abs ((e1R - e1F) + (e2R * e3R - e2F * e3F)) + abs (e1F + e2F * e3F) * (mTypeToR m)``,
rpt strip_tac
\\ qpat_x_assum `eval_exp E1 _ (toREval (Fma e1 e2 e3)) _ _` (fn thm => assume_tac (ONCE_REWRITE_RULE [toREval_def] thm))
\\ fs []
......@@ -254,7 +254,7 @@ val round_abs_err_bounded = store_thm ("round_abs_err_bounded",
eval_exp (updEnv 1 nF1 emptyEnv) (updDefVars 1 m defVars)
(Downcast machineEpsilon (Var 1)) nF machineEpsilon /\
abs (nR - nF1) <= err ==>
abs (nR - nF) <= err + (abs nF1) * (mTypeToQ machineEpsilon)``,
abs (nR - nF) <= err + (abs nF1) * (mTypeToR machineEpsilon)``,
rpt strip_tac
\\ `nR - nF = (nR - nF1) + (nF1 - nF)` by REAL_ASM_ARITH_TAC
\\ fs []
......
This diff is collapsed.
......@@ -85,29 +85,29 @@ val (eval_exp_rules, eval_exp_ind, eval_exp_cases) = Hol_reln `
E x = SOME v ==>
eval_exp E defVars (Var x) v m) /\
(!E defVars m n delta.
abs delta <= (mTypeToQ m) ==>
abs delta <= (mTypeToR m) ==>
eval_exp E defVars (Const m n) (perturb n delta) m) /\
(!E defVars m f1 v1.
eval_exp E defVars f1 v1 m ==>
eval_exp E defVars (Unop Neg f1) (evalUnop Neg v1) m) /\
(!E defVars m f1 v1 delta.
abs delta <= (mTypeToQ m) /\
abs delta <= (mTypeToR m) /\
(v1 <> 0) /\
eval_exp E defVars f1 v1 m ==>
eval_exp E defVars (Unop Inv f1) (perturb (evalUnop Inv v1) delta) m) /\
(!E defVars m m1 f1 v1 delta.
isMorePrecise m1 m /\
abs delta <= (mTypeToQ m) /\
abs delta <= (mTypeToR m) /\
eval_exp E defVars f1 v1 m1 ==>
eval_exp E defVars (Downcast m f1) (perturb v1 delta) m) /\
(!E defVars m1 m2 b f1 f2 v1 v2 delta.
abs delta <= (mTypeToQ (join m1 m2)) /\
abs delta <= (mTypeToR (join m1 m2)) /\
eval_exp E defVars f1 v1 m1 /\
eval_exp E defVars f2 v2 m2 /\
((b = Div) ==> (v2 <> 0)) ==>
eval_exp E defVars (Binop b f1 f2) (perturb (evalBinop b v1 v2) delta) (join m1 m2)) /\
(!E defVars m1 m2 m3 f1 f2 f3 v1 v2 v3 delta.
abs delta <= (mTypeToQ (join3 m1 m2 m3)) /\
abs delta <= (mTypeToR (join3 m1 m2 m3)) /\
eval_exp E defVars f1 v1 m1 /\
eval_exp E defVars f2 v2 m2 /\
eval_exp E defVars f3 v3 m3 ==>
......@@ -144,7 +144,7 @@ save_thm ("Downcast_dist", Downcast_dist);
val Const_dist' = store_thm (
"Const_dist'",
``!m n delta v m' E Gamma.
(abs delta) <= (mTypeToQ m) /\
(abs delta) <= (mTypeToR m) /\
v = perturb n delta /\
m' = m ==>
eval_exp E Gamma (Const m n) v m'``,
......@@ -162,7 +162,7 @@ val Unop_neg' = store_thm (
val Unop_inv' = store_thm (
"Unop_inv'",
``!m f1 v1 delta v m' E Gamma.
(abs delta) <= (mTypeToQ m) /\
(abs delta) <= (mTypeToR m) /\
eval_exp E Gamma f1 v1 m /\
(v1 <> 0) /\
v = perturb (evalUnop Inv v1) delta /\
......@@ -173,7 +173,7 @@ val Unop_inv' = store_thm (
val Downcast_dist' = store_thm ("Downcast_dist'",
``!m m1 f1 v1 delta v m' E Gamma.
isMorePrecise m1 m /\
(abs delta) <= (mTypeToQ m) /\
(abs delta) <= (mTypeToR m) /\
eval_exp E Gamma f1 v1 m1 /\
v = perturb v1 delta /\
m' = m ==>
......@@ -185,7 +185,7 @@ val Downcast_dist' = store_thm ("Downcast_dist'",
val Binop_dist' = store_thm ("Binop_dist'",
``!m1 m2 op f1 f2 v1 v2 delta v m' E Gamma.
(abs delta) <= (mTypeToQ m') /\
(abs delta) <= (mTypeToR m') /\
eval_exp E Gamma f1 v1 m1 /\
eval_exp E Gamma f2 v2 m2 /\
((op = Div) ==> (v2 <> 0)) /\
......@@ -196,7 +196,7 @@ val Binop_dist' = store_thm ("Binop_dist'",
val Fma_dist' = store_thm ("Fma_dist'",
``!m1 m2 m3 f1 f2 f3 v1 v2 v3 delta v m' E Gamma.
(abs delta) <= (mTypeToQ m') /\
(abs delta) <= (mTypeToR m') /\
eval_exp E Gamma f1 v1 m1 /\
eval_exp E Gamma f2 v2 m2 /\
eval_exp E Gamma f3 v3 m3 /\
......@@ -227,8 +227,8 @@ val delta_0_deterministic = store_thm("delta_0_deterministic",
fs [perturb_def,ABS_BOUNDS,REAL_LE_ANTISYM]);
val delta_M0_deterministic = store_thm("delta_M0_deterministic",
``!(v:real) (delta:real). abs delta <= mTypeToQ M0 ==> perturb v delta = v``,
fs [mTypeToQ_def,perturb_def,ABS_BOUNDS,REAL_LE_ANTISYM]);
``!(v:real) (delta:real). abs delta <= mTypeToR M0 ==> perturb v delta = v``,
fs [mTypeToR_def,perturb_def,ABS_BOUNDS,REAL_LE_ANTISYM]);
val toRMap_def = Define `
toRMap (d:num -> mType option) (n:num) : mType option =
......@@ -264,7 +264,7 @@ val meps_0_deterministic = store_thm("meps_0_deterministic",
Induct_on `f`
>- (rw [toREval_def] \\ fs [eval_exp_cases])
>- (rw [toREval_def]
\\ fs [eval_exp_cases, mTypeToQ_def, delta_0_deterministic])
\\ fs [eval_exp_cases, mTypeToR_def, delta_0_deterministic])
>- (rw []
\\ rpt (
qpat_x_assum `eval_exp _ _ (toREval _) _ _`
......@@ -272,7 +272,7 @@ val meps_0_deterministic = store_thm("meps_0_deterministic",
\\ Cases_on `u` \\ fs [eval_exp_cases] \\ rw []
\\ fs [eval_exp_cases]
>- (res_tac \\ fs [REAL_NEG_EQ])
>- (res_tac \\ fs [mTypeToQ_def, delta_0_deterministic]))
>- (res_tac \\ fs [mTypeToR_def, delta_0_deterministic]))
>- (rw[]
\\ rename1 `Binop b f1 f2`
\\ rpt (
......@@ -287,7 +287,7 @@ val meps_0_deterministic = store_thm("meps_0_deterministic",
\\ rename1 `eval_exp _ _ (toREval f2) vf22 m2`
\\ `m1 = M0 /\ m2 = M0` by (conj_tac \\ irule toRMap_eval_M0 \\ asm_exists_tac \\ fs [])
\\ rw []
\\ fs [join_def, mTypeToQ_def, delta_0_deterministic]
\\ fs [join_def, mTypeToR_def, delta_0_deterministic]
\\ qpat_x_assum `!v1 v2 E defVars. _ /\ _ ==> v1 = v2` (fn thm =>qspecl_then [`vf21`,`vf22`] ASSUME_TAC thm)
\\ qpat_x_assum `!v1 v2 E defVars. _ /\ _ ==> v1 = v2` (fn thm =>qspecl_then [`vf11`,`vf12`] ASSUME_TAC thm)
\\ res_tac
......@@ -305,7 +305,7 @@ val meps_0_deterministic = store_thm("meps_0_deterministic",
\\ qpat_x_assum `!v1 v2 E defVars. _ /\ _ ==> v1 = v2` (fn thm =>qspecl_then [`v3`,`v3'`, `E`, `defVars`] ASSUME_TAC thm)
\\ qpat_x_assum `!v1 v2 E defVars. _ /\ _ ==> v1 = v2` (fn thm =>qspecl_then [`v2'`,`v2''`, `E`, `defVars`] ASSUME_TAC thm)
\\ qpat_x_assum `!v1 v2 E defVars. _ /\ _ ==> v1 = v2` (fn thm =>qspecl_then [`v1'`,`v1''`, `E`, `defVars`] ASSUME_TAC thm)
\\ fs [join3_def, join_def, mTypeToQ_def, delta_0_deterministic])
\\ fs [join3_def, join_def, mTypeToR_def, delta_0_deterministic])
>- (rw[]
\\ rpt (
qpat_x_assum `eval_exp _ _ (toREval (Downcast _ _)) _ _`
......@@ -322,7 +322,7 @@ variables in the Environment.
val binary_unfolding = store_thm("binary_unfolding",
``!(b:binop) (f1:(real)exp) (f2:(real)exp) E Gamma (v:real) v1 v2 m1 m2 delta.
(b = Div ==> (v2 <> 0)) /\
(abs delta) <= (mTypeToQ (join m1 m2)) /\
(abs delta) <= (mTypeToR (join m1 m2)) /\
eval_exp E Gamma f1 v1 m1 /\
eval_exp E Gamma f2 v2 m2 /\
eval_exp E Gamma (Binop b f1 f2) (perturb (evalBinop b v1 v2) delta) (join m1 m2) ==>
......@@ -334,7 +334,7 @@ val binary_unfolding = store_thm("binary_unfolding",
val fma_unfolding = store_thm("fma_unfolding",
``!(f1:(real)exp) (f2:(real)exp) (f3:(real)exp) E Gamma (v:real) v1 v2 v3 m1 m2 m3 delta.
(abs delta) <= (mTypeToQ (join3 m1 m2 m3)) /\
(abs delta) <= (mTypeToR (join3 m1 m2 m3)) /\
eval_exp E Gamma f1 v1 m1 /\
eval_exp E Gamma f2 v2 m2 /\
eval_exp E Gamma f3 v3 m3 /\
......
......@@ -641,7 +641,7 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ fs[optionLift_def, normal_or_zero_def, minValue_def,
minExponentPos_def, REAL_LT_INV_EQ]
\\ qexists_tac `0:real`
\\ fs[mTypeToQ_pos, perturb_def, fp64_to_float_float_to_fp64,
\\ fs[mTypeToR_pos, perturb_def, fp64_to_float_float_to_fp64,
zero_to_real])
>- (fs[eval_exp_float_def, optionLift_def]
\\ first_x_assum (qspecl_then [`E1`, `E2`, `E2_real`, `Gamma`, `tMap`, `v1`, `A`, `P`, `fVars`, `dVars`] destruct)
......@@ -786,7 +786,7 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ asm_exists_tac \\ fs[])
\\ qexists_tac ` 0:real`
\\ Cases_on `b`
\\ fs[perturb_def, evalBinop_def, mTypeToQ_pos, join_def])
\\ fs[perturb_def, evalBinop_def, mTypeToR_pos, join_def])
\\ `validFloatValue (float_to_real (fp64_to_float vF1)) M64`
by (drule FPRangeValidator_sound
\\ disch_then
......@@ -862,14 +862,14 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`,
`float_to_real (fp64_to_float vF2)`, `err`]
\\ fs[perturb_def, evalBinop_def]
\\ fs[mTypeToQ_def, join_def])
\\ fs[mTypeToR_def, join_def])
(* result = 0 *)
>- (fs[REAL_LNEG_UNIQ, evalBinop_def]
\\ fs[fp64_add_def, dmode_def, fp64_to_float_float_to_fp64]
\\ fs[float_add_def]
\\ fs[join_def]
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`, `float_to_real (fp64_to_float vF2)`, `0:real`]
\\ fs[perturb_def, mTypeToQ_pos, evalBinop_def]
\\ fs[perturb_def, mTypeToR_pos, evalBinop_def]
\\ fs[validValue_gives_float_value, float_round_with_flags_def]
\\ `2 * abs (0:real) <= ulp (:52 #11)`
by (fs[ulp_def, ULP_def])
......@@ -905,18 +905,18 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`,
`float_to_real (fp64_to_float vF2)`, `err`]
\\ fs[perturb_def, evalBinop_def]
\\ fs[mTypeToQ_def, join_def])
\\ fs[mTypeToR_def, join_def])
>- (fs[evalBinop_def]
\\ qpat_x_assum `float_to_real (fp64_to_float _) = _` MP_TAC
\\ simp[real_sub, REAL_LNEG_UNIQ, evalBinop_def]
\\ fs[fp64_sub_def, dmode_def, fp64_to_float_float_to_fp64]
\\ fs[float_sub_def]
\\ fs[join_def]
\\ fs[perturb_def, mTypeToQ_pos, evalBinop_def]
\\ fs[perturb_def, mTypeToR_pos, evalBinop_def]
\\ fs[validValue_gives_float_value, float_round_with_flags_def]
\\ strip_tac
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`, `float_to_real (fp64_to_float vF2)`, `0:real`]
\\ fs[perturb_def, mTypeToQ_pos, evalBinop_def]
\\ fs[perturb_def, mTypeToR_pos, evalBinop_def]
\\ fs[validValue_gives_float_value, float_round_with_flags_def]
\\ `2 * abs (0:real) <= ulp (:52 #11)`
by (fs[ulp_def, ULP_def])
......@@ -955,7 +955,7 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`,
`float_to_real (fp64_to_float vF2)`, `err`]
\\ fs[perturb_def, evalBinop_def]
\\ fs[mTypeToQ_def, join_def])
\\ fs[mTypeToR_def, join_def])
>- (fs[evalBinop_def, REAL_ENTIRE, fp64_mul_def, float_mul_def,
GSYM float_is_zero_to_real, float_is_zero_def]
THENL [ Cases_on `float_value (fp64_to_float vF1)`,
......@@ -971,7 +971,7 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`,
`float_to_real (fp64_to_float vF2)`, `0:real`]
\\ rveq
\\ fs[GSYM float_is_zero_to_real, float_is_zero_def, join_def, mTypeToQ_pos])
\\ fs[GSYM float_is_zero_to_real, float_is_zero_def, join_def, mTypeToR_pos])
(* Division *)
>- (fs[fp64_div_def, fp64_to_float_float_to_fp64, evalBinop_def]
\\ `normal (evalBinop Div (float_to_real (fp64_to_float vF1))
......@@ -1002,7 +1002,7 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`,
`float_to_real (fp64_to_float vF2)`, `err`]
\\ fs[perturb_def, evalBinop_def]
\\ fs[mTypeToQ_def, join_def])
\\ fs[mTypeToR_def, join_def])
>- (fs[fp64_div_def, dmode_def, fp64_to_float_float_to_fp64,
float_div_def, evalBinop_def]
\\ `float_to_real (fp64_to_float vF1) = 0`
......@@ -1022,7 +1022,7 @@ val eval_exp_gives_IEEE = store_thm ("eval_exp_gives_IEEE",
by (fs[GSYM float_is_zero_to_real, float_is_zero_def])
\\ qexistsl_tac [`M64`, `M64`, `float_to_real (fp64_to_float vF1)`,
`float_to_real (fp64_to_float vF2)`, `0:real`]
\\ fs[perturb_def, join_def, mTypeToQ_pos]))
\\ fs[perturb_def, join_def, mTypeToR_pos]))
>- (rename1 `Fma (toRExp e1) (toRExp e2) (toRExp e3)`
\\ qpat_x_assum `M64 = _` (fn thm => fs [GSYM thm])
\\ `FloverMapTree_find (toRExp e1) tMap = SOME M64 /\
......
......@@ -208,4 +208,5 @@ fun Flover_compute t =
(* Flover_compute_steps terms_to_eval g *)
(* end; *)
end
......@@ -4,45 +4,82 @@
@author: Raphael Monat
@maintainer: Heiko Becker
**)
open miscTheory realTheory realLib sptreeTheory
open preamble
open miscTheory realTheory realLib sptreeTheory;
open RealSimpsTheory;
open preamble;
val _ = new_theory "MachineType";
val _ = temp_overload_on("abs",``real$abs``);
val _ = Datatype `
mType = M0 | M16 | M32 | M64(* | M128 | M256 *)`;
mType = M0 | M16 | M32 | M64(* | M128 | M256 *)
|F num num (*first num is word length, second is fractional bits *)`;
val mTypeToQ_def = Define `
mTypeToQ (m:mType) : real =
val mTypeToR_def = Define `
mTypeToR (m:mType) : real =
case m of
| M0 => 0
| M16 => 1 / (2 pow 11)
| M32 => 1 / (2 pow 24)
| M64 => 1 / (2 pow 53)
| F w f => 1 / (2 pow f)
(* the epsilons below match what is used internally in flover,
although these value do not match the IEEE standard *)
(* | M128 => 1 / (2 pow 105) *)
(* | M256 => 1 / (2 pow 211) *)`;
val meps_def = Define `meps = mTypeToQ`;
val _ = export_rewrites ["mTypeToR_def"];
val mTypeToQ_pos = store_thm("mTypeToQ_pos",
``!e. 0 <= mTypeToQ e``,
Cases_on `e` \\ EVAL_TAC);
(* val meps_def = Define `meps = mTypeToR`; *)
val computeError_def = Define `
computeError v m =
case m of
| M0 => 0
| F w f => mTypeToR m
| _ => abs v * mTypeToR m`;
val mTypeToR_pos = store_thm("mTypeToR_pos",
``!e. 0 <= mTypeToR e``,
Cases_on `e` \\ TRY EVAL_TAC
\\ fs[]);
val computeError_up = store_thm (
"computeError_up",
``!v a b m.
abs v <= maxAbs (a,b) ==>
computeError v m <= computeError (maxAbs (a,b)) m``,
rpt strip_tac \\ Cases_on `m` \\ fs[computeError_def] \\ TRY RealArith.REAL_ASM_ARITH_TAC
\\ irule REAL_LE_RMUL_IMP \\ fs[]
\\ fs[maxAbs_def]
\\ `abs (real$max (abs a) (abs b)) = real$max (abs a) (abs b)`
by (once_rewrite_tac[ABS_REFL]
\\ fs[max_def]
\\ Cases_on `abs a <= abs b`\\ fs[]
\\ irule REAL_ABS_POS)
\\ fs[]);
(**
Check if machine precision m1 is more precise than machine precision m2.
M0 is real-valued evaluation, hence the most precise.
All others are compared by
mTypeToQ m1 <= mTypeToQ m2
mTypeToR m1 <= mTypeToR m2
**)
val isMorePrecise_def = Define `
isMorePrecise (m1:mType) (m2:mType) = (mTypeToQ (m1) <= mTypeToQ (m2))`;
isMorePrecise (m1:mType) (m2:mType) =
case m1, m2 of
| M0, _ => T
| F w1 f1, F w2 f2 => w1 <= w2
| F w f, _ => F
| _, F w f => F
| _, _ => (mTypeToR (m1) <= mTypeToR (m2))`;
val morePrecise_def = Define `
(morePrecise M0 _ = T) /\
(morePrecise (F w1 f1) (F w2 f2) = (w1 <= w2)) /\
(morePrecise (F w f) _ = F) /\
(morePrecise _ (F w f) = F) /\
(morePrecise M16 M16 = T) /\
(morePrecise M32 M32 = T) /\
(morePrecise M32 M16 = T) /\
......@@ -50,13 +87,13 @@ val morePrecise_def = Define `
(morePrecise M64 _ = T) /\
(morePrecise _ _ = F) `;
val morePrecise_antisym = store_thm (
"morePrecise_antisym",
``!m1 m2.
morePrecise m1 m2 /\
morePrecise m2 m1 ==>
m1 = m2``,
rpt strip_tac \\ Cases_on `m1` \\ Cases_on `m2` \\ fs[morePrecise_def]);
(* val morePrecise_antisym = store_thm ( *)
(* "morePrecise_antisym", *)
(* ``!m1 m2. *)
(* morePrecise m1 m2 /\ *)
(* morePrecise m2 m1 ==> *)
(* m1 = m2``, *)
(* rpt strip_tac \\ Cases_on `m1` \\ Cases_on `m2` \\ fs[morePrecise_def]); *)
val morePrecise_trans = store_thm (
"morePrecise_trans",
......@@ -74,13 +111,14 @@ val isMorePrecise_morePrecise = store_thm (
isMorePrecise m1 m2 = morePrecise m1 m2``,
rpt strip_tac
\\ Cases_on `m1` \\ Cases_on `m2`
\\ fs[morePrecise_def, isMorePrecise_def, mTypeToQ_def]);
\\ once_rewrite_tac [morePrecise_def, isMorePrecise_def]
\\ fs[morePrecise_def, isMorePrecise_def, mTypeToR_def]);
val M0_least_precision = store_thm ("M0_least_precision",
``!(m:mType).
isMorePrecise m M0 ==>
m = M0``,
fs [isMorePrecise_def, mTypeToQ_def] \\
fs [isMorePrecise_def, mTypeToR_def] \\
rpt strip_tac \\
Cases_on `m` \\
fs []);
......@@ -109,20 +147,21 @@ val join3_def = Define `
(* fs [join_def, isMorePrecise_def] *)
(* \\ rpt strip_tac *)
(* \\ Cases_on `m1 = M0` \\ Cases_on `m2 = M0` \\ fs[] *)
(* >- (m1 = M0 by (Cases_on `mTypeToQ m1 <= mTypeToQ M0` \\ fs[] *)
(* >- (m1 = M0 by (Cases_on `mTypeToR m1 <= mTypeToR M0` \\ fs[] *)
(* \\ fs [ONCE_REWRITE_RULE [isMorePrecise_def] M0_least_precision] *)
(* \\ Cases_on `m1` \\ fs[mTypeToQ_def] *)
(* \\ Cases_on `m2` \\ fs[mTypeToQ_def] *)
(* \\ Cases_on `m1` \\ fs[mTypeToR_def] *)
(* \\ Cases_on `m2` \\ fs[mTypeToR_def] *)
(* qpat_x_assum `_ = M0` *)
(* (fn thm => fs [thm]) *)
(* >- (Cases_on `m1` \\ fs [mTypeToQ_def]) *)
(* >- (Cases_on `m2` \\ fs [mTypeToQ_def])); *)
(* >- (Cases_on `m1` \\ fs [mTypeToR_def]) *)
(* >- (Cases_on `m2` \\ fs [mTypeToR_def])); *)
val maxExponent_def = Define `
(maxExponent (M0) = 0n) /\
(maxExponent (M16) = 15) /\
(maxExponent (M32) = 127) /\
(maxExponent (M64) = 1023)
(maxExponent (M64) = 1023) /\
(maxExponent (F w f) = f)
(* | M128 => 1023 (** FIXME **) *)
(* | M256 => 1023 *)`;
......@@ -130,7 +169,8 @@ val minExponentPos_def = Define `
(minExponentPos (M0) = 0n) /\
(minExponentPos (M16) = 14) /\
(minExponentPos (M32) = 126) /\
(minExponentPos (M64) = 1022) (*/\ *)
(minExponentPos (M64) = 1022) /\
(minExponentPos (F w f) = f) (*/\ *)
(* (minExponentPos (M128) = 1022) /\ (* FIXME *) *)
(* (minExponentPos (M256) = 1022) *)`;
......@@ -142,12 +182,18 @@ which simplifies to 2^(e_max) for base 2
**)
val maxValue_def = Define `
maxValue (m:mType) = (&(2n ** (maxExponent m))):real`;
maxValue (m:mType) =
case m of
| F w f => &((2n ** (w-1)) - 1) * &(2n ** (maxExponent m))
| _ => (&(2n ** (maxExponent m))):real`;
(** Using the sign bit, the very same number is representable as a negative number,
thus just apply negation here **)
val minValue_def = Define `
minValue (m:mType) = inv (&(2n ** (minExponentPos m)))`;
val minValue_pos_def = Define `
minValue_pos (m:mType) =
case m of
| F w f => 0
| _ => inv (&(2n ** (minExponentPos m)))`;
(** Goldberg - Handbook of Floating-Point Arithmetic: (p.183)
......@@ -159,13 +205,13 @@ val minDenormalValue_def = Define `
val normal_def = Define `
normal (v:real) (m:mType) =
(minValue m <= abs v /\ abs v <= maxValue m)`;
(minValue_pos m <= abs v /\ abs v <= maxValue m)`;
val denormal_def = Define `
denormal (v:real) (m:mType) =
case m of
| M0 => F
| _ => ((abs v) < (minValue m) /\ v <> 0)`;
| _ => ((abs v) < (minValue_pos m) /\ v <> 0)`;
(**
Predicate that is true if and only if the given value v is a valid
......@@ -185,4 +231,9 @@ val validValue_def = Define `
| M0 => T
| _ => abs v <= maxValue m`;
val no_underflow_fixed_point = store_thm (
"no_underflow_fixed_point",
``!v f w. ~ denormal v (F w f)``,
fs[denormal_def, minValue_pos_def, REAL_NOT_LT, REAL_ABS_POS]);
val _ = export_theory();
......@@ -54,6 +54,9 @@ val maxAbs = store_thm ("maxAbs",
\\ simp [REAL_LE_MAX]
\\ REAL_ASM_ARITH_TAC);
val maxAbs_def = Define `
maxAbs iv = max (abs (FST iv)) (abs (SND iv))`;
val Rabs_err_simpl = store_thm("Rabs_err_simpl",
``!(a:real) (b:real). abs (a - (a * (1 + b))) = abs (a * b)``,
rpt strip_tac \\ REAL_ASM_ARITH_TAC);
......
......@@ -90,9 +90,6 @@ multInterval (iv1:interval) (iv2:interval) = absIntvUpd ( * ) iv1 iv2`;
val divideInterval_def = Define `
divideInterval iv1 iv2 = multInterval iv1 (invertInterval iv2)`;
val maxAbs_def = Define `
maxAbs iv = max (abs (FST iv)) (abs (SND iv))`;
val minAbsFun_def = Define `
minAbsFun iv = min (abs (FST iv)) (abs (SND iv))`;
......
......@@ -175,7 +175,7 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound",
>- (qexists_tac `v` \\ fs[]
\\ irule Const_dist' \\ fs[]
\\ qexists_tac `0` \\ fs[perturb_def]
\\ irule mTypeToQ_pos)
\\ irule mTypeToR_pos)
(* Unary operator case *)
>- (first_x_assum (qspecl_then [`A`, `P`, `fVars`, `dVars`, `E`, `Gamma`] destruct)
\\ fs[]
......@@ -190,7 +190,7 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound",
\\ qexists_tac `1 / vR`
\\ conj_tac
>- (irule Unop_inv' \\ fs[] \\ qexistsl_tac [`0`, `vR`]
\\ fs[evalUnop_def, perturb_def, REAL_INV_1OVER, mTypeToQ_pos, IVhi_def, IVlo_def]
\\ fs[evalUnop_def, perturb_def, REAL_INV_1OVER, mTypeToR_pos, IVhi_def, IVlo_def]
\\ CCONTR_TAC \\ fs[] \\ rveq
\\ `0 < 0:real` by (REAL_ASM_ARITH_TAC)
\\ fs[])
......@@ -222,7 +222,7 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound",
\\ conj_tac
>- (irule Binop_dist'
\\ qexistsl_tac [`0:real`, `M0`, `M0`, `vR1`, `vR2`]
\\ fs[join_def, mTypeToQ_pos, perturb_def]
\\ fs[join_def, mTypeToR_pos, perturb_def]
\\ strip_tac \\ rveq \\ fs[IVlo_def, IVhi_def]
\\ CCONTR_TAC \\ fs[] \\ rveq
>- (`0 < 0:real` by (irule REAL_LET_TRANS \\ asm_exists_tac \\ fs[])
......@@ -297,7 +297,7 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound",
\\ conj_tac
>- (irule Fma_dist'
\\ qexistsl_tac [`0:real`, `M0`, `M0`, `M0`, `vR1`, `vR2`, `vR3`]
\\ fs [mTypeToQ_def, perturb_def, evalFma_def, evalBinop_def, join3_def, join_def])
\\ fs [mTypeToR_def, perturb_def, evalFma_def, evalBinop_def, join3_def, join_def])
\\ rename1 `FloverMapTree_find f1 A = SOME (iv_f1, err1)`
\\ rename1 `FloverMapTree_find f2 A = SOME (iv_f2, err2)`
\\ rename1 `FloverMapTree_find f3 A = SOME (iv_f3, err3)`
......
......@@ -125,7 +125,7 @@ val _ = translate const_1_over_2_pow_11_eq;
val _ = translate const_1_over_2_pow_24_eq;
val _ = translate const_1_over_2_pow_53_eq;
val _ = translate (MachineTypeTheory.mTypeToQ_def
val _ = translate (MachineTypeTheory.mTypeToR_def
|> REWRITE_RULE [GSYM const_1_over_2_pow_11_def,
GSYM const_1_over_2_pow_24_def,
GSYM const_1_over_2_pow_53_def]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment