next up previous index
Next: Low Level Arithmetic Builtins Up: Arithmetic Evaluation Previous: Numeric Types and Type   Index

Subsections


Arithmetic Functions


Predefined Arithmetic Functions

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

Function       Description                       Argument Types      Result
------------------------------------------------------------------------------
+ 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

E1 + E2        addition                          number x number     number
E1 - E2        subtraction                       number x number     number
E1 * E2        multiplication                    number x number     number
E1 / E2        division                          number x number     see below
E1 // E2       integer division                  integer x integer   integer
E1 mod E2      modulus operation                 integer x integer   integer
E1 ^ E2        power operation                   number x number     number
min(E1,E2)     minimum of 2 values               number x number     number
max(E1,E2)     maximum of 2 values               number x number     number

\ E            bitwise complement                integer             integer
E1 /\ E2       bitwise conjunction               integer x integer   integer
E1 \/ E2       bitwise disjunction               integer x integer   integer
xor(E1,E2)     bitwise exclusive disjunction     integer x integer   integer
E1 >> E2       shift E1 right by E2 bits         integer x integer   integer
E1 << E2       shift E1 left by E2 bits          integer x integer   integer
setbit(E1,E2)  set bit E2 in E1                  integer x integer   integer
clrbit(E1,E2)  clear bit E2 in E1                integer x integer   integer
getbit(E1,E2)  get of bit E2 in E1               integer x integer   integer

sin(E)         trigonometric function            number              float
cos(E)         trigonometric function            number              float
tan(E)         trigonometric function            number              float
asin(E)        trigonometric function            number              float
acos(E)        trigonometric function            number              float
atan(E)        trigonometric function            number              float
exp(E)         exponential function e^x          number              float
ln(E)          natural logarithm                 number              float
sqrt(E)        square root                       number              float
pi             the constant pi = 3.1415926...    ---                 float
e              the constant e = 2.7182818...     ---                 float

fix(E)         convert to integer (truncate)     number              integer
float(E)       convert to float                  number              float
rational(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
breal(E)       convert to bounded real           number              breal
breal_from_bounds(Lo, Hi)
               make bounded real from bounds     float x float       breal
breal_min(E)   lower bound of bounded real       breal               float
breal_max(E)   upper bound of bounded real       breal               float

sum(L)         sum of list elements              list                number
min(L)         minimum of list elements          list                number
max(L)         maximum of list elements          list                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. 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 relation between integer division // and modulus operation mod is as follows:

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


Evaluation Mechanism

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 Ti 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.


User Defined Arithmetic Functions

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 ECLiPSe built-ins inside arithmetic expressions, eg.
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. E.g. 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.

Runtime Expressions

In order to enable efficient compilation of arithmetic expressions, ECLiPSe requires that variables in compiled arithmetic expressions must be bound to numbers at runtime, not symbolic expressions. E.g. 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.


next up previous index
Next: Low Level Arithmetic Builtins Up: Arithmetic Evaluation Previous: Numeric Types and Type   Index
Warwick Harvey
2004-08-07