src/HOL/Library/Float.thy
changeset 53381 355a4cac5440
parent 53215 5e47c31c6f7c
child 54230 b1d955791529
equal deleted inserted replaced
53380:08f3491c50bf 53381:355a4cac5440
    42 lemma floatI: fixes m e :: int shows "m * 2 powr e = x \<Longrightarrow> x \<in> float"
    42 lemma floatI: fixes m e :: int shows "m * 2 powr e = x \<Longrightarrow> x \<in> float"
    43   by (auto simp: float_def)
    43   by (auto simp: float_def)
    44 
    44 
    45 lemma zero_float[simp]: "0 \<in> float" by (auto simp: float_def)
    45 lemma zero_float[simp]: "0 \<in> float" by (auto simp: float_def)
    46 lemma one_float[simp]: "1 \<in> float" by (intro floatI[of 1 0]) simp
    46 lemma one_float[simp]: "1 \<in> float" by (intro floatI[of 1 0]) simp
    47 lemma numeral_float[simp]: "numeral i \<in> float" by (intro floatI[of "numeral i" 0]) simp  
    47 lemma numeral_float[simp]: "numeral i \<in> float" by (intro floatI[of "numeral i" 0]) simp
    48 lemma neg_numeral_float[simp]: "neg_numeral i \<in> float" by (intro floatI[of "neg_numeral i" 0]) simp
    48 lemma neg_numeral_float[simp]: "neg_numeral i \<in> float" by (intro floatI[of "neg_numeral i" 0]) simp
    49 lemma real_of_int_float[simp]: "real (x :: int) \<in> float" by (intro floatI[of x 0]) simp
    49 lemma real_of_int_float[simp]: "real (x :: int) \<in> float" by (intro floatI[of x 0]) simp
    50 lemma real_of_nat_float[simp]: "real (x :: nat) \<in> float" by (intro floatI[of x 0]) simp
    50 lemma real_of_nat_float[simp]: "real (x :: nat) \<in> float" by (intro floatI[of x 0]) simp
    51 lemma two_powr_int_float[simp]: "2 powr (real (i::int)) \<in> float" by (intro floatI[of 1 i]) simp
    51 lemma two_powr_int_float[simp]: "2 powr (real (i::int)) \<in> float" by (intro floatI[of 1 i]) simp
    52 lemma two_powr_nat_float[simp]: "2 powr (real (i::nat)) \<in> float" by (intro floatI[of 1 i]) simp
    52 lemma two_powr_nat_float[simp]: "2 powr (real (i::nat)) \<in> float" by (intro floatI[of 1 i]) simp
   173 end
   173 end
   174 
   174 
   175 lemma real_of_float_power[simp]: fixes f::float shows "real (f^n) = real f^n"
   175 lemma real_of_float_power[simp]: fixes f::float shows "real (f^n) = real f^n"
   176   by (induct n) simp_all
   176   by (induct n) simp_all
   177 
   177 
   178 lemma fixes x y::float 
   178 lemma fixes x y::float
   179   shows real_of_float_min: "real (min x y) = min (real x) (real y)"
   179   shows real_of_float_min: "real (min x y) = min (real x) (real y)"
   180     and real_of_float_max: "real (max x y) = max (real x) (real y)"
   180     and real_of_float_max: "real (max x y) = max (real x) (real y)"
   181   by (simp_all add: min_def max_def)
   181   by (simp_all add: min_def max_def)
   182 
   182 
   183 instance float :: unbounded_dense_linorder
   183 instance float :: unbounded_dense_linorder
   195     done
   195     done
   196   assume "a < b"
   196   assume "a < b"
   197   then show "\<exists>c. a < c \<and> c < b"
   197   then show "\<exists>c. a < c \<and> c < b"
   198     apply (intro exI[of _ "(a + b) * Float 1 -1"])
   198     apply (intro exI[of _ "(a + b) * Float 1 -1"])
   199     apply transfer
   199     apply transfer
   200     apply (simp add: powr_neg_numeral) 
   200     apply (simp add: powr_neg_numeral)
   201     done
   201     done
   202 qed
   202 qed
   203 
   203 
   204 instantiation float :: lattice_ab_group_add
   204 instantiation float :: lattice_ab_group_add
   205 begin
   205 begin
   220   apply simp
   220   apply simp
   221   apply (simp_all only: numeral_Bit0 numeral_Bit1 real_of_float_eq real_float
   221   apply (simp_all only: numeral_Bit0 numeral_Bit1 real_of_float_eq real_float
   222                   plus_float.rep_eq one_float.rep_eq plus_float numeral_float one_float)
   222                   plus_float.rep_eq one_float.rep_eq plus_float numeral_float one_float)
   223   done
   223   done
   224 
   224 
   225 lemma transfer_numeral [transfer_rule]: 
   225 lemma transfer_numeral [transfer_rule]:
   226   "fun_rel (op =) pcr_float (numeral :: _ \<Rightarrow> real) (numeral :: _ \<Rightarrow> float)"
   226   "fun_rel (op =) pcr_float (numeral :: _ \<Rightarrow> real) (numeral :: _ \<Rightarrow> float)"
   227   unfolding fun_rel_def float.pcr_cr_eq  cr_float_def by simp
   227   unfolding fun_rel_def float.pcr_cr_eq  cr_float_def by simp
   228 
   228 
   229 lemma float_neg_numeral[simp]: "real (neg_numeral x :: float) = neg_numeral x"
   229 lemma float_neg_numeral[simp]: "real (neg_numeral x :: float) = neg_numeral x"
   230   by (simp add: minus_numeral[symmetric] del: minus_numeral)
   230   by (simp add: minus_numeral[symmetric] del: minus_numeral)
   231 
   231 
   232 lemma transfer_neg_numeral [transfer_rule]: 
   232 lemma transfer_neg_numeral [transfer_rule]:
   233   "fun_rel (op =) pcr_float (neg_numeral :: _ \<Rightarrow> real) (neg_numeral :: _ \<Rightarrow> float)"
   233   "fun_rel (op =) pcr_float (neg_numeral :: _ \<Rightarrow> real) (neg_numeral :: _ \<Rightarrow> float)"
   234   unfolding fun_rel_def float.pcr_cr_eq cr_float_def by simp
   234   unfolding fun_rel_def float.pcr_cr_eq cr_float_def by simp
   235 
   235 
   236 lemma
   236 lemma
   237   shows float_of_numeral[simp]: "numeral k = float_of (numeral k)"
   237   shows float_of_numeral[simp]: "numeral k = float_of (numeral k)"
   319 
   319 
   320 definition exponent :: "float \<Rightarrow> int" where
   320 definition exponent :: "float \<Rightarrow> int" where
   321   "exponent f = snd (SOME p::int \<times> int. (f = 0 \<and> fst p = 0 \<and> snd p = 0)
   321   "exponent f = snd (SOME p::int \<times> int. (f = 0 \<and> fst p = 0 \<and> snd p = 0)
   322    \<or> (f \<noteq> 0 \<and> real f = real (fst p) * 2 powr real (snd p) \<and> \<not> 2 dvd fst p))"
   322    \<or> (f \<noteq> 0 \<and> real f = real (fst p) * 2 powr real (snd p) \<and> \<not> 2 dvd fst p))"
   323 
   323 
   324 lemma 
   324 lemma
   325   shows exponent_0[simp]: "exponent (float_of 0) = 0" (is ?E)
   325   shows exponent_0[simp]: "exponent (float_of 0) = 0" (is ?E)
   326     and mantissa_0[simp]: "mantissa (float_of 0) = 0" (is ?M)
   326     and mantissa_0[simp]: "mantissa (float_of 0) = 0" (is ?M)
   327 proof -
   327 proof -
   328   have "\<And>p::int \<times> int. fst p = 0 \<and> snd p = 0 \<longleftrightarrow> p = (0, 0)" by auto
   328   have "\<And>p::int \<times> int. fst p = 0 \<and> snd p = 0 \<longleftrightarrow> p = (0, 0)" by auto
   329   then show ?E ?M
   329   then show ?E ?M
   349 qed simp
   349 qed simp
   350 
   350 
   351 lemma mantissa_noteq_0: "f \<noteq> float_of 0 \<Longrightarrow> mantissa f \<noteq> 0"
   351 lemma mantissa_noteq_0: "f \<noteq> float_of 0 \<Longrightarrow> mantissa f \<noteq> 0"
   352   using mantissa_not_dvd[of f] by auto
   352   using mantissa_not_dvd[of f] by auto
   353 
   353 
   354 lemma 
   354 lemma
   355   fixes m e :: int
   355   fixes m e :: int
   356   defines "f \<equiv> float_of (m * 2 powr e)"
   356   defines "f \<equiv> float_of (m * 2 powr e)"
   357   assumes dvd: "\<not> 2 dvd m"
   357   assumes dvd: "\<not> 2 dvd m"
   358   shows mantissa_float: "mantissa f = m" (is "?M")
   358   shows mantissa_float: "mantissa f = m" (is "?M")
   359     and exponent_float: "m \<noteq> 0 \<Longrightarrow> exponent f = e" (is "_ \<Longrightarrow> ?E")
   359     and exponent_float: "m \<noteq> 0 \<Longrightarrow> exponent f = e" (is "_ \<Longrightarrow> ?E")
   738     using floor_add[of "log 2 b" c] assms
   738     using floor_add[of "log 2 b" c] assms
   739     by (auto simp add: log_mult log_nat_power bitlen_def)
   739     by (auto simp add: log_mult log_nat_power bitlen_def)
   740 qed
   740 qed
   741 
   741 
   742 lemma bitlen_Float:
   742 lemma bitlen_Float:
   743 fixes m e
   743   fixes m e
   744 defines "f \<equiv> Float m e"
   744   defines "f \<equiv> Float m e"
   745 shows "bitlen (\<bar>mantissa f\<bar>) + exponent f = (if m = 0 then 0 else bitlen \<bar>m\<bar> + e)"
   745   shows "bitlen (\<bar>mantissa f\<bar>) + exponent f = (if m = 0 then 0 else bitlen \<bar>m\<bar> + e)"
   746 proof cases
   746 proof (cases "m = 0")
   747   assume "m \<noteq> 0"
   747   case True
       
   748   then show ?thesis by (simp add: f_def bitlen_def Float_def)
       
   749 next
       
   750   case False
   748   hence "f \<noteq> float_of 0"
   751   hence "f \<noteq> float_of 0"
   749     unfolding real_of_float_eq by (simp add: f_def)
   752     unfolding real_of_float_eq by (simp add: f_def)
   750   hence "mantissa f \<noteq> 0"
   753   hence "mantissa f \<noteq> 0"
   751     by (simp add: mantissa_noteq_0)
   754     by (simp add: mantissa_noteq_0)
   752   moreover
   755   moreover
   753   from f_def[THEN denormalize_shift, OF `f \<noteq> float_of 0`] guess i .
   756   obtain i where "m = mantissa f * 2 ^ i" "e = exponent f - int i"
       
   757     by (rule f_def[THEN denormalize_shift, OF `f \<noteq> float_of 0`])
   754   ultimately show ?thesis by (simp add: abs_mult)
   758   ultimately show ?thesis by (simp add: abs_mult)
   755 qed (simp add: f_def bitlen_def Float_def)
   759 qed
   756 
   760 
   757 lemma compute_bitlen[code]:
   761 lemma compute_bitlen[code]:
   758   shows "bitlen x = (if x > 0 then bitlen (x div 2) + 1 else 0)"
   762   shows "bitlen x = (if x > 0 then bitlen (x div 2) + 1 else 0)"
   759 proof -
   763 proof -
   760   { assume "2 \<le> x"
   764   { assume "2 \<le> x"
   863 
   867 
   864 lift_definition lapprox_posrat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> float"
   868 lift_definition lapprox_posrat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> float"
   865   is "\<lambda>prec (x::nat) (y::nat). round_down (rat_precision prec x y) (x / y)" by simp
   869   is "\<lambda>prec (x::nat) (y::nat). round_down (rat_precision prec x y) (x / y)" by simp
   866 
   870 
   867 lemma compute_lapprox_posrat[code]:
   871 lemma compute_lapprox_posrat[code]:
   868   fixes prec x y 
   872   fixes prec x y
   869   shows "lapprox_posrat prec x y = 
   873   shows "lapprox_posrat prec x y =
   870    (let 
   874    (let
   871        l = rat_precision prec x y;
   875        l = rat_precision prec x y;
   872        d = if 0 \<le> l then x * 2^nat l div y else x div 2^nat (- l) div y
   876        d = if 0 \<le> l then x * 2^nat l div y else x div 2^nat (- l) div y
   873     in normfloat (Float d (- l)))"
   877     in normfloat (Float d (- l)))"
   874     unfolding div_mult_twopow_eq normfloat_def
   878     unfolding div_mult_twopow_eq normfloat_def
   875     by transfer
   879     by transfer
   946 
   950 
   947 lemma rapprox_posrat_less1:
   951 lemma rapprox_posrat_less1:
   948   assumes "0 \<le> x" and "0 < y" and "2 * x < y" and "0 < n"
   952   assumes "0 \<le> x" and "0 < y" and "2 * x < y" and "0 < n"
   949   shows "real (rapprox_posrat n x y) < 1"
   953   shows "real (rapprox_posrat n x y) < 1"
   950 proof -
   954 proof -
   951   have powr1: "2 powr real (rat_precision n (int x) (int y)) = 
   955   have powr1: "2 powr real (rat_precision n (int x) (int y)) =
   952     2 ^ nat (rat_precision n (int x) (int y))" using rat_precision_pos[of x y n] assms
   956     2 ^ nat (rat_precision n (int x) (int y))" using rat_precision_pos[of x y n] assms
   953     by (simp add: powr_realpow[symmetric])
   957     by (simp add: powr_realpow[symmetric])
   954   have "x * 2 powr real (rat_precision n (int x) (int y)) / y = (x / y) *
   958   have "x * 2 powr real (rat_precision n (int x) (int y)) / y = (x / y) *
   955      2 powr real (rat_precision n (int x) (int y))" by simp
   959      2 powr real (rat_precision n (int x) (int y))" by simp
   956   also have "... < (1 / 2) * 2 powr real (rat_precision n (int x) (int y))"
   960   also have "... < (1 / 2) * 2 powr real (rat_precision n (int x) (int y))"
   976 lemma compute_lapprox_rat[code]:
   980 lemma compute_lapprox_rat[code]:
   977   "lapprox_rat prec x y =
   981   "lapprox_rat prec x y =
   978     (if y = 0 then 0
   982     (if y = 0 then 0
   979     else if 0 \<le> x then
   983     else if 0 \<le> x then
   980       (if 0 < y then lapprox_posrat prec (nat x) (nat y)
   984       (if 0 < y then lapprox_posrat prec (nat x) (nat y)
   981       else - (rapprox_posrat prec (nat x) (nat (-y)))) 
   985       else - (rapprox_posrat prec (nat x) (nat (-y))))
   982       else (if 0 < y
   986       else (if 0 < y
   983         then - (rapprox_posrat prec (nat (-x)) (nat y))
   987         then - (rapprox_posrat prec (nat (-x)) (nat y))
   984         else lapprox_posrat prec (nat (-x)) (nat (-y))))"
   988         else lapprox_posrat prec (nat (-x)) (nat (-y))))"
   985   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
   989   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
   986 hide_fact (open) compute_lapprox_rat
   990 hide_fact (open) compute_lapprox_rat
   991 lemma compute_rapprox_rat[code]:
   995 lemma compute_rapprox_rat[code]:
   992   "rapprox_rat prec x y =
   996   "rapprox_rat prec x y =
   993     (if y = 0 then 0
   997     (if y = 0 then 0
   994     else if 0 \<le> x then
   998     else if 0 \<le> x then
   995       (if 0 < y then rapprox_posrat prec (nat x) (nat y)
   999       (if 0 < y then rapprox_posrat prec (nat x) (nat y)
   996       else - (lapprox_posrat prec (nat x) (nat (-y)))) 
  1000       else - (lapprox_posrat prec (nat x) (nat (-y))))
   997       else (if 0 < y
  1001       else (if 0 < y
   998         then - (lapprox_posrat prec (nat (-x)) (nat y))
  1002         then - (lapprox_posrat prec (nat (-x)) (nat y))
   999         else rapprox_posrat prec (nat (-x)) (nat (-y))))"
  1003         else rapprox_posrat prec (nat (-x)) (nat (-y))))"
  1000   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
  1004   by transfer (auto simp: round_up_def round_down_def ceiling_def ac_simps)
  1001 hide_fact (open) compute_rapprox_rat
  1005 hide_fact (open) compute_rapprox_rat
  1015     by (simp add: abs_mult log_mult rat_precision_def bitlen_def)
  1019     by (simp add: abs_mult log_mult rat_precision_def bitlen_def)
  1016   have eq1: "real m1 * 2 powr real s1 / (real m2 * 2 powr real s2) = ?m * ?s"
  1020   have eq1: "real m1 * 2 powr real s1 / (real m2 * 2 powr real s2) = ?m * ?s"
  1017     by (simp add: field_simps powr_divide2[symmetric])
  1021     by (simp add: field_simps powr_divide2[symmetric])
  1018 
  1022 
  1019   show ?thesis
  1023   show ?thesis
  1020     using not_0 
  1024     using not_0
  1021     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_down_shift, simp add: field_simps)
  1025     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_down_shift, simp add: field_simps)
  1022 qed (transfer, auto)
  1026 qed (transfer, auto)
  1023 hide_fact (open) compute_float_divl
  1027 hide_fact (open) compute_float_divl
  1024 
  1028 
  1025 lift_definition float_divr :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" is
  1029 lift_definition float_divr :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" is
  1035     by (simp add: abs_mult log_mult rat_precision_def bitlen_def)
  1039     by (simp add: abs_mult log_mult rat_precision_def bitlen_def)
  1036   have eq1: "real m1 * 2 powr real s1 / (real m2 * 2 powr real s2) = ?m * ?s"
  1040   have eq1: "real m1 * 2 powr real s1 / (real m2 * 2 powr real s2) = ?m * ?s"
  1037     by (simp add: field_simps powr_divide2[symmetric])
  1041     by (simp add: field_simps powr_divide2[symmetric])
  1038 
  1042 
  1039   show ?thesis
  1043   show ?thesis
  1040     using not_0 
  1044     using not_0
  1041     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_up_shift, simp add: field_simps)
  1045     by (transfer fixing: m1 s1 m2 s2 prec) (unfold eq1 eq2 round_up_shift, simp add: field_simps)
  1042 qed (transfer, auto)
  1046 qed (transfer, auto)
  1043 hide_fact (open) compute_float_divr
  1047 hide_fact (open) compute_float_divr
  1044 
  1048 
  1045 subsection {* Lemmas needed by Approximate *}
  1049 subsection {* Lemmas needed by Approximate *}
  1102   finally show ?thesis
  1106   finally show ?thesis
  1103     by (simp add: rapprox_rat_def round_up_def)
  1107     by (simp add: rapprox_rat_def round_up_def)
  1104        (simp add: powr_minus inverse_eq_divide)
  1108        (simp add: powr_minus inverse_eq_divide)
  1105 qed
  1109 qed
  1106 
  1110 
  1107 lemma rapprox_rat_nonneg_neg: 
  1111 lemma rapprox_rat_nonneg_neg:
  1108   "0 \<le> x \<Longrightarrow> y < 0 \<Longrightarrow> real (rapprox_rat n x y) \<le> 0"
  1112   "0 \<le> x \<Longrightarrow> y < 0 \<Longrightarrow> real (rapprox_rat n x y) \<le> 0"
  1109   unfolding rapprox_rat_def round_up_def
  1113   unfolding rapprox_rat_def round_up_def
  1110   by (auto simp: field_simps mult_le_0_iff zero_le_mult_iff)
  1114   by (auto simp: field_simps mult_le_0_iff zero_le_mult_iff)
  1111 
  1115 
  1112 lemma rapprox_rat_neg:
  1116 lemma rapprox_rat_neg:
  1155 
  1159 
  1156 lemma float_divl_pos_less1_bound:
  1160 lemma float_divl_pos_less1_bound:
  1157   "0 < real x \<Longrightarrow> real x < 1 \<Longrightarrow> prec \<ge> 1 \<Longrightarrow> 1 \<le> real (float_divl prec 1 x)"
  1161   "0 < real x \<Longrightarrow> real x < 1 \<Longrightarrow> prec \<ge> 1 \<Longrightarrow> 1 \<le> real (float_divl prec 1 x)"
  1158 proof transfer
  1162 proof transfer
  1159   fix prec :: nat and x :: real assume x: "0 < x" "x < 1" "x \<in> float" and prec: "1 \<le> prec"
  1163   fix prec :: nat and x :: real assume x: "0 < x" "x < 1" "x \<in> float" and prec: "1 \<le> prec"
  1160   def p \<equiv> "int prec + \<lfloor>log 2 \<bar>x\<bar>\<rfloor>" 
  1164   def p \<equiv> "int prec + \<lfloor>log 2 \<bar>x\<bar>\<rfloor>"
  1161   show "1 \<le> round_down (int prec + \<lfloor>log 2 \<bar>x\<bar>\<rfloor> - \<lfloor>log 2 \<bar>1\<bar>\<rfloor>) (1 / x) "
  1165   show "1 \<le> round_down (int prec + \<lfloor>log 2 \<bar>x\<bar>\<rfloor> - \<lfloor>log 2 \<bar>1\<bar>\<rfloor>) (1 / x) "
  1162   proof cases
  1166   proof cases
  1163     assume nonneg: "0 \<le> p"
  1167     assume nonneg: "0 \<le> p"
  1164     hence "2 powr real (p) = floor (real ((2::int) ^ nat p)) * floor (1::real)"
  1168     hence "2 powr real (p) = floor (real ((2::int) ^ nat p)) * floor (1::real)"
  1165       by (simp add: powr_int del: real_of_int_power) simp
  1169       by (simp add: powr_int del: real_of_int_power) simp
  1277 lemma floor_fl: "real (floor_fl x) \<le> real x" by transfer simp
  1281 lemma floor_fl: "real (floor_fl x) \<le> real x" by transfer simp
  1278 
  1282 
  1279 lemma int_floor_fl: "real (int_floor_fl x) \<le> real x" by transfer simp
  1283 lemma int_floor_fl: "real (int_floor_fl x) \<le> real x" by transfer simp
  1280 
  1284 
  1281 lemma floor_pos_exp: "exponent (floor_fl x) \<ge> 0"
  1285 lemma floor_pos_exp: "exponent (floor_fl x) \<ge> 0"
  1282 proof cases
  1286 proof (cases "floor_fl x = float_of 0")
  1283   assume nzero: "floor_fl x \<noteq> float_of 0"
  1287   case True
  1284   have "floor_fl x = Float \<lfloor>real x\<rfloor> 0" by transfer simp
  1288   then show ?thesis by (simp add: floor_fl_def)
  1285   from denormalize_shift[OF this[THEN eq_reflection] nzero] guess i . note i = this
  1289 next
  1286   thus ?thesis by simp
  1290   case False
  1287 qed (simp add: floor_fl_def)
  1291   have eq: "floor_fl x = Float \<lfloor>real x\<rfloor> 0" by transfer simp
       
  1292   obtain i where "\<lfloor>real x\<rfloor> = mantissa (floor_fl x) * 2 ^ i" "0 = exponent (floor_fl x) - int i"
       
  1293     by (rule denormalize_shift[OF eq[THEN eq_reflection] False])
       
  1294   then show ?thesis by simp
       
  1295 qed
  1288 
  1296 
  1289 end
  1297 end
  1290 
  1298