What do Prolog implementations mean by “float”?

2019-06-22 07:18发布

I was looking through the SICStus manual's syntax description and there is a definition of "float". However, there is no indication of what the implementation of "float" actually is. IEEE single or double precision? Maybe even a BigDecimal?

In SWI Prolog (or at least SWISH), the "float" seems to be IEEE double precision, as can be determined via:

planck_float(P) :-
   planck_float_descent(1.0,P).

planck_float_descent(X,P) :-
   Xhalf is X / 2.0, Xtest is 1.0 + Xhalf, Xtest =\= 1.0, !,
   write(Xhalf),writeln(Xtest),
   planck_float_descent(Xhalf,P).
planck_float_descent(P,P) :-
   Xhalf is P / 2.0, Xtest is 1.0 + Xhalf, Xtest == 1.0,
   writeln(P).

?- planck_float(P).
P = 2.220446049250313e-16

2.22e-16 being the last value that, added to 1.0 still yields something larger than 1.0 sounds about right for IEEE 64-bit floating point arithmetic.

What implementation do other Prologs have?

2条回答
小情绪 Triste *
2楼-- · 2019-06-22 08:09

The documentation of SICStus 4.3.1 reads:

The range of floats is the one provided by the C double type, typically [4.9e-324, 1.8e+308] (plus or minus). In case of overflow or division by zero, an evaluation error exception will be raised. Floats are represented by 64 bits and they conform to the IEEE 754 standard.

Together with the declaration of ISO conformance, this does not leave anything open. Note that "the IEEE 754 standard" alone without any further qualification does not say much, as it might mean minifloats, decimals, and various modes. Also, exception handling vs continuation values and other recommendations make things much more complex and by no means easy.

The ISO Prolog standard requires to produce Prolog-exceptions ("traps" in IEEE parlance) in all cases. There is no provision of continuation values like NaN, +∞ and the like. At first cursory sight this suggests that those values are entirely incompatible to ISO Prolog. However, subclause 5.5 defines the possible extensions to the standard. There is in particular the following subclause which permits the introduction of continuation values.

5.5.10 Evaluable functors

A processor may support one or more additional evaluable
functors (9) as an implementation specific feature. A
processor may support the value of an expression being a
value of an additional type instead of an exceptional value.

NOTE - A program that makes no use of extensions should
not rely on catching errors from procedures that evaluate their
arguments (such as is/2, 8.6.1) unless it is executed in strictly
conforming mode (5.1 e).

This note reveals the intention behind: In strictly conforming mode all those extensions are absent and only Prolog-exceptions are signaled. How precisely an extension should look like is by far not clear. The proposal by @jschimpf contains some interesting points, but it does not take into account the intention of William Kahan's documents. In particular, IEEE-exception-flags are missing completely (or a corresponding better scoped functionality), which renders NaNs next to useless. The other two proper algebraic completions are not there. (Further, that proposal dates from 2009 and has not taken into account Cor.2:2012.)

ISO Prolog does only provide a framework for floating points (see ISO/IEC 13211-1:1995 7.1.3 Floating point), both binary, decimal and even any positive even base (radix) would fit. In the 1980s, some systems (e.g., C-Prolog) used to have floats with a precision a bit lower than single precision IEEE floats. In 32 bits both the Prolog tag and the float was squeezed (with a smaller mantissa), while actual computations were carried out in double precision, the good olde, no longer valid, C default. I believe that that representation fits into ISO, too. ISO Prolog requires at least 6 decimal digits. However, I am unaware of current systems using anything else than binary IEEE double precision.

Floats in ISO Prolog are based essentially on the ISO LIA standards ("language independent arithmetics") ISO/IEC 10967-1:1995, which in the meantime has been replaced by ISO/IEC 10967-1:2012 which is compatible with ISO/IEC/IEEE 60559:2011, vulgo IEEE 754-2008.

Note that IEEE and LIA serve different purposes: IEEE is about floats and only a few functions, whereas LIA includes more functions, integer arithmetics and complex numbers, too.

To give you an idea, how floating point operations are currently implemented in various Prolog systems, consider the goal

X is 0** -1, write_canonical(X).

which should produce an evaluation_error(undefined). Three systems conform (IF, SICStus, Prolog IV), and the other systems are all different except for two.

0, (+inf), Infinity.0, inf.0, 0.Inf, inf, inf

is produced respectively by

SWI, YAP, Minerva, XSB, Ciao, B, GNU

As all those outputs constitute valid Prolog text (some need an infix .), they are all invalid extensions since they redefine the meaning of existing Prolog syntax.

查看更多
Bombasti
3楼-- · 2019-06-22 08:12

What you call planck_float is usually called epsilon. Many Prolog systems have a constant for this value, so that it doesn't need to be calculated.

The constant was suggested in N208:

9.7.3.1 Description epsilon evaluates to the
distance from 1.0 to the next largest floating point
number, an implementation defined value.
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/N208

Many Prolog systems support this constant which can tell you what the default float type means. For example GNU Prolog gives me:

GNU Prolog 1.4.5 (64 bits)
| ?- X is epsilon.
X = 2.2204460492503131e-016

This doesn't mean that a Prolog system only might have one float data type. It is also possible that a Prolog system supports multiple float types. For example in Jekejeke Prolog it is possible to use 32-bit floats denoted by the prefix 0f:

Jekejeke Prolog 3, Runtime Library 1.3.6
?- X is epsilon.
X = 2.220446049250313E-16
?- X is epsilon32.
X = 0f1.1920929E-7
查看更多
登录 后发表回答