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" |
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) |
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 |