1 (** {1 Formalization of Floating-Point Arithmetic}
3 Full float theory (with infinities and NaN).
5 A note on intended semantics: we use the same idea as the SMTLIB floating
6 point theory, that defers any inconsistencies to the "parent" document.
7 Hence, in doubt, the correct axiomatisation is one that implements
8 [BTRW14] "An Automatable Formal Semantics for IEEE-754 Floating-Point
9 Arithmetic", which in turn defers any inconsistencies to IEEE-754.
11 This theory is split into two parts: the first part talks about IEEE
12 operations and this is what you should use as a user, the second part is
13 internal only and is an axiomatisation for the provers that do not
14 natively support floating point. You should not use any symbols you find
15 there in your verification conditions as solvers with native floating
16 point support will leave them uninterpreted.
19 (** {2 Rounding Modes} *)
22 type mode = RNE | RNA | RTP | RTN | RTZ
24 <li>RNE : Round Nearest ties to Even
25 <li>RNA : Round Nearest ties to Away
26 <li>RTP : Round Towards Positive
27 <li>RTN : Round Towards Negative
28 <li>RTZ : Round Towards Zero
31 predicate to_nearest (m:mode) = m = RNE \/ m = RNA
39 use real.FromInt as FromInt
40 use real.Truncate as Truncate
42 use export RoundingMode
44 (** {2 Part I - Public Interface} *)
47 (** the number of bits in the exponent. *)
50 (** the number of bits in the significand, including the hidden bit. *)
58 (** abstract type to denote floating-point numbers, including the special values
59 for infinities and NaNs *)
61 (** {3 Constructors and Constants} *)
63 val constant zeroF : t (** +0.0 *)
64 (* exp_bias = 2^(eb - 1) - 1 *)
65 (* max_finite_exp = 2^sb - 2 - exp_bias = exp_bias *)
66 (* max_significand = (2^eb + 2^eb - 1) * 2^(1-eb) *)
67 (* max_value = (2^eb + 2^eb - 1) * 2^(1-eb) * 2 ^ max_finite_exp *)
68 (* [m;x] = ( 1 + m * 2^(1-eb) ) * 2^( x - exp_bias ) *)
69 (* max_value = [2^(eb-1); 2^sb - 2] *)
73 val function add mode t t : t
74 val function sub mode t t : t
75 val function mul mode t t : t
76 val function div mode t t : t
77 (** The four basic operations, rounded in the given mode *)
79 val function abs t : t (** Absolute value *)
80 val function neg t : t (** Opposite *)
81 val function fma mode t t t : t (** Fused multiply-add: x * y + z *)
82 val function sqrt mode t : t (** Square root *)
84 let function (.-_) (x:t) : t = neg x
85 let function (.+) (x y:t) : t = add RNE x y
86 let function (.-) (x y:t) : t = sub RNE x y
87 let function (.*) (x y:t) : t = mul RNE x y
88 let function (./) (x y:t) : t = div RNE x y
89 (** Notations for operations in the default mode RNE *)
91 val function roundToIntegral mode t : t
92 (** Rounding to an integer *)
96 (** Minimum and Maximum
98 Note that we have to follow IEEE-754 and SMTLIB here. Two things to
101 1) min(-0, 0) is either 0 or -0, there is a choice
103 2) if either argument is NaN then the other argument is returned
105 Due to the unclear status of min and max in IEEE norm, we
106 intentionally not provide these function as "val"s to be used in
111 (** {3 Comparisons} *)
115 let predicate ge (x:t) (y:t) = le y x
116 let predicate gt (x:t) (y:t) = lt y x
118 (** equality on floats, different from = since not (eq NaN NaN) *)
120 let predicate (.<=) (x:t) (y:t) = le x y
121 let predicate (.<) (x:t) (y:t) = lt x y
122 let predicate (.>=) (x:t) (y:t) = ge x y
123 let predicate (.>) (x:t) (y:t) = gt x y
124 let predicate (.=) (x:t) (y:t) = eq x y
128 (** {3 Classification of numbers} *)
130 predicate is_normal t
131 predicate is_subnormal t
132 val predicate is_zero t
133 val predicate is_infinite t
134 val predicate is_nan t
135 val predicate is_positive t
136 val predicate is_negative t
138 (** helper predicate for zeros, normals and subnormals. not defined
139 so that the axiomatisation below can use it without talking about
141 predicate is_finite t
143 predicate is_plus_infinity (x:t) = is_infinite x /\ is_positive x
144 predicate is_minus_infinity (x:t) = is_infinite x /\ is_negative x
145 predicate is_plus_zero (x:t) = is_zero x /\ is_positive x
146 predicate is_minus_zero (x:t) = is_zero x /\ is_negative x
147 predicate is_not_nan (x:t) = is_finite x \/ is_infinite x
149 axiom is_not_nan: forall x:t. is_not_nan x <-> not (is_nan x)
151 axiom is_not_finite: forall x:t.
152 not (is_finite x) <-> (is_infinite x \/ is_nan x)
156 (** {3 Conversions from other sorts} *)
158 (* from bitvec binary interchange *)
159 (* partly done with from_binary (for literals only) *)
160 (* from another fp - see FloatConverter *)
162 (* partly done with (!) (for literals only) *)
163 (* from unsigned integer bitvector - see Float_BV_Converter *)
164 (* from signed integer bitvector *)
166 (** {3 Conversions to other sorts} *)
168 (* to unsigned integer bitvector - see Float_BV_Converter *)
169 (* to signed integer bitvector *)
171 function to_real t : real
173 (** {2 Part II - Private Axiomatisation} *)
175 (** {3 Constructors and Constants} *)
177 axiom zeroF_is_positive : is_positive zeroF
178 axiom zeroF_is_zero : is_zero zeroF
180 axiom zero_to_real : forall x [is_zero x].
181 is_zero x <-> is_finite x /\ to_real x = 0.0
183 (** {3 Conversions from other sorts} *)
185 (* with mathematical int *)
186 (* note that these conversions do not feature in SMTLIB *)
188 (* intended semantics for of_int are the same as (_ to_fp eb sb) with a *)
189 (* suitably sized bitvector, large enough to hold x *)
190 (* note values >= than the below should result in infinities *)
191 (* float32 : 0x1ffffff * 2^103 *)
192 (* float64 : 0x3fffffffffffff * 2^970 *)
193 (* also note that this function never yields a subnormal, or a NaN, or -0 *)
194 function of_int (m:mode) (x:int) : t
196 (** {3 Conversions to other sorts} *)
198 (* Intended semantics for to_int are the same as (_ fp.to_sbv) with a *)
199 (* suitably sized bitvector. Safe minimum sizes are given below: *)
202 (* In particular this function should be uninterpreted for infinities *)
203 (* and NaN. Take care that no conclusion can be made on the result based *)
204 (* on the size of the bitvector chosen in those cases, i.e. this should *)
206 (* to_int +INF < 2 ** 2048 // nope *)
207 (* to_int +INF > 0 // nope *)
208 function to_int (m:mode) (x:t) : int
210 axiom zero_of_int : forall m. zeroF = of_int m 0
212 (** {3 Arithmetic} *)
214 (* The intended meaning for round is the rounding for floating point as *)
215 (* described on p17 of IEEE-754. For results where the corresponding *)
216 (* floating point result would be infinity or NaN this function should *)
217 (* be uninterpreted. *)
219 (* Note that this means round (+INF) > 0 is not true. *)
220 (* Note also this means round (2*INF) > round (INF) is not true either. *)
221 function round mode real : real
223 constant max_real : real (* defined when cloning *)
224 constant max_int : int (* defined when cloning *)
226 constant emax : int = pow2 (eb - 1)
228 axiom max_int_spec : max_int = pow2 emax - pow2 (emax - sb)
229 axiom max_real_int: max_real = FromInt.from_int max_int
231 predicate in_range (x:real) = -. max_real <=. x <=. max_real
233 predicate in_int_range (i:int) = - max_int <= i <= max_int
235 axiom is_finite: forall x:t. is_finite x -> in_range (to_real x)
237 (* used as a condition to propagate is_finite *)
238 predicate no_overflow (m:mode) (x:real) = in_range (round m x)
240 (* Axioms on round *)
242 axiom Bounded_real_no_overflow [@W:non_conservative_extension:N] :
243 forall m:mode, x:real. in_range x -> no_overflow m x
245 axiom Round_monotonic :
246 forall m:mode, x y:real. x <=. y -> round m x <=. round m y
248 axiom Round_idempotent :
249 forall m1 m2:mode, x:real. round m1 (round m2 x) = round m2 x
251 axiom Round_to_real :
252 forall m:mode, x:t. is_finite x -> round m (to_real x) = to_real x
254 (** rounding up and down *)
256 forall x:real. round RTN x <=. x
258 forall x:real. round RTP x >=. x
259 axiom Round_down_neg:
260 forall x:real. round RTN (-.x) = -. round RTP x
262 forall x:real. round RTP (-.x) = -. round RTN x
264 (* The biggest representable integer whose predecessor (i.e. -1) is representable *)
265 constant pow2sb : int (* defined when cloning *)
266 axiom pow2sb: pow2sb = pow2 sb
268 (* range in which every integer is representable *)
269 predicate in_safe_int_range (i: int) = - pow2sb <= i <= pow2sb
271 (* round and integers *)
273 axiom Exact_rounding_for_integers:
274 forall m:mode, i:int.
275 in_safe_int_range i ->
276 round m (FromInt.from_int i) = FromInt.from_int i
278 (** {3 Comparisons} *)
280 (** Comparison predicates *)
282 predicate same_sign (x y : t) =
283 (is_positive x /\ is_positive y) \/ (is_negative x /\ is_negative y)
284 predicate diff_sign (x y : t) =
285 (is_positive x /\ is_negative y) \/ (is_negative x /\ is_positive y)
287 axiom feq_eq: forall x y.
288 is_finite x -> is_finite y -> not (is_zero x) -> x .= y -> x = y
290 axiom eq_feq: forall x y.
291 is_finite x -> is_finite y -> x = y -> x .= y
293 axiom eq_refl: forall x. is_finite x -> x .= x
296 forall x y. x .= y -> y .= x
299 forall x y z. x .= y -> y .= z -> x .= z
301 axiom eq_zero: zeroF .= (.- zeroF)
303 axiom eq_to_real_finite: forall x y.
304 is_finite x /\ is_finite y -> (x .= y <-> to_real x = to_real y)
306 axiom eq_special: forall x y. x .= y ->
307 (is_not_nan x /\ is_not_nan y
308 /\ ((is_finite x /\ is_finite y)
309 \/ (is_infinite x /\ is_infinite y /\ same_sign x y)))
311 axiom lt_finite: forall x y [lt x y].
312 is_finite x /\ is_finite y -> (lt x y <-> to_real x <. to_real y)
314 axiom le_finite: forall x y [le x y].
315 is_finite x /\ is_finite y -> (le x y <-> to_real x <=. to_real y)
318 forall x y z:t. x .<= y /\ y .< z -> x .< z
321 forall x y z:t. x .< y /\ y .<= z -> x .< z
324 forall x y:t. x .<= y /\ x .>= y -> x .= y
326 lemma not_lt_ge: forall x y:t.
327 not (x .< y) /\ is_not_nan x /\ is_not_nan y -> x .>= y
329 lemma not_gt_le: forall x y:t.
330 not (x .> y) /\ is_not_nan x /\ is_not_nan y -> x .<= y
332 axiom le_special: forall x y [le x y]. le x y ->
333 ((is_finite x /\ is_finite y)
334 \/ ((is_minus_infinity x /\ is_not_nan y)
335 \/ (is_not_nan x /\ is_plus_infinity y)))
337 axiom lt_special: forall x y [lt x y]. lt x y ->
338 ((is_finite x /\ is_finite y)
339 \/ ((is_minus_infinity x /\ is_not_nan y /\ not (is_minus_infinity y))
340 \/ (is_not_nan x /\ not (is_plus_infinity x) /\ is_plus_infinity y)))
342 axiom lt_lt_finite: forall x y z. lt x y -> lt y z -> is_finite y
345 axiom positive_to_real: forall x[is_positive x|to_real x >=. 0.0].
346 is_finite x -> is_positive x -> to_real x >=. 0.0
347 axiom to_real_positive: forall x[is_positive x].
348 is_finite x -> to_real x >. 0.0 -> is_positive x
350 axiom negative_to_real: forall x [is_negative x|to_real x <=. 0.0].
351 is_finite x -> is_negative x -> to_real x <=. 0.0
352 axiom to_real_negative: forall x [is_negative x].
353 is_finite x -> to_real x <. 0.0 -> is_negative x
355 axiom negative_xor_positive: forall x.
356 not (is_positive x /\ is_negative x)
357 axiom negative_or_positive: forall x.
358 is_not_nan x -> is_positive x \/ is_negative x
360 lemma diff_sign_trans:
361 forall x y z:t. (diff_sign x y /\ diff_sign y z) -> same_sign x z
363 lemma diff_sign_product:
365 (is_finite x /\ is_finite y /\ to_real x *. to_real y <. 0.0) ->
368 lemma same_sign_product:
370 (is_finite x /\ is_finite y /\ same_sign x y) ->
371 to_real x *. to_real y >=. 0.0
373 predicate product_sign (z x y: t) =
374 (same_sign x y -> is_positive z) /\ (diff_sign x y -> is_negative z)
378 (* This predicate is used to tell what is the result of a rounding
379 in case of overflow in the axioms specifying add/sub/mul and fma
381 predicate overflow_value (m:mode) (x:t) =
383 | RTN -> if is_positive x then is_finite x /\ to_real x = max_real
385 | RTP -> if is_positive x then is_infinite x
386 else is_finite x /\ to_real x = -. max_real
387 | RTZ -> if is_positive x then is_finite x /\ to_real x = max_real
388 else is_finite x /\ to_real x = -. max_real
389 | (RNA | RNE) -> is_infinite x
392 (* This predicate is used to tell what is the sign of zero in the
393 axioms specifying add and sub *)
394 predicate sign_zero_result (m:mode) (x:t) =
397 | RTN -> is_negative x
401 (** {3 binary operations} *)
403 axiom add_finite: forall m:mode, x y:t [add m x y].
404 is_finite x -> is_finite y -> no_overflow m (to_real x +. to_real y) ->
405 is_finite (add m x y) /\
406 to_real (add m x y) = round m (to_real x +. to_real y)
408 lemma add_finite_rev: forall m:mode, x y:t [add m x y].
409 is_finite (add m x y) ->
410 is_finite x /\ is_finite y
412 lemma add_finite_rev_n: forall m:mode, x y:t [add m x y].
414 is_finite (add m x y) ->
415 no_overflow m (to_real x +. to_real y) /\
416 to_real (add m x y) = round m (to_real x +. to_real y)
418 axiom sub_finite: forall m:mode, x y:t [sub m x y].
419 is_finite x -> is_finite y -> no_overflow m (to_real x -. to_real y) ->
420 is_finite (sub m x y) /\
421 to_real (sub m x y) = round m (to_real x -. to_real y)
423 lemma sub_finite_rev: forall m:mode, x y:t [sub m x y].
424 is_finite (sub m x y) ->
425 is_finite x /\ is_finite y
427 lemma sub_finite_rev_n: forall m:mode, x y:t [sub m x y].
429 is_finite (sub m x y) ->
430 no_overflow m (to_real x -. to_real y) /\
431 to_real (sub m x y) = round m (to_real x -. to_real y)
433 axiom mul_finite: forall m:mode, x y:t [mul m x y].
434 is_finite x -> is_finite y -> no_overflow m (to_real x *. to_real y) ->
435 is_finite (mul m x y) /\
436 to_real (mul m x y) = round m (to_real x *. to_real y)
438 lemma mul_finite_rev: forall m:mode, x y:t [mul m x y].
439 is_finite (mul m x y) ->
440 is_finite x /\ is_finite y
442 lemma mul_finite_rev_n: forall m:mode, x y:t [mul m x y].
444 is_finite (mul m x y) ->
445 no_overflow m (to_real x *. to_real y) /\
446 to_real (mul m x y) = round m (to_real x *. to_real y)
448 axiom div_finite: forall m:mode, x y:t [div m x y].
449 is_finite x -> is_finite y ->
450 not is_zero y -> no_overflow m (to_real x /. to_real y) ->
451 is_finite (div m x y) /\
452 to_real (div m x y) = round m (to_real x /. to_real y)
454 lemma div_finite_rev: forall m:mode, x y:t [div m x y].
455 is_finite (div m x y) ->
456 (is_finite x /\ is_finite y /\ not is_zero y) \/
457 (is_finite x /\ is_infinite y /\ to_real (div m x y) = 0.)
459 lemma div_finite_rev_n: forall m:mode, x y:t [div m x y].
461 is_finite (div m x y) -> is_finite y ->
462 no_overflow m (to_real x /. to_real y) /\
463 to_real (div m x y) = round m (to_real x /. to_real y)
465 axiom neg_finite: forall x:t [neg x].
468 to_real (neg x) = -. to_real x
470 lemma neg_finite_rev: forall x:t [neg x].
473 to_real (neg x) = -. to_real x
475 axiom abs_finite: forall x:t [abs x].
478 to_real (abs x) = Abs.abs (to_real x) /\
481 lemma abs_finite_rev: forall x:t [abs x].
484 to_real (abs x) = Abs.abs (to_real x)
486 axiom abs_universal : forall x:t [abs x]. not (is_negative (abs x))
488 axiom fma_finite: forall m:mode, x y z:t [fma m x y z].
489 is_finite x -> is_finite y -> is_finite z ->
490 no_overflow m (to_real x *. to_real y +. to_real z) ->
491 is_finite (fma m x y z) /\
492 to_real (fma m x y z) = round m (to_real x *. to_real y +. to_real z)
494 lemma fma_finite_rev: forall m:mode, x y z:t [fma m x y z].
495 is_finite (fma m x y z) ->
496 is_finite x /\ is_finite y /\ is_finite z
498 lemma fma_finite_rev_n: forall m:mode, x y z:t [fma m x y z].
500 is_finite (fma m x y z) ->
501 no_overflow m (to_real x *. to_real y +. to_real z) /\
502 to_real (fma m x y z) = round m (to_real x *. to_real y +. to_real z)
506 axiom sqrt_finite: forall m:mode, x:t [sqrt m x].
507 is_finite x -> to_real x >=. 0. ->
508 is_finite (sqrt m x) /\
509 to_real (sqrt m x) = round m (S.sqrt (to_real x))
511 lemma sqrt_finite_rev: forall m:mode, x:t [sqrt m x].
512 is_finite (sqrt m x) ->
513 is_finite x /\ to_real x >=. 0. /\
514 to_real (sqrt m x) = round m (S.sqrt (to_real x))
516 predicate same_sign_real (x:t) (r:real) =
517 (is_positive x /\ r >. 0.0) \/ (is_negative x /\ r <. 0.0)
519 axiom add_special: forall m:mode, x y:t [add m x y].
521 (is_nan x \/ is_nan y -> is_nan r)
523 (is_finite x /\ is_infinite y -> is_infinite r /\ same_sign r y)
525 (is_infinite x /\ is_finite y -> is_infinite r /\ same_sign r x)
527 (is_infinite x /\ is_infinite y /\ same_sign x y
528 -> is_infinite r /\ same_sign r x)
530 (is_infinite x /\ is_infinite y /\ diff_sign x y -> is_nan r)
532 (is_finite x /\ is_finite y /\ not no_overflow m (to_real x +. to_real y)
533 -> same_sign_real r (to_real x +. to_real y) /\ overflow_value m r)
535 (is_finite x /\ is_finite y
536 -> if same_sign x y then same_sign r x else sign_zero_result m r)
538 axiom sub_special: forall m:mode, x y:t [sub m x y].
540 (is_nan x \/ is_nan y -> is_nan r)
542 (is_finite x /\ is_infinite y -> is_infinite r /\ diff_sign r y)
544 (is_infinite x /\ is_finite y -> is_infinite r /\ same_sign r x)
546 (is_infinite x /\ is_infinite y /\ same_sign x y -> is_nan r)
548 (is_infinite x /\ is_infinite y /\ diff_sign x y
549 -> is_infinite r /\ same_sign r x)
551 (is_finite x /\ is_finite y /\ not no_overflow m (to_real x -. to_real y)
552 -> same_sign_real r (to_real x -. to_real y) /\ overflow_value m r)
554 (is_finite x /\ is_finite y
555 -> if diff_sign x y then same_sign r x else sign_zero_result m r)
557 axiom mul_special: forall m:mode, x y:t [mul m x y].
559 (is_nan x \/ is_nan y -> is_nan r)
560 /\ (is_zero x /\ is_infinite y -> is_nan r)
561 /\ (is_finite x /\ is_infinite y /\ not (is_zero x)
563 /\ (is_infinite x /\ is_zero y -> is_nan r)
564 /\ (is_infinite x /\ is_finite y /\ not (is_zero y)
566 /\ (is_infinite x /\ is_infinite y -> is_infinite r)
567 /\ (is_finite x /\ is_finite y /\ not no_overflow m (to_real x *. to_real y)
568 -> overflow_value m r)
569 /\ (not is_nan r -> product_sign r x y)
571 axiom div_special: forall m:mode, x y:t [div m x y].
573 (is_nan x \/ is_nan y -> is_nan r)
574 /\ (is_finite x /\ is_infinite y -> is_zero r)
575 /\ (is_infinite x /\ is_finite y -> is_infinite r)
576 /\ (is_infinite x /\ is_infinite y -> is_nan r)
577 /\ (is_finite x /\ is_finite y /\ not (is_zero y) /\
578 not no_overflow m (to_real x /. to_real y)
579 -> overflow_value m r)
580 /\ (is_finite x /\ is_zero y /\ not (is_zero x)
582 /\ (is_zero x /\ is_zero y -> is_nan r)
583 /\ (not is_nan r -> product_sign r x y)
585 axiom neg_special: forall x:t [neg x].
586 (is_nan x -> is_nan (neg x))
587 /\ (is_infinite x -> is_infinite (neg x))
588 /\ (not is_nan x -> diff_sign x (neg x))
590 axiom abs_special: forall x:t [abs x].
591 (is_nan x -> is_nan (abs x))
592 /\ (is_infinite x -> is_infinite (abs x))
593 /\ (not is_nan x -> is_positive (abs x))
595 axiom fma_special: forall m:mode, x y z:t [fma m x y z].
596 let r = fma m x y z in
597 (is_nan x \/ is_nan y \/ is_nan z -> is_nan r)
598 /\ (is_zero x /\ is_infinite y -> is_nan r)
599 /\ (is_infinite x /\ is_zero y -> is_nan r)
600 /\ (is_finite x /\ not (is_zero x) /\ is_infinite y /\ is_finite z
601 -> is_infinite r /\ product_sign r x y)
602 /\ (is_finite x /\ not (is_zero x) /\ is_infinite y /\ is_infinite z
603 -> (if product_sign z x y then is_infinite r /\ same_sign r z
605 /\ (is_infinite x /\ is_finite y /\ not (is_zero y) /\ is_finite z
606 -> is_infinite r /\ product_sign r x y)
607 /\ (is_infinite x /\ is_finite y /\ not (is_zero y) /\ is_infinite z
608 -> (if product_sign z x y then is_infinite r /\ same_sign r z
610 /\ (is_infinite x /\ is_infinite y /\ is_finite z
611 -> is_infinite r /\ product_sign r x y)
612 /\ (is_finite x /\ is_finite y /\ is_infinite z
613 -> is_infinite r /\ same_sign r z)
614 /\ (is_infinite x /\ is_infinite y /\ is_infinite z
615 -> (if product_sign z x y then is_infinite r /\ same_sign r z
617 /\ (is_finite x /\ is_finite y /\ is_finite z /\
618 not no_overflow m (to_real x *. to_real y +. to_real z)
619 -> same_sign_real r (to_real x *. to_real y +. to_real z)
620 /\ overflow_value m r)
621 /\ (is_finite x /\ is_finite y /\ is_finite z
622 -> if product_sign z x y then same_sign r z
623 else (to_real x *. to_real y +. to_real z = 0.0 ->
624 if m = RTN then is_negative r else is_positive r))
626 axiom sqrt_special: forall m:mode, x:t [sqrt m x].
628 (is_nan x -> is_nan r)
629 /\ (is_plus_infinity x -> is_plus_infinity r)
630 /\ (is_minus_infinity x -> is_nan r)
631 /\ (is_finite x /\ to_real x <. 0.0 -> is_nan r)
632 /\ (is_zero x -> same_sign r x)
633 /\ (is_finite x /\ to_real x >. 0.0 -> is_positive r)
635 (* exact arithmetic with integers *)
637 axiom of_int_add_exact: forall m n, i j.
638 in_safe_int_range i -> in_safe_int_range j ->
639 in_safe_int_range (i + j) -> eq (of_int m (i + j)) (add n (of_int m i) (of_int m j))
641 axiom of_int_sub_exact: forall m n, i j.
642 in_safe_int_range i -> in_safe_int_range j ->
643 in_safe_int_range (i - j) -> eq (of_int m (i - j)) (sub n (of_int m i) (of_int m j))
645 axiom of_int_mul_exact: forall m n, i j.
646 in_safe_int_range i -> in_safe_int_range j ->
647 in_safe_int_range (i * j) -> eq (of_int m (i * j)) (mul n (of_int m i) (of_int m j))
651 lemma Min_r : forall x y:t. y .<= x -> (min x y) .= y
652 lemma Min_l : forall x y:t. x .<= y -> (min x y) .= x
653 lemma Max_r : forall x y:t. y .<= x -> (max x y) .= x
654 lemma Max_l : forall x y:t. x .<= y -> (max x y) .= y
658 use real.Truncate as Truncate
660 (* This predicate specify if a float is finite and is an integer *)
661 predicate is_int (x:t)
663 (** characterizing integers *)
665 (* by construction *)
666 axiom zeroF_is_int: is_int zeroF
668 axiom of_int_is_int: forall m, x.
669 in_int_range x -> is_int (of_int m x)
671 axiom big_float_is_int: forall m i.
673 i .<= neg (of_int m pow2sb) \/ (of_int m pow2sb) .<= i ->
676 axiom roundToIntegral_is_int: forall m:mode, x:t. is_finite x ->
677 is_int (roundToIntegral m x)
680 axiom eq_is_int: forall x y. eq x y -> is_int x -> is_int y
682 axiom add_int: forall x y m. is_int x -> is_int y ->
683 is_finite (add m x y) -> is_int (add m x y)
685 axiom sub_int: forall x y m. is_int x -> is_int y ->
686 is_finite (sub m x y) -> is_int (sub m x y)
688 axiom mul_int: forall x y m. is_int x -> is_int y ->
689 is_finite (mul m x y) -> is_int (mul m x y)
691 axiom fma_int: forall x y z m. is_int x -> is_int y -> is_int z ->
692 is_finite (fma m x y z) -> is_int (fma m x y z)
694 axiom neg_int: forall x. is_int x -> is_int (neg x)
696 axiom abs_int: forall x. is_int x -> is_int (abs x)
698 (** basic properties of float integers *)
700 axiom is_int_of_int: forall x m m'.
701 is_int x -> eq x (of_int m' (to_int m x))
703 axiom is_int_to_int: forall m x.
704 is_int x -> in_int_range (to_int m x)
706 axiom is_int_is_finite: forall x.
707 is_int x -> is_finite x
709 axiom int_to_real: forall m x.
710 is_int x -> to_real x = FromInt.from_int (to_int m x)
712 (* axiom int_mode: forall m1 m2 x.
713 is_int x -> to_int m1 x = to_int m2 x etc ...*)
717 axiom truncate_int: forall m:mode, i:t. is_int i ->
718 roundToIntegral m i .= i
722 axiom truncate_neg: forall x:t.
723 is_finite x -> is_negative x -> roundToIntegral RTZ x = roundToIntegral RTP x
725 axiom truncate_pos: forall x:t.
726 is_finite x -> is_positive x -> roundToIntegral RTZ x = roundToIntegral RTN x
730 axiom ceil_le: forall x:t. is_finite x -> x .<= (roundToIntegral RTP x)
732 axiom ceil_lest: forall x y:t. x .<= y /\ is_int y -> (roundToIntegral RTP x) .<= y
734 axiom ceil_to_real: forall x:t.
736 to_real (roundToIntegral RTP x) = FromInt.from_int (Truncate.ceil (to_real x))
738 axiom ceil_to_int: forall m:mode, x:t.
740 to_int m (roundToIntegral RTP x) = Truncate.ceil (to_real x)
744 axiom floor_le: forall x:t. is_finite x -> (roundToIntegral RTN x) .<= x
746 axiom floor_lest: forall x y:t. y .<= x /\ is_int y -> y .<= (roundToIntegral RTN x)
748 axiom floor_to_real: forall x:t.
750 to_real (roundToIntegral RTN x) = FromInt.from_int (Truncate.floor (to_real x))
752 axiom floor_to_int: forall m:mode, x:t.
754 to_int m (roundToIntegral RTN x) = Truncate.floor (to_real x)
759 forall x:t. (x .- (roundToIntegral RTN x)) .< ((roundToIntegral RTP x) .- x) ->
760 roundToIntegral RNA x = roundToIntegral RTN x
763 forall x:t. (x .- (roundToIntegral RTN x)) .> ((roundToIntegral RTP x) .- x) ->
764 roundToIntegral RNA x = roundToIntegral RTP x
767 forall x:t. (x .- (roundToIntegral RTN x)) .= ((roundToIntegral RTP x) .- x) ->
768 is_negative x -> roundToIntegral RNA x = roundToIntegral RTN x
771 forall x:t. ((roundToIntegral RTP x) .- x) .= (x .- (roundToIntegral RTN x)) ->
772 is_positive x -> roundToIntegral RNA x = roundToIntegral RTP x
775 axiom to_int_roundToIntegral: forall m:mode, x:t.
776 to_int m x = to_int m (roundToIntegral m x)
778 axiom to_int_monotonic: forall m:mode, x y:t.
779 is_finite x -> is_finite y -> le x y -> to_int m x <= to_int m y
781 axiom to_int_of_int: forall m:mode, i:int.
782 in_safe_int_range i ->
783 to_int m (of_int m i) = i
785 axiom eq_to_int: forall m, x y. is_finite x -> x .= y ->
786 to_int m x = to_int m y
788 axiom neg_to_int: forall m x.
789 is_int x -> to_int m (neg x) = - (to_int m x)
791 axiom roundToIntegral_is_finite : forall m:mode, x:t. is_finite x ->
792 is_finite (roundToIntegral m x)
795 (** {2 Conversions to/from bitvectors} *)
797 module Float_BV_Converter
804 type t (* the underlying float type, to be cloned *)
805 predicate is_finite t
807 function to_real t : real
808 function round mode real : real
810 (* convert from signed bitvector *)
811 val function of_sbv8 mode BV8.t : t
812 val function of_sbv16 mode BV16.t : t
813 val function of_sbv32 mode BV32.t : t
814 val function of_sbv64 mode BV64.t : t
816 (* convert to signed bitvector *)
817 val function to_sbv8 mode BV8.t : t
818 val function to_sbv16 mode BV16.t : t
819 val function to_sbv32 mode BV32.t : t
820 val function to_sbv64 mode BV64.t : t
822 (* convert from unsigned bitvector *)
823 val function of_ubv8 mode BV8.t : t
824 val function of_ubv16 mode BV16.t : t
825 val function of_ubv32 mode BV32.t : t
826 val function of_ubv64 mode BV64.t : t
828 (* convert to unsigned bitvector *)
829 val function to_ubv8 mode t : BV8.t
830 val function to_ubv16 mode t : BV16.t
831 val function to_ubv32 mode t : BV32.t
832 val function to_ubv64 mode t : BV64.t
835 use real.FromInt as FromInt
837 (** of unsigned bv axioms *)
838 (* only true for big enough floats... *)
840 axiom of_ubv8_is_finite : forall m, x. is_finite (of_ubv8 m x)
841 axiom of_ubv16_is_finite: forall m, x. is_finite (of_ubv16 m x)
842 axiom of_ubv32_is_finite: forall m, x. is_finite (of_ubv32 m x)
843 axiom of_ubv64_is_finite: forall m, x. is_finite (of_ubv64 m x)
845 axiom of_ubv8_monotonic :
846 forall m, x y. BV8.ule x y -> le (of_ubv8 m x) (of_ubv8 m y)
847 axiom of_ubv16_monotonic:
848 forall m, x y. BV16.ule x y -> le (of_ubv16 m x) (of_ubv16 m y)
849 axiom of_ubv32_monotonic:
850 forall m, x y. BV32.ule x y -> le (of_ubv32 m x) (of_ubv32 m y)
851 axiom of_ubv64_monotonic:
852 forall m, x y. BV64.ule x y -> le (of_ubv64 m x) (of_ubv64 m y)
854 axiom of_ubv8_to_real : forall m, x.
855 to_real (of_ubv8 m x) = FromInt.from_int (BV8.t'int x)
856 axiom of_ubv16_to_real: forall m, x.
857 to_real (of_ubv16 m x) = FromInt.from_int (BV16.t'int x)
858 (* of_ubv32_to_real is defined at cloning *)
859 axiom of_ubv64_to_real: forall m, x.
860 to_real (of_ubv64 m x) = round m (FromInt.from_int (BV64.t'int x))
863 (** {2 Standard simple precision floats (32 bits)} *)
869 type t = < float 8 24 >
871 constant pow2sb : int = 16777216
872 constant max_int : int = 0xFFFF_FF00_0000_0000_0000_0000_0000_0000
873 constant max_real : real = 0x1.FFFFFEp127
875 clone export GenericFloat with
879 constant pow2sb = pow2sb,
880 constant max_int = max_int,
881 constant max_real = max_real,
882 function to_real = t'real,
883 predicate is_finite = t'isFinite,
884 (* the following are lemmas and not goals, because we want to
885 prove them in the realizations. See also
886 [https://gitlab.inria.fr/why3/why3/-/issues/664] *)
892 axiom . (* TODO: "lemma"? "goal"? *)
894 lemma round_bound_ne :
895 forall x:real [round RNE x].
897 x - 0x1p-24 * Abs.abs(x) - 0x1p-150 <= round RNE x <= x + 0x1p-24 * Abs.abs(x) + 0x1p-150
900 forall m:mode, x:real [round m x].
902 x - 0x1p-23 * Abs.abs(x) - 0x1p-149 <= round m x <= x + 0x1p-23 * Abs.abs(x) + 0x1p-149
905 (** {2 Standard double precision floats (64 bits)} *)
911 type t = < float 11 53 >
913 constant pow2sb : int = 9007199254740992 (* 242 *)
914 constant max_int : int = 0xFFFF_FFFF_FFFF_F800_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
915 constant max_real : real = 0x1.FFFFFFFFFFFFFp1023
917 clone export GenericFloat with
921 constant pow2sb = pow2sb,
922 constant max_int = max_int,
923 constant max_real = max_real,
924 function to_real = t'real,
925 predicate is_finite = t'isFinite,
926 (* the following are lemmas and not goals, because we want to
927 prove them in the realizations. See also
928 [https://gitlab.inria.fr/why3/why3/-/issues/664] *)
934 axiom . (* TODO: "lemma"? "goal"? *)
936 lemma round_bound_ne :
937 forall x:real [round RNE x].
939 x - 0x1p-53 * Abs.abs(x) - 0x1p-1075 <= round RNE x <= x + 0x1p-53 * Abs.abs(x) + 0x1p-1075
942 forall m:mode, x:real [round m x].
944 x - 0x1p-52 * Abs.abs(x) - 0x1p-1074 <= round m x <= x + 0x1p-52 * Abs.abs(x) + 0x1p-1074
947 (** {2 Conversions between float formats} *)
949 module FloatConverter
951 use Float64 as Float64
952 use Float32 as Float32
954 use export RoundingMode
956 function to_float64 mode Float32.t : Float64.t
957 function to_float32 mode Float64.t : Float32.t
959 lemma round_double_single :
960 forall m1 m2:mode, x:real.
961 Float64.round m1 (Float32.round m2 x) = Float32.round m2 x
963 lemma to_float64_exact:
964 forall m:mode, x:Float32.t. Float32.t'isFinite x ->
965 Float64.t'isFinite (to_float64 m x)
966 /\ Float64.t'real (to_float64 m x) = Float32.t'real x
968 lemma to_float32_conv:
969 forall m:mode, x:Float64.t. Float64.t'isFinite x ->
970 Float32.no_overflow m (Float64.t'real x) ->
971 Float32.t'isFinite (to_float32 m x)
972 /\ Float32.t'real (to_float32 m x) = Float32.round m (Float64.t'real x)
976 module Float32_BV_Converter
979 clone export Float_BV_Converter with
981 predicate is_finite = t'isFinite,
982 predicate le = (.<=),
983 function to_real = t'real,
984 function round = round,
985 axiom . (* TODO: "lemma"? "goal"? *)
987 axiom of_ubv32_to_real : forall m, x.
988 t'real (of_ubv32 m x) = round m (FromInt.from_int (BV32.t'int x))
991 module Float64_BV_Converter
994 clone export Float_BV_Converter with
996 predicate is_finite = t'isFinite,
997 predicate le = (.<=),
998 function to_real = t'real,
999 function round = round,
1000 axiom . (* TODO: "lemma"? "goal"? *)
1002 axiom of_ubv32_to_real : forall m, x.
1003 t'real (of_ubv32 m x) = FromInt.from_int (BV32.t'int x)