4.26 Arithmetic

Arithmetic can be divided into some special purpose integer predicates and a series of general predicates for integer, floating point and rational arithmetic as appropriate. The general arithmetic predicates all handle expressions. An expression is either a simple number or a function. The arguments of a function are expressions. The functions are described in section 4.26.2.3.

4.26.1 Special purpose integer arithmetic

The predicates in this section provide more logical operations between integers. They are not covered by the ISO standard, although they are `part of the community' and found as either library or built-in in many other Prolog systems.

between(+Low, +High, ?Value)
Low and High are integers, High >=Low. If Value is an integer, Low =<Value =<High. When Value is a variable it is successively bound to all integers between Low and High. If High is inf or infinite64We prefer infinite, but some other Prolog systems already use inf for infinity we accept both for the time being. between/3 is true iff Value >=Low, a feature that is particularly interesting for generating integers from a certain value.
succ(?Int1, ?Int2)
True if Int2 = Int1 + 1 and Int1 >= 0. At least one of the arguments must be instantiated to a natural number. This predicate raises the domain-error not_less_than_zero if called with a negative integer. E.g. succ(X, 0) fails silently and succ(X, -1) raises a domain-error.65The behaviour to deal with natural numbers only was defined by Richard O'Keefe to support the common count-down-to-zero in a natural way. Up-to 5.1.8 succ/2 also accepted negative integers.
plus(?Int1, ?Int2, ?Int3)
True if Int3 = Int1 + Int2. At least two of the three arguments must be instantiated to integers.

4.26.2 General purpose arithmetic

The general arithmetic predicates are optionally compiled (see set_prolog_flag/2 and the -O command line option). Compiled arithmetic reduces global stack requirements and improves performance. Unfortunately compiled arithmetic cannot be traced, which is why it is optional.

[ISO]+Expr1 > +Expr2
True if expression Expr1 evaluates to a larger number than Expr2.
[ISO]+Expr1 < +Expr2
True if expression Expr1 evaluates to a smaller number than Expr2.
[ISO]+Expr1 =< +Expr2
True if expression Expr1 evaluates to a smaller or equal number to Expr2.
[ISO]+Expr1 >= +Expr2
True if expression Expr1 evaluates to a larger or equal number to Expr2.
[ISO]+Expr1 =\= +Expr2
True if expression Expr1 evaluates to a number non-equal to Expr2.
[ISO]+Expr1 =:= +Expr2
True if expression Expr1 evaluates to a number equal to Expr2.
[ISO]-Number is +Expr
True when Number is the value to which Expr evaluates. Typically, is/2 should be used with unbound left operand. If equality is to be tested, =:=/2 should be used. For example:

?- 1 is sin(pi/2). Fails!. sin(pi/2) evaluates to the float 1.0, which does not unify with the integer 1.
?- 1 =:= sin(pi/2). Succeeds as expected.

4.26.2.1 Arithmetic types

SWI-Prolog defines the following numeric types:

Arithmetic functions that require integer arguments accept, in addition to integers, rational numbers with (canonical) denominator `1'. If the required argument is a float the argument is converted to float. Note that conversion of integers to floating point numbers may raise an overflow exception. In all other cases, arguments are converted to the same type using the order below.

integer -> rational number -> floating point number

4.26.2.2 Rational number examples

The use of rational numbers with unbounded integers allows for exact integer or fixed point arithmetic under the addition, subtraction, multiplication and division. To exploit rational arithmetic rdiv(2) should be used instead of `/' and floating point numbers must be converted to rational using rational(1). Omitting the rational(1) on floats will convert a rational operand to float and continue the arithmetic using floating point numbers. Here are some examples.

A is 2 rdiv 6A = 1 rdiv 3
A is 4 rdiv 3 + 1A = 7 rdiv 3
A is 4 rdiv 3 + 1.5A = 2.83333
A is 4 rdiv 3 + rational(1.5)A = 17 rdiv 6

Note that floats cannot represent all decimal numbers exactly. The function rational(1) creates an exact equivalent of the float, while rationalize(1) creates a rational number that is within the float rounding error from the original float. Please check the documentation of these functions for details and examples.

Rational numbers can be printed as decimal numbers with arbitrary precision using the format/3 floating point conversion:

?- A is 4 rdiv 3 + rational(1.5),
   format('~50f~n', [A]).
2.83333333333333333333333333333333333333333333333333

A = 17 rdiv 6

4.26.2.3 Arithmetic Functions

Arithmetic functions are terms which are evaluated by the arithmetic predicates described in section 4.26.2. There are four types of arguments to functions:

Expr Arbitrary expression, returning either a floating point value or an integer.
IntExpr Arbitrary expression that must evaluate into an integer.
RatExpr Arbitrary expression that must evaluate into a rational number.
FloatExpr Arbitrary expression that must evaluate into a floating point.

For systems using bounded integer arithmetic (default is unbounded, see section 4.26.2.1 for details), integer operations that would cause overflow automatically convert to floating point arithmetic.

Bitvector functions

The functions below are not covered by the standard. The msb(1) function is compatible with hProlog. The others are private extensions that improve handling of ---unbounded--- integers as bit-vectors.