src/HOL/Library/Float.thy
changeset 47444 8c4c5c8dcf7a
parent 46899 9f113cdf3d66
child 47537 e9aa6d151329
equal deleted inserted replaced
47443:3074685ab7ed 47444:8c4c5c8dcf7a
     7 
     7 
     8 theory Float
     8 theory Float
     9 imports Complex_Main Lattice_Algebras
     9 imports Complex_Main Lattice_Algebras
    10 begin
    10 begin
    11 
    11 
    12 definition
    12 definition pow2 :: "int \<Rightarrow> real" where
    13   pow2 :: "int \<Rightarrow> real" where
       
    14   [simp]: "pow2 a = (if (0 <= a) then (2^(nat a)) else (inverse (2^(nat (-a)))))"
    13   [simp]: "pow2 a = (if (0 <= a) then (2^(nat a)) else (inverse (2^(nat (-a)))))"
    15 
    14 
    16 datatype float = Float int int
    15 datatype float = Float int int
    17 
    16 
    18 primrec of_float :: "float \<Rightarrow> real" where
    17 primrec of_float :: "float \<Rightarrow> real" where
    28   "mantissa (Float a b) = a"
    27   "mantissa (Float a b) = a"
    29 
    28 
    30 primrec scale :: "float \<Rightarrow> int" where
    29 primrec scale :: "float \<Rightarrow> int" where
    31   "scale (Float a b) = b"
    30   "scale (Float a b) = b"
    32 
    31 
    33 instantiation float :: zero begin
    32 instantiation float :: zero
       
    33 begin
    34 definition zero_float where "0 = Float 0 0"
    34 definition zero_float where "0 = Float 0 0"
    35 instance ..
    35 instance ..
    36 end
    36 end
    37 
    37 
    38 instantiation float :: one begin
    38 instantiation float :: one
       
    39 begin
    39 definition one_float where "1 = Float 1 0"
    40 definition one_float where "1 = Float 1 0"
    40 instance ..
    41 instance ..
    41 end
    42 end
    42 
    43 
    43 instantiation float :: number begin
    44 instantiation float :: number
       
    45 begin
    44 definition number_of_float where "number_of n = Float n 0"
    46 definition number_of_float where "number_of n = Float n 0"
    45 instance ..
    47 instance ..
    46 end
    48 end
    47 
    49 
    48 lemma number_of_float_Float:
    50 lemma number_of_float_Float:
   122 
   124 
   123 lemma pow2_neq_zero[simp]: "pow2 x \<noteq> 0"
   125 lemma pow2_neq_zero[simp]: "pow2 x \<noteq> 0"
   124   by (auto simp add: pow2_def)
   126   by (auto simp add: pow2_def)
   125 
   127 
   126 lemma pow2_int: "pow2 (int c) = 2^c"
   128 lemma pow2_int: "pow2 (int c) = 2^c"
   127 by (simp add: pow2_def)
   129   by (simp add: pow2_def)
   128 
   130 
   129 lemma zero_less_pow2[simp]:
   131 lemma zero_less_pow2[simp]: "0 < pow2 x"
   130   "0 < pow2 x"
       
   131   by (simp add: pow2_powr)
   132   by (simp add: pow2_powr)
   132 
   133 
   133 lemma normfloat_imp_odd_or_zero: "normfloat f = Float a b \<Longrightarrow> odd a \<or> (a = 0 \<and> b = 0)"
   134 lemma normfloat_imp_odd_or_zero:
       
   135   "normfloat f = Float a b \<Longrightarrow> odd a \<or> (a = 0 \<and> b = 0)"
   134 proof (induct f rule: normfloat.induct)
   136 proof (induct f rule: normfloat.induct)
   135   case (1 u v)
   137   case (1 u v)
   136   from 1 have ab: "normfloat (Float u v) = Float a b" by auto
   138   from 1 have ab: "normfloat (Float u v) = Float a b" by auto
   137   {
   139   {
   138     assume eu: "even u"
   140     assume eu: "even u"
   167     done
   169     done
   168 qed
   170 qed
   169 
   171 
   170 lemma float_eq_odd_helper: 
   172 lemma float_eq_odd_helper: 
   171   assumes odd: "odd a'"
   173   assumes odd: "odd a'"
   172   and floateq: "real (Float a b) = real (Float a' b')"
   174     and floateq: "real (Float a b) = real (Float a' b')"
   173   shows "b \<le> b'"
   175   shows "b \<le> b'"
   174 proof - 
   176 proof - 
   175   from odd have "a' \<noteq> 0" by auto
   177   from odd have "a' \<noteq> 0" by auto
   176   with floateq have a': "real a' = real a * pow2 (b - b')"
   178   with floateq have a': "real a' = real a * pow2 (b - b')"
   177     by (simp add: pow2_diff field_simps)
   179     by (simp add: pow2_diff field_simps)
   189   then show ?thesis by arith
   191   then show ?thesis by arith
   190 qed
   192 qed
   191 
   193 
   192 lemma float_eq_odd: 
   194 lemma float_eq_odd: 
   193   assumes odd1: "odd a"
   195   assumes odd1: "odd a"
   194   and odd2: "odd a'"
   196     and odd2: "odd a'"
   195   and floateq: "real (Float a b) = real (Float a' b')"
   197     and floateq: "real (Float a b) = real (Float a' b')"
   196   shows "a = a' \<and> b = b'"
   198   shows "a = a' \<and> b = b'"
   197 proof -
   199 proof -
   198   from 
   200   from 
   199      float_eq_odd_helper[OF odd2 floateq] 
   201      float_eq_odd_helper[OF odd2 floateq] 
   200      float_eq_odd_helper[OF odd1 floateq[symmetric]]
   202      float_eq_odd_helper[OF odd1 floateq[symmetric]]
   214     by (simp add: normf normg)
   216     by (simp add: normf normg)
   215   have ab: "odd a \<or> (a = 0 \<and> b = 0)" by (rule normfloat_imp_odd_or_zero[OF normf])
   217   have ab: "odd a \<or> (a = 0 \<and> b = 0)" by (rule normfloat_imp_odd_or_zero[OF normf])
   216   have ab': "odd a' \<or> (a' = 0 \<and> b' = 0)" by (rule normfloat_imp_odd_or_zero[OF normg])
   218   have ab': "odd a' \<or> (a' = 0 \<and> b' = 0)" by (rule normfloat_imp_odd_or_zero[OF normg])
   217   {
   219   {
   218     assume odd: "odd a"
   220     assume odd: "odd a"
   219     then have "a \<noteq> 0" by (simp add: even_def, arith)
   221     then have "a \<noteq> 0" by (simp add: even_def) arith
   220     with float_eq have "a' \<noteq> 0" by auto
   222     with float_eq have "a' \<noteq> 0" by auto
   221     with ab' have "odd a'" by simp
   223     with ab' have "odd a'" by simp
   222     from odd this float_eq have "a = a' \<and> b = b'" by (rule float_eq_odd)
   224     from odd this float_eq have "a = a' \<and> b = b'" by (rule float_eq_odd)
   223   }
   225   }
   224   note odd_case = this
   226   note odd_case = this
   234     apply (case_tac "even a")
   236     apply (case_tac "even a")
   235     apply auto
   237     apply auto
   236     done
   238     done
   237 qed
   239 qed
   238 
   240 
   239 instantiation float :: plus begin
   241 instantiation float :: plus
       
   242 begin
   240 fun plus_float where
   243 fun plus_float where
   241 [simp del]: "(Float a_m a_e) + (Float b_m b_e) = 
   244 [simp del]: "(Float a_m a_e) + (Float b_m b_e) = 
   242      (if a_e \<le> b_e then Float (a_m + b_m * 2^(nat(b_e - a_e))) a_e 
   245      (if a_e \<le> b_e then Float (a_m + b_m * 2^(nat(b_e - a_e))) a_e 
   243                    else Float (a_m * 2^(nat (a_e - b_e)) + b_m) b_e)"
   246                    else Float (a_m * 2^(nat (a_e - b_e)) + b_m) b_e)"
   244 instance ..
   247 instance ..
   245 end
   248 end
   246 
   249 
   247 instantiation float :: uminus begin
   250 instantiation float :: uminus
       
   251 begin
   248 primrec uminus_float where [simp del]: "uminus_float (Float m e) = Float (-m) e"
   252 primrec uminus_float where [simp del]: "uminus_float (Float m e) = Float (-m) e"
   249 instance ..
   253 instance ..
   250 end
   254 end
   251 
   255 
   252 instantiation float :: minus begin
   256 instantiation float :: minus
   253 definition minus_float where [simp del]: "(z::float) - w = z + (- w)"
   257 begin
       
   258 definition minus_float where "(z::float) - w = z + (- w)"
   254 instance ..
   259 instance ..
   255 end
   260 end
   256 
   261 
   257 instantiation float :: times begin
   262 instantiation float :: times
       
   263 begin
   258 fun times_float where [simp del]: "(Float a_m a_e) * (Float b_m b_e) = Float (a_m * b_m) (a_e + b_e)"
   264 fun times_float where [simp del]: "(Float a_m a_e) * (Float b_m b_e) = Float (a_m * b_m) (a_e + b_e)"
   259 instance ..
   265 instance ..
   260 end
   266 end
   261 
   267 
   262 primrec float_pprt :: "float \<Rightarrow> float" where
   268 primrec float_pprt :: "float \<Rightarrow> float" where
   263   "float_pprt (Float a e) = (if 0 <= a then (Float a e) else 0)"
   269   "float_pprt (Float a e) = (if 0 <= a then (Float a e) else 0)"
   264 
   270 
   265 primrec float_nprt :: "float \<Rightarrow> float" where
   271 primrec float_nprt :: "float \<Rightarrow> float" where
   266   "float_nprt (Float a e) = (if 0 <= a then 0 else (Float a e))" 
   272   "float_nprt (Float a e) = (if 0 <= a then 0 else (Float a e))" 
   267 
   273 
   268 instantiation float :: ord begin
   274 instantiation float :: ord
       
   275 begin
   269 definition le_float_def: "z \<le> (w :: float) \<equiv> real z \<le> real w"
   276 definition le_float_def: "z \<le> (w :: float) \<equiv> real z \<le> real w"
   270 definition less_float_def: "z < (w :: float) \<equiv> real z < real w"
   277 definition less_float_def: "z < (w :: float) \<equiv> real z < real w"
   271 instance ..
   278 instance ..
   272 end
   279 end
   273 
   280 
   274 lemma real_of_float_add[simp]: "real (a + b) = real a + real (b :: float)"
   281 lemma real_of_float_add[simp]: "real (a + b) = real a + real (b :: float)"
   275   by (cases a, cases b) (simp add: algebra_simps plus_float.simps, 
   282   by (cases a, cases b) (simp add: algebra_simps plus_float.simps, 
   276       auto simp add: pow2_int[symmetric] pow2_add[symmetric])
   283       auto simp add: pow2_int[symmetric] pow2_add[symmetric])
   277 
   284 
   278 lemma real_of_float_minus[simp]: "real (- a) = - real (a :: float)"
   285 lemma real_of_float_minus[simp]: "real (- a) = - real (a :: float)"
   279   by (cases a) (simp add: uminus_float.simps)
   286   by (cases a) simp
   280 
   287 
   281 lemma real_of_float_sub[simp]: "real (a - b) = real a - real (b :: float)"
   288 lemma real_of_float_sub[simp]: "real (a - b) = real a - real (b :: float)"
   282   by (cases a, cases b) (simp add: minus_float_def)
   289   by (cases a, cases b) (simp add: minus_float_def)
   283 
   290 
   284 lemma real_of_float_mult[simp]: "real (a*b) = real a * real (b :: float)"
   291 lemma real_of_float_mult[simp]: "real (a*b) = real a * real (b :: float)"
   285   by (cases a, cases b) (simp add: times_float.simps pow2_add)
   292   by (cases a, cases b) (simp add: times_float.simps pow2_add)
   286 
   293 
   287 lemma real_of_float_0[simp]: "real (0 :: float) = 0"
   294 lemma real_of_float_0[simp]: "real (0 :: float) = 0"
   288   by (auto simp add: zero_float_def float_zero)
   295   by (auto simp add: zero_float_def)
   289 
   296 
   290 lemma real_of_float_1[simp]: "real (1 :: float) = 1"
   297 lemma real_of_float_1[simp]: "real (1 :: float) = 1"
   291   by (auto simp add: one_float_def)
   298   by (auto simp add: one_float_def)
   292 
   299 
   293 lemma zero_le_float:
   300 lemma zero_le_float:
  1159       unfolding Float round_down.simps Let_def if_not_P[OF False] .. 
  1166       unfolding Float round_down.simps Let_def if_not_P[OF False] .. 
  1160   qed
  1167   qed
  1161 qed
  1168 qed
  1162 
  1169 
  1163 definition lb_mult :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1170 definition lb_mult :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1164 "lb_mult prec x y = (case normfloat (x * y) of Float m e \<Rightarrow> let
  1171   "lb_mult prec x y =
  1165     l = bitlen m - int prec
  1172     (case normfloat (x * y) of Float m e \<Rightarrow>
  1166   in if l > 0 then Float (m div (2^nat l)) (e + l)
  1173       let
  1167               else Float m e)"
  1174         l = bitlen m - int prec
       
  1175       in if l > 0 then Float (m div (2^nat l)) (e + l)
       
  1176                   else Float m e)"
  1168 
  1177 
  1169 definition ub_mult :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1178 definition ub_mult :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1170 "ub_mult prec x y = (case normfloat (x * y) of Float m e \<Rightarrow> let
  1179   "ub_mult prec x y =
  1171     l = bitlen m - int prec
  1180     (case normfloat (x * y) of Float m e \<Rightarrow>
  1172   in if l > 0 then Float (m div (2^nat l) + 1) (e + l)
  1181       let
  1173               else Float m e)"
  1182         l = bitlen m - int prec
       
  1183       in if l > 0 then Float (m div (2^nat l) + 1) (e + l)
       
  1184                   else Float m e)"
  1174 
  1185 
  1175 lemma lb_mult: "real (lb_mult prec x y) \<le> real (x * y)"
  1186 lemma lb_mult: "real (lb_mult prec x y) \<le> real (x * y)"
  1176 proof (cases "normfloat (x * y)")
  1187 proof (cases "normfloat (x * y)")
  1177   case (Float m e)
  1188   case (Float m e)
  1178   hence "odd m \<or> (m = 0 \<and> e = 0)" by (rule normfloat_imp_odd_or_zero)
  1189   hence "odd m \<or> (m = 0 \<and> e = 0)" by (rule normfloat_imp_odd_or_zero)
  1223 qed
  1234 qed
  1224 
  1235 
  1225 primrec float_abs :: "float \<Rightarrow> float" where
  1236 primrec float_abs :: "float \<Rightarrow> float" where
  1226   "float_abs (Float m e) = Float \<bar>m\<bar> e"
  1237   "float_abs (Float m e) = Float \<bar>m\<bar> e"
  1227 
  1238 
  1228 instantiation float :: abs begin
  1239 instantiation float :: abs
       
  1240 begin
  1229 definition abs_float_def: "\<bar>x\<bar> = float_abs x"
  1241 definition abs_float_def: "\<bar>x\<bar> = float_abs x"
  1230 instance ..
  1242 instance ..
  1231 end
  1243 end
  1232 
  1244 
  1233 lemma real_of_float_abs: "real \<bar>x :: float\<bar> = \<bar>real x\<bar>" 
  1245 lemma real_of_float_abs: "real \<bar>x :: float\<bar> = \<bar>real x\<bar>" 
  1288 qed
  1300 qed
  1289 
  1301 
  1290 declare ceiling_fl.simps[simp del]
  1302 declare ceiling_fl.simps[simp del]
  1291 
  1303 
  1292 definition lb_mod :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1304 definition lb_mod :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1293 "lb_mod prec x ub lb = x - ceiling_fl (float_divr prec x lb) * ub"
  1305   "lb_mod prec x ub lb = x - ceiling_fl (float_divr prec x lb) * ub"
  1294 
  1306 
  1295 definition ub_mod :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1307 definition ub_mod :: "nat \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float \<Rightarrow> float" where
  1296 "ub_mod prec x ub lb = x - floor_fl (float_divl prec x ub) * lb"
  1308   "ub_mod prec x ub lb = x - floor_fl (float_divl prec x ub) * lb"
  1297 
  1309 
  1298 lemma lb_mod: fixes k :: int assumes "0 \<le> real x" and "real k * y \<le> real x" (is "?k * y \<le> ?x")
  1310 lemma lb_mod: fixes k :: int assumes "0 \<le> real x" and "real k * y \<le> real x" (is "?k * y \<le> ?x")
  1299   assumes "0 < real lb" "real lb \<le> y" (is "?lb \<le> y") "y \<le> real ub" (is "y \<le> ?ub")
  1311   assumes "0 < real lb" "real lb \<le> y" (is "?lb \<le> y") "y \<le> real ub" (is "y \<le> ?ub")
  1300   shows "real (lb_mod prec x ub lb) \<le> ?x - ?k * y"
  1312   shows "real (lb_mod prec x ub lb) \<le> ?x - ?k * y"
  1301 proof -
  1313 proof -
  1305   also have "\<dots> \<le> ?x / ?lb * ?ub" by (metis mult_left_mono[OF `?lb \<le> ?ub` `0 \<le> ?x`] divide_right_mono[OF _ `0 \<le> ?lb` ] times_divide_eq_left nonzero_mult_divide_cancel_right[OF `?lb \<noteq> 0`])
  1317   also have "\<dots> \<le> ?x / ?lb * ?ub" by (metis mult_left_mono[OF `?lb \<le> ?ub` `0 \<le> ?x`] divide_right_mono[OF _ `0 \<le> ?lb` ] times_divide_eq_left nonzero_mult_divide_cancel_right[OF `?lb \<noteq> 0`])
  1306   also have "\<dots> \<le> real (ceiling_fl (float_divr prec x lb)) * ?ub" by (metis mult_right_mono order_trans `0 \<le> ?lb` `?lb \<le> ?ub` float_divr ceiling_fl)
  1318   also have "\<dots> \<le> real (ceiling_fl (float_divr prec x lb)) * ?ub" by (metis mult_right_mono order_trans `0 \<le> ?lb` `?lb \<le> ?ub` float_divr ceiling_fl)
  1307   finally show ?thesis unfolding lb_mod_def real_of_float_sub real_of_float_mult by auto
  1319   finally show ?thesis unfolding lb_mod_def real_of_float_sub real_of_float_mult by auto
  1308 qed
  1320 qed
  1309 
  1321 
  1310 lemma ub_mod: fixes k :: int and x :: float assumes "0 \<le> real x" and "real x \<le> real k * y" (is "?x \<le> ?k * y")
  1322 lemma ub_mod:
       
  1323   fixes k :: int and x :: float
       
  1324   assumes "0 \<le> real x" and "real x \<le> real k * y" (is "?x \<le> ?k * y")
  1311   assumes "0 < real lb" "real lb \<le> y" (is "?lb \<le> y") "y \<le> real ub" (is "y \<le> ?ub")
  1325   assumes "0 < real lb" "real lb \<le> y" (is "?lb \<le> y") "y \<le> real ub" (is "y \<le> ?ub")
  1312   shows "?x - ?k * y \<le> real (ub_mod prec x ub lb)"
  1326   shows "?x - ?k * y \<le> real (ub_mod prec x ub lb)"
  1313 proof -
  1327 proof -
  1314   have "?lb \<le> ?ub" using assms by auto
  1328   have "?lb \<le> ?ub" using assms by auto
  1315   hence "0 \<le> ?lb" and "0 \<le> ?ub" and "?ub \<noteq> 0" using assms by auto
  1329   hence "0 \<le> ?lb" and "0 \<le> ?ub" and "?ub \<noteq> 0" using assms by auto