216 plus_float.rep_eq one_float.rep_eq plus_float numeral_float one_float) |
216 plus_float.rep_eq one_float.rep_eq plus_float numeral_float one_float) |
217 done |
217 done |
218 |
218 |
219 lemma transfer_numeral [transfer_rule]: |
219 lemma transfer_numeral [transfer_rule]: |
220 "fun_rel (op =) cr_float (numeral :: _ \<Rightarrow> real) (numeral :: _ \<Rightarrow> float)" |
220 "fun_rel (op =) cr_float (numeral :: _ \<Rightarrow> real) (numeral :: _ \<Rightarrow> float)" |
221 unfolding fun_rel_def cr_float_def by (simp add: real_of_float_def[symmetric]) |
221 unfolding fun_rel_def cr_float_def by simp |
222 |
222 |
223 lemma float_neg_numeral[simp]: "real (neg_numeral x :: float) = neg_numeral x" |
223 lemma float_neg_numeral[simp]: "real (neg_numeral x :: float) = neg_numeral x" |
224 by (simp add: minus_numeral[symmetric] del: minus_numeral) |
224 by (simp add: minus_numeral[symmetric] del: minus_numeral) |
225 |
225 |
226 lemma transfer_neg_numeral [transfer_rule]: |
226 lemma transfer_neg_numeral [transfer_rule]: |
227 "fun_rel (op =) cr_float (neg_numeral :: _ \<Rightarrow> real) (neg_numeral :: _ \<Rightarrow> float)" |
227 "fun_rel (op =) cr_float (neg_numeral :: _ \<Rightarrow> real) (neg_numeral :: _ \<Rightarrow> float)" |
228 unfolding fun_rel_def cr_float_def by (simp add: real_of_float_def[symmetric]) |
228 unfolding fun_rel_def cr_float_def by simp |
229 |
229 |
230 lemma |
230 lemma |
231 shows float_of_numeral[simp]: "numeral k = float_of (numeral k)" |
231 shows float_of_numeral[simp]: "numeral k = float_of (numeral k)" |
232 and float_of_neg_numeral[simp]: "neg_numeral k = float_of (neg_numeral k)" |
232 and float_of_neg_numeral[simp]: "neg_numeral k = float_of (neg_numeral k)" |
233 unfolding real_of_float_eq by simp_all |
233 unfolding real_of_float_eq by simp_all |
413 with `e \<le> exponent f` |
409 with `e \<le> exponent f` |
414 show "m = mantissa f * 2 ^ nat (exponent f - e)" "e = exponent f - nat (exponent f - e)" |
410 show "m = mantissa f * 2 ^ nat (exponent f - e)" "e = exponent f - nat (exponent f - e)" |
415 unfolding real_of_int_inject by auto |
411 unfolding real_of_int_inject by auto |
416 qed |
412 qed |
417 |
413 |
418 lemma compute_zero[code_unfold, code]: "0 = Float 0 0" |
414 lemma compute_float_zero[code_unfold, code]: "0 = Float 0 0" |
419 by transfer simp |
415 by transfer simp |
420 |
416 hide_fact (open) compute_float_zero |
421 lemma compute_one[code_unfold, code]: "1 = Float 1 0" |
417 |
|
418 lemma compute_float_one[code_unfold, code]: "1 = Float 1 0" |
422 by transfer simp |
419 by transfer simp |
|
420 hide_fact (open) compute_float_one |
423 |
421 |
424 definition normfloat :: "float \<Rightarrow> float" where |
422 definition normfloat :: "float \<Rightarrow> float" where |
425 [simp]: "normfloat x = x" |
423 [simp]: "normfloat x = x" |
426 |
424 |
427 lemma compute_normfloat[code]: "normfloat (Float m e) = |
425 lemma compute_normfloat[code]: "normfloat (Float m e) = |
428 (if m mod 2 = 0 \<and> m \<noteq> 0 then normfloat (Float (m div 2) (e + 1)) |
426 (if m mod 2 = 0 \<and> m \<noteq> 0 then normfloat (Float (m div 2) (e + 1)) |
429 else if m = 0 then 0 else Float m e)" |
427 else if m = 0 then 0 else Float m e)" |
430 unfolding normfloat_def |
428 unfolding normfloat_def |
431 by transfer (auto simp add: powr_add zmod_eq_0_iff) |
429 by transfer (auto simp add: powr_add zmod_eq_0_iff) |
|
430 hide_fact (open) compute_normfloat |
432 |
431 |
433 lemma compute_float_numeral[code_abbrev]: "Float (numeral k) 0 = numeral k" |
432 lemma compute_float_numeral[code_abbrev]: "Float (numeral k) 0 = numeral k" |
434 by transfer simp |
433 by transfer simp |
|
434 hide_fact (open) compute_float_numeral |
435 |
435 |
436 lemma compute_float_neg_numeral[code_abbrev]: "Float (neg_numeral k) 0 = neg_numeral k" |
436 lemma compute_float_neg_numeral[code_abbrev]: "Float (neg_numeral k) 0 = neg_numeral k" |
437 by transfer simp |
437 by transfer simp |
|
438 hide_fact (open) compute_float_neg_numeral |
438 |
439 |
439 lemma compute_float_uminus[code]: "- Float m1 e1 = Float (- m1) e1" |
440 lemma compute_float_uminus[code]: "- Float m1 e1 = Float (- m1) e1" |
440 by transfer simp |
441 by transfer simp |
|
442 hide_fact (open) compute_float_uminus |
441 |
443 |
442 lemma compute_float_times[code]: "Float m1 e1 * Float m2 e2 = Float (m1 * m2) (e1 + e2)" |
444 lemma compute_float_times[code]: "Float m1 e1 * Float m2 e2 = Float (m1 * m2) (e1 + e2)" |
443 by transfer (simp add: field_simps powr_add) |
445 by transfer (simp add: field_simps powr_add) |
|
446 hide_fact (open) compute_float_times |
444 |
447 |
445 lemma compute_float_plus[code]: "Float m1 e1 + Float m2 e2 = |
448 lemma compute_float_plus[code]: "Float m1 e1 + Float m2 e2 = |
446 (if e1 \<le> e2 then Float (m1 + m2 * 2^nat (e2 - e1)) e1 |
449 (if e1 \<le> e2 then Float (m1 + m2 * 2^nat (e2 - e1)) e1 |
447 else Float (m2 + m1 * 2^nat (e1 - e2)) e2)" |
450 else Float (m2 + m1 * 2^nat (e1 - e2)) e2)" |
448 by transfer (simp add: field_simps powr_realpow[symmetric] powr_divide2[symmetric]) |
451 by transfer (simp add: field_simps powr_realpow[symmetric] powr_divide2[symmetric]) |
|
452 hide_fact (open) compute_float_plus |
449 |
453 |
450 lemma compute_float_minus[code]: fixes f g::float shows "f - g = f + (-g)" |
454 lemma compute_float_minus[code]: fixes f g::float shows "f - g = f + (-g)" |
451 by simp |
455 by simp |
|
456 hide_fact (open) compute_float_minus |
452 |
457 |
453 lemma compute_float_sgn[code]: "sgn (Float m1 e1) = (if 0 < m1 then 1 else if m1 < 0 then -1 else 0)" |
458 lemma compute_float_sgn[code]: "sgn (Float m1 e1) = (if 0 < m1 then 1 else if m1 < 0 then -1 else 0)" |
454 by transfer (simp add: sgn_times) |
459 by transfer (simp add: sgn_times) |
|
460 hide_fact (open) compute_float_sgn |
455 |
461 |
456 lift_definition is_float_pos :: "float \<Rightarrow> bool" is "op < 0 :: real \<Rightarrow> bool" .. |
462 lift_definition is_float_pos :: "float \<Rightarrow> bool" is "op < 0 :: real \<Rightarrow> bool" .. |
457 |
463 |
458 lemma compute_is_float_pos[code]: "is_float_pos (Float m e) \<longleftrightarrow> 0 < m" |
464 lemma compute_is_float_pos[code]: "is_float_pos (Float m e) \<longleftrightarrow> 0 < m" |
459 by transfer (auto simp add: zero_less_mult_iff not_le[symmetric, of _ 0]) |
465 by transfer (auto simp add: zero_less_mult_iff not_le[symmetric, of _ 0]) |
|
466 hide_fact (open) compute_is_float_pos |
460 |
467 |
461 lemma compute_float_less[code]: "a < b \<longleftrightarrow> is_float_pos (b - a)" |
468 lemma compute_float_less[code]: "a < b \<longleftrightarrow> is_float_pos (b - a)" |
462 by transfer (simp add: field_simps) |
469 by transfer (simp add: field_simps) |
|
470 hide_fact (open) compute_float_less |
463 |
471 |
464 lift_definition is_float_nonneg :: "float \<Rightarrow> bool" is "op \<le> 0 :: real \<Rightarrow> bool" .. |
472 lift_definition is_float_nonneg :: "float \<Rightarrow> bool" is "op \<le> 0 :: real \<Rightarrow> bool" .. |
465 |
473 |
466 lemma compute_is_float_nonneg[code]: "is_float_nonneg (Float m e) \<longleftrightarrow> 0 \<le> m" |
474 lemma compute_is_float_nonneg[code]: "is_float_nonneg (Float m e) \<longleftrightarrow> 0 \<le> m" |
467 by transfer (auto simp add: zero_le_mult_iff not_less[symmetric, of _ 0]) |
475 by transfer (auto simp add: zero_le_mult_iff not_less[symmetric, of _ 0]) |
|
476 hide_fact (open) compute_is_float_nonneg |
468 |
477 |
469 lemma compute_float_le[code]: "a \<le> b \<longleftrightarrow> is_float_nonneg (b - a)" |
478 lemma compute_float_le[code]: "a \<le> b \<longleftrightarrow> is_float_nonneg (b - a)" |
470 by transfer (simp add: field_simps) |
479 by transfer (simp add: field_simps) |
|
480 hide_fact (open) compute_float_le |
471 |
481 |
472 lift_definition is_float_zero :: "float \<Rightarrow> bool" is "op = 0 :: real \<Rightarrow> bool" by simp |
482 lift_definition is_float_zero :: "float \<Rightarrow> bool" is "op = 0 :: real \<Rightarrow> bool" by simp |
473 |
483 |
474 lemma compute_is_float_zero[code]: "is_float_zero (Float m e) \<longleftrightarrow> 0 = m" |
484 lemma compute_is_float_zero[code]: "is_float_zero (Float m e) \<longleftrightarrow> 0 = m" |
475 by transfer (auto simp add: is_float_zero_def) |
485 by transfer (auto simp add: is_float_zero_def) |
|
486 hide_fact (open) compute_is_float_zero |
476 |
487 |
477 lemma compute_float_abs[code]: "abs (Float m e) = Float (abs m) e" |
488 lemma compute_float_abs[code]: "abs (Float m e) = Float (abs m) e" |
478 by transfer (simp add: abs_mult) |
489 by transfer (simp add: abs_mult) |
|
490 hide_fact (open) compute_float_abs |
479 |
491 |
480 lemma compute_float_eq[code]: "equal_class.equal f g = is_float_zero (f - g)" |
492 lemma compute_float_eq[code]: "equal_class.equal f g = is_float_zero (f - g)" |
481 by transfer simp |
493 by transfer simp |
|
494 hide_fact (open) compute_float_eq |
482 |
495 |
483 subsection {* Rounding Real numbers *} |
496 subsection {* Rounding Real numbers *} |
484 |
497 |
485 definition round_down :: "int \<Rightarrow> real \<Rightarrow> real" where |
498 definition round_down :: "int \<Rightarrow> real \<Rightarrow> real" where |
486 "round_down prec x = floor (x * 2 powr prec) * 2 powr -prec" |
499 "round_down prec x = floor (x * 2 powr prec) * 2 powr -prec" |
1206 |
1228 |
1207 lemma compute_float_round_down[code]: |
1229 lemma compute_float_round_down[code]: |
1208 "float_round_down prec (Float m e) = (let d = bitlen (abs m) - int prec in |
1230 "float_round_down prec (Float m e) = (let d = bitlen (abs m) - int prec in |
1209 if 0 < d then let P = 2^nat d ; n = m div P in Float n (e + d) |
1231 if 0 < d then let P = 2^nat d ; n = m div P in Float n (e + d) |
1210 else Float m e)" |
1232 else Float m e)" |
1211 using compute_float_down[of "prec - bitlen \<bar>m\<bar> - e" m e, symmetric] |
1233 using Float.compute_float_down[of "prec - bitlen \<bar>m\<bar> - e" m e, symmetric] |
1212 by transfer (simp add: field_simps abs_mult log_mult bitlen_def cong del: if_weak_cong) |
1234 by transfer (simp add: field_simps abs_mult log_mult bitlen_def cong del: if_weak_cong) |
|
1235 hide_fact (open) compute_float_round_down |
1213 |
1236 |
1214 lemma compute_float_round_up[code]: |
1237 lemma compute_float_round_up[code]: |
1215 "float_round_up prec (Float m e) = (let d = (bitlen (abs m) - int prec) in |
1238 "float_round_up prec (Float m e) = (let d = (bitlen (abs m) - int prec) in |
1216 if 0 < d then let P = 2^nat d ; n = m div P ; r = m mod P |
1239 if 0 < d then let P = 2^nat d ; n = m div P ; r = m mod P |
1217 in Float (n + (if r = 0 then 0 else 1)) (e + d) |
1240 in Float (n + (if r = 0 then 0 else 1)) (e + d) |
1218 else Float m e)" |
1241 else Float m e)" |
1219 using compute_float_up[of "prec - bitlen \<bar>m\<bar> - e" m e, symmetric] |
1242 using Float.compute_float_up[of "prec - bitlen \<bar>m\<bar> - e" m e, symmetric] |
1220 unfolding Let_def |
1243 unfolding Let_def |
1221 by transfer (simp add: field_simps abs_mult log_mult bitlen_def cong del: if_weak_cong) |
1244 by transfer (simp add: field_simps abs_mult log_mult bitlen_def cong del: if_weak_cong) |
|
1245 hide_fact (open) compute_float_round_up |
1222 |
1246 |
1223 lemma Float_le_zero_iff: "Float a b \<le> 0 \<longleftrightarrow> a \<le> 0" |
1247 lemma Float_le_zero_iff: "Float a b \<le> 0 \<longleftrightarrow> a \<le> 0" |
1224 apply (auto simp: zero_float_def mult_le_0_iff) |
1248 apply (auto simp: zero_float_def mult_le_0_iff) |
1225 using powr_gt_zero[of 2 b] by simp |
1249 using powr_gt_zero[of 2 b] by simp |
1226 |
1250 |
1227 (* TODO: how to use as code equation? -> pprt_float?! *) |
1251 lemma real_of_float_pprt[simp]: fixes a::float shows "real (pprt a) = pprt (real a)" |
1228 lemma compute_pprt[code]: "pprt (Float a e) = (if a <= 0 then 0 else (Float a e))" |
|
1229 unfolding pprt_def sup_float_def max_def Float_le_zero_iff .. |
|
1230 |
|
1231 (* TODO: how to use as code equation? *) |
|
1232 lemma compute_nprt[code]: "nprt (Float a e) = (if a <= 0 then (Float a e) else 0)" |
|
1233 unfolding nprt_def inf_float_def min_def Float_le_zero_iff .. |
|
1234 |
|
1235 lemma of_float_pprt[simp]: fixes a::float shows "real (pprt a) = pprt (real a)" |
|
1236 unfolding pprt_def sup_float_def max_def sup_real_def by auto |
1252 unfolding pprt_def sup_float_def max_def sup_real_def by auto |
1237 |
1253 |
1238 lemma of_float_nprt[simp]: fixes a::float shows "real (nprt a) = nprt (real a)" |
1254 lemma real_of_float_nprt[simp]: fixes a::float shows "real (nprt a) = nprt (real a)" |
1239 unfolding nprt_def inf_float_def min_def inf_real_def by auto |
1255 unfolding nprt_def inf_float_def min_def inf_real_def by auto |
1240 |
1256 |
1241 lift_definition int_floor_fl :: "float \<Rightarrow> int" is floor by simp |
1257 lift_definition int_floor_fl :: "float \<Rightarrow> int" is floor by simp |
1242 |
1258 |
1243 lemma compute_int_floor_fl[code]: |
1259 lemma compute_int_floor_fl[code]: |
1244 "int_floor_fl (Float m e) = (if 0 \<le> e then m * 2 ^ nat e else m div (2 ^ (nat (-e))))" |
1260 "int_floor_fl (Float m e) = (if 0 \<le> e then m * 2 ^ nat e else m div (2 ^ (nat (-e))))" |
1245 by transfer (simp add: powr_int int_of_reals floor_divide_eq_div del: real_of_ints) |
1261 by transfer (simp add: powr_int int_of_reals floor_divide_eq_div del: real_of_ints) |
|
1262 hide_fact (open) compute_int_floor_fl |
1246 |
1263 |
1247 lift_definition floor_fl :: "float \<Rightarrow> float" is "\<lambda>x. real (floor x)" by simp |
1264 lift_definition floor_fl :: "float \<Rightarrow> float" is "\<lambda>x. real (floor x)" by simp |
1248 |
1265 |
1249 lemma compute_floor_fl[code]: |
1266 lemma compute_floor_fl[code]: |
1250 "floor_fl (Float m e) = (if 0 \<le> e then Float m e else Float (m div (2 ^ (nat (-e)))) 0)" |
1267 "floor_fl (Float m e) = (if 0 \<le> e then Float m e else Float (m div (2 ^ (nat (-e)))) 0)" |
1251 by transfer (simp add: powr_int int_of_reals floor_divide_eq_div del: real_of_ints) |
1268 by transfer (simp add: powr_int int_of_reals floor_divide_eq_div del: real_of_ints) |
|
1269 hide_fact (open) compute_floor_fl |
1252 |
1270 |
1253 lemma floor_fl: "real (floor_fl x) \<le> real x" by transfer simp |
1271 lemma floor_fl: "real (floor_fl x) \<le> real x" by transfer simp |
1254 |
1272 |
1255 lemma int_floor_fl: "real (int_floor_fl x) \<le> real x" by transfer simp |
1273 lemma int_floor_fl: "real (int_floor_fl x) \<le> real x" by transfer simp |
1256 |
1274 |