src/HOL/Library/Float.thy
changeset 47621 4cf6011fb884
parent 47615 341fd902ef1c
child 47780 3357688660ff
equal deleted inserted replaced
47620:148d0b3db78d 47621:4cf6011fb884
   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
   363     using mantissa_not_dvd[OF f_not_0] dvd
   363     using mantissa_not_dvd[OF f_not_0] dvd
   364     by (auto simp: mult_powr_eq_mult_powr_iff)
   364     by (auto simp: mult_powr_eq_mult_powr_iff)
   365 qed
   365 qed
   366 
   366 
   367 subsection {* Compute arithmetic operations *}
   367 subsection {* Compute arithmetic operations *}
   368 
       
   369 lemma real_of_float_Float[code]: "real_of_float (Float m e) =
       
   370   (if e \<ge> 0 then m * 2 ^ nat e else m * inverse (2 ^ nat (- e)))"
       
   371 by (auto simp add: powr_realpow[symmetric] powr_minus real_of_float_def[symmetric])
       
   372 
   368 
   373 lemma Float_mantissa_exponent: "Float (mantissa f) (exponent f) = f"
   369 lemma Float_mantissa_exponent: "Float (mantissa f) (exponent f) = f"
   374   unfolding real_of_float_eq mantissa_exponent[of f] by simp
   370   unfolding real_of_float_eq mantissa_exponent[of f] by simp
   375 
   371 
   376 lemma Float_cases[case_names Float, cases type: float]:
   372 lemma Float_cases[case_names Float, cases type: float]:
   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"
   579              simp add: ac_simps powr_add[symmetric] r powr_realpow)
   592              simp add: ac_simps powr_add[symmetric] r powr_realpow)
   580   with `\<not> p + e < 0` show ?thesis
   593   with `\<not> p + e < 0` show ?thesis
   581     by transfer
   594     by transfer
   582        (auto simp add: round_down_def field_simps powr_add powr_minus inverse_eq_divide)
   595        (auto simp add: round_down_def field_simps powr_add powr_minus inverse_eq_divide)
   583 qed
   596 qed
       
   597 hide_fact (open) compute_float_down
   584 
   598 
   585 lemma ceil_divide_floor_conv:
   599 lemma ceil_divide_floor_conv:
   586 assumes "b \<noteq> 0"
   600 assumes "b \<noteq> 0"
   587 shows "\<lceil>real a / real b\<rceil> = (if b dvd a then a div b else \<lfloor>real a / real b\<rfloor> + 1)"
   601 shows "\<lceil>real a / real b\<rceil> = (if b dvd a then a div b else \<lfloor>real a / real b\<rfloor> + 1)"
   588 proof cases
   602 proof cases
   641       intro: exI[where x="m*2^nat (e+p)"])
   655       intro: exI[where x="m*2^nat (e+p)"])
   642   then show ?thesis using `\<not> p + e < 0`
   656   then show ?thesis using `\<not> p + e < 0`
   643     by transfer
   657     by transfer
   644        (simp add: round_up_def floor_divide_eq_div field_simps powr_add powr_minus inverse_eq_divide)
   658        (simp add: round_up_def floor_divide_eq_div field_simps powr_add powr_minus inverse_eq_divide)
   645 qed
   659 qed
       
   660 hide_fact (open) compute_float_up
   646 
   661 
   647 lemmas real_of_ints =
   662 lemmas real_of_ints =
   648   real_of_int_zero
   663   real_of_int_zero
   649   real_of_one
   664   real_of_one
   650   real_of_int_add
   665   real_of_int_add
   775     then have "\<lfloor>log 2 (real x)\<rfloor> = 0" by simp }
   790     then have "\<lfloor>log 2 (real x)\<rfloor> = 0" by simp }
   776   ultimately show ?thesis
   791   ultimately show ?thesis
   777     unfolding bitlen_def
   792     unfolding bitlen_def
   778     by (auto simp: pos_imp_zdiv_pos_iff not_le)
   793     by (auto simp: pos_imp_zdiv_pos_iff not_le)
   779 qed
   794 qed
       
   795 hide_fact (open) compute_bitlen
   780 
   796 
   781 lemma float_gt1_scale: assumes "1 \<le> Float m e"
   797 lemma float_gt1_scale: assumes "1 \<le> Float m e"
   782   shows "0 \<le> e + (bitlen m - 1)"
   798   shows "0 \<le> e + (bitlen m - 1)"
   783 proof -
   799 proof -
   784   have "0 < Float m e" using assms by auto
   800   have "0 < Float m e" using assms by auto
   851     in normfloat (Float d (- l)))"
   867     in normfloat (Float d (- l)))"
   852     unfolding div_mult_twopow_eq normfloat_def
   868     unfolding div_mult_twopow_eq normfloat_def
   853     by transfer
   869     by transfer
   854        (simp add: round_down_def powr_int real_div_nat_eq_floor_of_divide field_simps Let_def
   870        (simp add: round_down_def powr_int real_div_nat_eq_floor_of_divide field_simps Let_def
   855              del: two_powr_minus_int_float)
   871              del: two_powr_minus_int_float)
       
   872 hide_fact (open) compute_lapprox_posrat
   856 
   873 
   857 lift_definition rapprox_posrat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> float"
   874 lift_definition rapprox_posrat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> float"
   858   is "\<lambda>prec (x::nat) (y::nat). round_up (rat_precision prec x y) (x / y)" by simp
   875   is "\<lambda>prec (x::nat) (y::nat). round_up (rat_precision prec x y) (x / y)" by simp
   859 
   876 
   860 (* TODO: optimize using zmod_zmult2_eq, pdivmod ? *)
   877 (* TODO: optimize using zmod_zmult2_eq, pdivmod ? *)
   898         l_def[symmetric, THEN meta_eq_to_obj_eq]
   915         l_def[symmetric, THEN meta_eq_to_obj_eq]
   899       by transfer
   916       by transfer
   900          (simp add: round_up_def ceil_divide_floor_conv floor_divide_eq_div[symmetric] dvd_eq_mod_eq_0)
   917          (simp add: round_up_def ceil_divide_floor_conv floor_divide_eq_div[symmetric] dvd_eq_mod_eq_0)
   901   qed
   918   qed
   902 qed
   919 qed
       
   920 hide_fact (open) compute_rapprox_posrat
   903 
   921 
   904 lemma rat_precision_pos:
   922 lemma rat_precision_pos:
   905   assumes "0 \<le> x" and "0 < y" and "2 * x < y" and "0 < n"
   923   assumes "0 \<le> x" and "0 < y" and "2 * x < y" and "0 < n"
   906   shows "rat_precision n (int x) (int y) > 0"
   924   shows "rat_precision n (int x) (int y) > 0"
   907 proof -
   925 proof -
   957       else - (rapprox_posrat prec (nat x) (nat (-y)))) 
   975       else - (rapprox_posrat prec (nat x) (nat (-y)))) 
   958       else (if 0 < y
   976       else (if 0 < y
   959         then - (rapprox_posrat prec (nat (-x)) (nat y))
   977         then - (rapprox_posrat prec (nat (-x)) (nat y))
   960         else lapprox_posrat prec (nat (-x)) (nat (-y))))"
   978         else lapprox_posrat prec (nat (-x)) (nat (-y))))"
   961   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
   979   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
       
   980 hide_fact (open) compute_lapprox_rat
   962 
   981 
   963 lift_definition rapprox_rat :: "nat \<Rightarrow> int \<Rightarrow> int \<Rightarrow> float" is
   982 lift_definition rapprox_rat :: "nat \<Rightarrow> int \<Rightarrow> int \<Rightarrow> float" is
   964   "\<lambda>prec (x::int) (y::int). round_up (rat_precision prec \<bar>x\<bar> \<bar>y\<bar>) (x / y)" by simp
   983   "\<lambda>prec (x::int) (y::int). round_up (rat_precision prec \<bar>x\<bar> \<bar>y\<bar>) (x / y)" by simp
   965 
   984 
   966 lemma compute_rapprox_rat[code]:
   985 lemma compute_rapprox_rat[code]:
   971       else - (lapprox_posrat prec (nat x) (nat (-y)))) 
   990       else - (lapprox_posrat prec (nat x) (nat (-y)))) 
   972       else (if 0 < y
   991       else (if 0 < y
   973         then - (lapprox_posrat prec (nat (-x)) (nat y))
   992         then - (lapprox_posrat prec (nat (-x)) (nat y))
   974         else rapprox_posrat prec (nat (-x)) (nat (-y))))"
   993         else rapprox_posrat prec (nat (-x)) (nat (-y))))"
   975   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
   994   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
       
   995 hide_fact (open) compute_rapprox_rat
   976 
   996 
   977 subsection {* Division *}
   997 subsection {* Division *}
   978 
   998 
   979 lift_definition float_divl :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" is
   999 lift_definition float_divl :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" is
   980   "\<lambda>(prec::nat) a b. round_down (prec + \<lfloor> log 2 \<bar>b\<bar> \<rfloor> - \<lfloor> log 2 \<bar>a\<bar> \<rfloor>) (a / b)" by simp
  1000   "\<lambda>(prec::nat) a b. round_down (prec + \<lfloor> log 2 \<bar>b\<bar> \<rfloor> - \<lfloor> log 2 \<bar>a\<bar> \<rfloor>) (a / b)" by simp
   992 
  1012 
   993   show ?thesis
  1013   show ?thesis
   994     using not_0 
  1014     using not_0 
   995     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_down_shift, simp add: field_simps)
  1015     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_down_shift, simp add: field_simps)
   996 qed (transfer, auto)
  1016 qed (transfer, auto)
       
  1017 hide_fact (open) compute_float_divl
   997 
  1018 
   998 lift_definition float_divr :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" is
  1019 lift_definition float_divr :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" is
   999   "\<lambda>(prec::nat) a b. round_up (prec + \<lfloor> log 2 \<bar>b\<bar> \<rfloor> - \<lfloor> log 2 \<bar>a\<bar> \<rfloor>) (a / b)" by simp
  1020   "\<lambda>(prec::nat) a b. round_up (prec + \<lfloor> log 2 \<bar>b\<bar> \<rfloor> - \<lfloor> log 2 \<bar>a\<bar> \<rfloor>) (a / b)" by simp
  1000 
  1021 
  1001 lemma compute_float_divr[code]:
  1022 lemma compute_float_divr[code]:
  1011 
  1032 
  1012   show ?thesis
  1033   show ?thesis
  1013     using not_0 
  1034     using not_0 
  1014     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_up_shift, simp add: field_simps)
  1035     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_up_shift, simp add: field_simps)
  1015 qed (transfer, auto)
  1036 qed (transfer, auto)
       
  1037 hide_fact (open) compute_float_divr
  1016 
  1038 
  1017 subsection {* Lemmas needed by Approximate *}
  1039 subsection {* Lemmas needed by Approximate *}
  1018 
  1040 
  1019 lemma Float_num[simp]: shows
  1041 lemma Float_num[simp]: shows
  1020    "real (Float 1 0) = 1" and "real (Float 1 1) = 2" and "real (Float 1 2) = 4" and
  1042    "real (Float 1 0) = 1" and "real (Float 1 1) = 2" and "real (Float 1 2) = 4" and
  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