SWI currently provides partial support for rational numbers. From the reference manual (184.108.40.206 Arithmetic types):
“In the long term, it is likely that rational numbers will become atomic as well as a subtype of number. User code that creates or inspects the
rdiv(M,N) terms will not be portable to future versions.”
I’m prepared to submit a feature request on improvements to rational number support but would like to make sure I understand what this “long term” view entails. Perhaps there are already ideas in play, but to me it means:
Rationals are a subtype of numbers (as stated above) and not compound terms. Integers are a subtype of rationals as currently.
This carries over to the “Standard Order of Terms” (4.7):
“Numbers are compared by value. Mixed integer/float are compared as floats. If the comparison is equal, the float is considered the smaller value.”
substituting “rational” for “integer”. (The canonical form of rational numbers include integers so it’s not possible to have an integer value which can be distinguished from an equivalent rational number.)
This means the standard sort predicates will work as expected on lists of mixed numbers (integers, rationals, and floats).
For the most part, the current arithmetic predicates provide adequate support for rationals. However the division (/ operator) of two rational numbers (which include integers) should produce a rational number, not a float. This is not currently the case, i.e.,
X is 1/2unifies
1 rdiv 2. (However
X is 1 rdiv 2 / 2does unify
1 rdiv 4.)
Built-in predicates for “Analysing and Constructing Terms” (4.21) change to so that rationals work the same as other number types. Predicates that expect compound terms will no longer work with rationals.
Native syntax. In general, programming language support for rational literals is mixed. Those that have it (Common Lisp, Python, Ruby, OWL, Guile, Wolfram, Julia) usually use the
qare integers and
q!=0. However, this conflicts with the Prolog operator
/used to construct compound terms. (Julia uses
//which has a similar issue.) Ruby rational literals could work. They have a ‘
r’ suffix, e.g.,
3/2r, which is currently illegal Prolog syntax. Using a letter in a number format is a little reminiscent of the ‘
e’ optionally used in floating point literals. (So maybe
3/2Rshould also be acceptable on input.)
Given the above, I think the
rdiv operator is no longer required and could be deprecated.