Informally, one of the two types in CLP( ) is given by the real numbers,
and the other by the remaining ground (variable-free) terms.
Strictly speaking, CLP(
) is a statically typed language in the sense
that variables, uninterpreted functors and predicates in a program
must be used in a consistent way with respect to their type.
That is, each variable and each argument of
every predicate and uninterpreted functor
is first acknowledged to be of a certain type.
The program is then considered to be ill-typed if, for example,
a variable appears both in a functor constraint and an arithmetic
constraint; similarly, the program is ill-typed
if one occurrence of a predicate or uninterpreted functor
has a number in the first argument while, in another occurrence,
it has a functor term in the first argument.
For programming convenience, however, CLP( ) does not perform
such type-checking at compile time. This decision is based on
the fact that it is often useful to overload a symbol; for example,
one may want a database p of both numbers and letters:
p(2).
p(a).
p(b).
p(1).
and one may run a goal containing p(X) and some
constraints used for selection within the database.
Note that by not performing type-checking, one can have a
runtime type error. That is, an execution sequence which
fails because of a ``type clash''.
Often such failures indicate that there is an error in the program.
The CLP( ) system will not distinguish such failures from failures obtained
from well-typed constraints.
A straightforward way of thinking about the type issue when
writing CLP( ) programs is that whenever an arithmetic term
appears in a rule, for each variable X therein,
we can implicitly add a corresponding atom real(X)
to the body of the rule.
The system predicate real/1 is true just in case
there is a real solution for X in the context of the current
collection of constraints.