Arithmetic

Arithmetic is performed by evaluable predicates which take as arguments arithmetic expressions and evaluate them. An arithmetic expression is a term built from evaluable functors, numbers and variables. At the time of evaluation, each variable in an arithmetic expression must be bound to a number or to an arithmetic expression. Each evaluable functor stands for an arithmetic operation.

The evaluable functors are as follows, where X and Y are arithmetic expressions.

X + Y
addition.

X - Y
subtraction.

X*Y
multiplication.

X/Y
division.

X//Y
integer division.

X(mod Y)
X (integer) modulo Y.

- X
unary minus.

X / \ Y
integer bitwise conjunction.

X \/ Y
integer bitwise disjunction.

X $\ll$ Y
integer bitwise left shift of X by Y places.

X $\gg$ Y
integer bitwise right shift of X by Y places.

\X
integer bitwise negation.

As far as unification is concerned, no type distinction is made between integers and floating point numbers, and no explicit type conversion is necessary when unifying an integer with a float. However, due to the finite precision representation of floating point numbers and cumulative round-off errors in floating point arithmetic, comparisons involving floating point numbers may not always give the expected results. An effort is made to minimize surprises by considering two numbers x and y (at least one of which is a float) to be unifiable if (| x| - | y|)/min(| x|,| y|) to be less than 10-5. The user should note, however, that this does not guarantee immunity against round-off errors.

The arithmetic evaluable predicates are as follows, where X and Y stand for arithmetic expressions, and Z for some term. Note that this means that is only evaluates one of its arguments as an arithmetic expression (the right-hand side one), whereas all the comparison predicates evaluate both their arguments.

Z $\bf is$ X
is/2 (L) Arithmetic expression X is evaluated and the result, is unified with Z. Fails if X is not an arithmetic expression. Unlike many other Prolog systems, variables in the expression X may be bound to other arithmetic expressions as well as to numbers.

eval(E, X)
eval/2 (L) Evaluates the arithmetic expression E and unifies the result with the term X. Fails if E is not an arithmetic expression. (Thus, eval/2 is, except for the switched argument order, the same as is/2. It's around mainly for historical reasons.)

X$\bf =:=$Y
=:=/2 (I) The values of X and Y are equal. If either X or Y involve compound subexpressions that are created at runtime, they should first be evaluated using eval/2.

X$\bf =\backslash\,=$Y
= \  = /2 (I) The values of X and Y are not equal. If either X or Y involve compound subexpressions that are created at runtime, they should first be evaluated using eval/2.

X$\bf <$Y
< /2 (I) The value of X is less than the value of Y. If either X or Y involve compound subexpressions that are created at runtime, they should first be evaluated using eval/2.

X$\bf >$Y
> /2 (I) The value of X is greater than the value of Y. If either X or Y involve compound subexpressions that are created at runtime, they should first be evaluated using eval/2.

X$\bf =<$Y
= < /2 (I) The value of X is less than or equal to the value of Y. If either X or Y involve compound subexpressions that are created at runtime, they should first be evaluated using eval/2.

X$\bf >=$Y
> =/2 (I) The value of X is greater than or equal to the value of Y. If either X or Y involve compound subexpressions that are created at runtime, they should first be evaluated using eval/2.

floor(X, Y)
floor/2 (B) If X is a floating point number in the call and Y is free, then Y is instantiated to the largest integer whose absolute value is not greater than the absolute value of X; if X is uninstantiated in the call and Y is an integer, then X is instantiated to the smallest float not less than Y.

floatc(F, M, E)
floatc/3 (B) If F is a number while M and E are uninstantiated in the call, then M is instantiated to a float m (of magnitude less than 1), and E to an integer n, such that

F = m×2n

If F is uninstantiated in the call while M is a float and E an integer, then F becomes instantiated to  M×2E.

exp(X, Y)
exp/2 (B) If X is instantiated to a number and Y is uninstantiated in the call, then Y is instantiated to eX (where e = 2.71828...); if X is uninstantiated in the call while Y is instantiated to a positive number, then X is instantiated to loge(Y).

square(X, Y)
square/2 (B) If X is instantiated to a number while Y is uninstantiated in the call, then Y becomes instantiated to X2; if X is uninstantiated in the call while Y is instantiated to a positive number, then X becomes instantiated to the positive square root of Y (if Y is negative in the call, X becomes instantiated to 0.0).

sin(X, Y)
sin/2 (B) If X is instantiated to a number (representing an angle in radians) and Y is uninstantiated in the call, then Y becomes instantiated to sin(X) (the user should check the magnitude of X to make sure that the result is meaningful). If Y is instantiated to a number between - π/2 and π/2 and X is uninstantiated in the call, then X becomes instantiated to sin-1(Y).