- Predefined Arithmetic Functions
- Evaluation Mechanism
- User Defined Arithmetic Functions
- Runtime Expressions

The following predefined arithmetic functions are available.
*E*, *E1* and *E2* stand for
arbitrary arithmetic expressions.

Function | Description | Argument Types | Result Type |

+ E | unary plus | number | number |

– E | unary minus | number | number |

abs(E) | absolute value | number | number |

sgn(E) | sign value | number | integer |

floor(E) | round down to integral value | number | number |

ceiling(E) | round up to integral value | number | number |

round(E) | round to nearest integral value | number | number |

truncate(E) | truncate to integral value | number | number |

E1 + E2 | addition | number × number | number |

E1 – E2 | subtraction | number × number | number |

E1 * E2 | multiplication | number × number | number |

E1 / E2 | division | number × number | see below |

E1 // E2 | integer division (truncate) | integer × integer | integer |

E1 rem E2 | integer remainder | integer × integer | integer |

E1 div E2 | integer division (floor) | integer × integer | integer |

E1 mod E2 | integer modulus | integer × integer | integer |

gcd(E1,E2) | greatest common divisor | integer × integer | integer |

lcm(E1,E2) | least common multiple | integer × integer | integer |

E1 ^ E2 | power operation | number × number | number |

min(E1,E2) | minimum of 2 values | number × number | number |

max(E1,E2) | maximum of 2 values | number × number | number |

copysign(E1,E2) | combine value and sign | number × number | number |

nexttoward(E1,E2) | next representable number | number × number | number |

`\` E | bitwise complement | integer | integer |

E1 `/\` E2 | bitwise conjunction | integer × integer | integer |

E1 `\/` E2 | bitwise disjunction | integer × integer | integer |

xor(E1,E2) | bitwise exclusive disjunction | integer × integer | integer |

E1 >> E2 | shift E1 right by E2 bits | integer × integer | integer |

E1 << E2 | shift E1 left by E2 bits | integer × integer | integer |

sin(E) | trigonometric function | number | real |

cos(E) | trigonometric function | number | real |

tan(E) | trigonometric function | number | real |

asin(E) | trigonometric function | number | real |

acos(E) | trigonometric function | number | real |

atan(E) | trigonometric function | number | real |

atan(E1,E1) | trigonometric function | number × number | real |

exp(E) | exponential function e^{x} | number | real |

ln(E) | natural logarithm | number | real |

sqrt(E) | square root | number | real |

pi | the constant pi = 3.1415926... | — | float |

e | the constant e = 2.7182818... | — | float |

fix(E) | convert to integer (truncate) | number | integer |

integer(E) | convert to integer (exact) | number | integer |

float(E) | convert to float | number | float |

breal(E) | convert to bounded real | number | breal |

rational(E) | convert to rational | number | rational |

rationalize(E) | convert to rational | number | rational |

numerator(E) | extract numerator of a rational | integer or rational | integer |

denominator(E) | extract denominator of a rational | integer or rational | integer |

sum(Es) | sum of elements | vector | number |

sum(Es*Es) | scalar product | vector*vector | number |

min(Es) | minimum of list elements | vector | number |

max(Es) | maximum of list elements | vector | number |

eval(E) | evaluate runtime expression | term | number |

Argument types other than specified yield a type error.
As an argument type, *number* stands for *integer*,
*rational*, *float* or *breal* with the type conversions as
specified above.
As a result type, *number* stands for
*the more general of the argument types*, and *real* stands for
*float* or *breal*.
The division operator / yields either a rational or a float result,
depending on the value of the global flag
prefer_rationals.
The same is true for the result of ^ if an integer is raised to
a negative integral power.

The integer division // rounds the result towards zero (truncates),
while the div division rounds towards negative infinity (floor).
Each division function is paired with a corresponding remainder function:
(rem computes the remainder corresponding to //, and
mod
computes the remainder corresponding to div
^{3}.
The remainder results differ only in the case where the two arguments
have opposite signs. The relationship between them is as follows:

X =:= (X rem Y) + (X // Y) * Y X =:= (X mod Y) + (X div Y) * Y

This table gives an overview:

10 x 3 -10 x 3 10 x -3 -10 x -3 // 3 -3 -3 3 rem 1 -1 1 -1 div 3 -4 -4 3 mod 1 2 -2 -1

An arithmetic expression is a Prolog term that is made up of variables, numbers, atoms and compound terms, e.g.,

3 * 1.5 + Y / sqrt(pi)

Compound terms are evaluated by first evaluating their arguments and then
calling the corresponding evaluation predicate.
The evaluation predicate associated with a compound term
func(a_1,..,a_n)
is the predicate func/(n+1). It receives
a_1,..,a_n as its first
*n* arguments and returns a numeric result as its last argument.
This result is then used in the arithmetic computation.
For instance, the expression above would be evaluated by the goal sequence

*(3,1.5,T1), sqrt(3.14159,T2), /(Y,T2,T3), +(T1,T3,T4)

where *T1*, *T2* etc. are auxiliary variables created by the system
to hold
intermediate results.

Although this evaluation mechanism is usually transparent to the user, it becomes visible when errors occur, when subgoals are delayed, or when inline-expanded code is traced.

This evaluation mechanism outlined above is not restricted to the predefined arithmetic functions shown in the table. In fact it works for all atoms and compound terms. It is therefore possible to define a new arithmetic operation by just defining an evaluating predicate:

[eclipse 1]: [user]. :- op(200, yf, !). % let's have some syntaxtic sugar !(N, F) :- fac(N, 1, F). fac(0, F0, F) :- !, F=F0. fac(N, F0, F) :- N1 is N-1, F1 is F0*N, fac(N1, F1, F). user compiled traceable 504 bytes in 0.00 seconds yes. [eclipse 2]: X is 23!. % calls !/2 X = 25852016738884976640000 yes.

Note that this mechanism is not only useful for user-defined predicates, but
can also be used to call ECL^{i}PS^{e} built-ins inside arithmetic expressions,
e.g.,

T is cputime - T0. L is string_length("abcde") - 1.

which call cputime/1 and string_length/2 respectively. Any predicate that returns a number as its last argument can be used in a similar manner.

However there is a difference compared to the evaluation of the predefined
arithmetic functions (as listed in the table above):
The arguments of the user-defined arithmetic expression are *not
evaluated* but passed unchanged to the evaluating predicate.
For example, the expression twice(3+4) is transformed into the goal
twice(3+4, Result) rather than twice(7, Result).
This makes sense because otherwise it would not be possible to pass
any compound term to the predicate.
If evaluation is wanted, the user-defined predicate can explicitly call
is/2 or use eval/1.

In order to enable efficient compilation of arithmetic expressions,
ECL^{i}PS^{e} requires that variables in compiled arithmetic expressions
must be bound to numbers at runtime, not symbolic expressions.
For example, in the following code p/1 will only work when called
with a
numerical argument, else it will raise error 24:

p(Number) :- Res is 1 + Number, ...

To make it work even when the argument gets bound to a symbolic expression at runtime, use eval/1 as in the following example:

p(Expr) :- Res is 1 + eval(Expr), ...

If the expression is the only argument of is/2, the eval/1 may be omitted.

- 3
- Caution: In ECL
^{i}PS^{e}versions up to 5.8, mod was the remainder corresponding to //, i.e., behaved like rem