3.1 Terms and their data types
Prolog data (terms) and programs are built from a small set of
simple data-types. In this section, we introduce these data types
together with their syntax (their textual representations). For the
full syntax see the User Manual appendix on Syntax.
Numbers come in several flavours. The ones that are familiar from
other programming languages are integers and floating point numbers.
Integers in ECLiPSe can be as large as fits into the machine's
memory:
123 0 -27 3492374892749289174
Floating point numbers (represented as IEEE double floats) are written
as
0.0 3.141592653589793 6.02e23 -35e-12 -1.0Inf
ECLiPSe provides two additional numeric types, rationals and
bounded reals. ECLiPSe can do arithmetic with all these numeric
types.
Note that performing arithmetic requires the use of the
is/2 predicate:
?- X is 3 + 4.
X = 7
Yes
If one just uses =/2,
ECLiPSe will simply construct a term corresponding to the
arithmetic expression, and will not evaluate it:
?- X = 3 + 4.
X = 3 + 4
Yes
-
⊙
- For more details on numeric types and arithmetic in general see the
User Manual chapter on Arithmetic.
-
⊙
- For more information on the bounded real numeric type, see
Chapter 9.
Strings are a representation for arbitrary sequences of bytes and are
written with double quotes:
"hello"
"I am a string!"
"string with a newline \n and a null \000 character"
Strings can be constructed and partitioned in various ways using
ECLiPSe primitives.
Atoms are simple symbolic constants, similar to enumeration type
constants in other languages. No special meaning is attached to them
by the language. Syntactically, all words starting with a lower case
letter are atoms, sequences of symbols are atoms, and anything in
single quotes is an atom:
atom quark i486 -*- ??? 'Atom' 'an atom'
A list is an ordered sequence of (any number of) elements, each of
which is itself a term. Lists are delimited by square brackets ([
]), and elements are separated by a comma. Thus, the following are
lists:
[1,2,3]
[london, cardiff, edinburgh, belfast]
["hello", 23, [1,2,3], london]
A special case is the empty list (sometimes called nil), which
is written as
[]
A list is actually composed of head-and-tail pairs, where the head contains one
list element, and the tail is itself a list (possibly the empty list).
Lists can be written as a [Head|Tail] pair, with the head separated from
the tail by the vertical bar. Thus the list [1,2,3] can
be written in any of the following equivalent ways:
[1,2,3]
[1|[2,3]]
[1|[2|[3]]]
[1|[2|[3|[]]]]
The last line shows that the list actually consists of 3 [Head|Tail]
pairs, where the tail of the last pair is the empty list.
The usefulness of this notation is
that the tail can be a variable (introduced below):
[1|Tail], which leaves the tail unspecified for the moment.
3.1.5 Structures
Structures correspond to structs or records in other languages. A
structure is an aggregate of a fixed number of components, called its
arguments. Each argument is itself a term. Moreover, a
structure always has a name (which looks like an atom). The canonical
syntax for structures is
<name>(<arg>1,...<arg>n)
Valid examples of structures are:
date(december, 25, "Christmas")
element(hydrogen, composition(1,0))
flight(london, new_york, 12.05, 17.55)
The number of arguments of a structure is called its arity. The name and arity of a structure are
together called its functor and is often written as name/arity. The last example above therefore has the functor flight/4.
-
⊙
- See section 4.1 for information about defining structures
with named fields.
Operator Syntax
As a syntactic convenience, unary (1-argument) structures can also be written
in prefix or postfix notation, and binary (2-argument) structures can be
written in prefix or infix notation, if the programmer has made an
appropriate declaration (called an operator declaration)
about its functor. For example if plus/2 were declared to
be an infix operator, we could write:
1 plus 100
instead of
plus(1,100)
It is worth keeping in mind that the data term represented by the
two notations is the same, we have just two ways of writing the same thing.
Various logical and arithmetic functors are automatically declared to
allow operator syntax, for example +/2, not/1 etc.
Parentheses
When prefix, infix and postfix notation is used, it is sometimes necessary to
write extra parentheses to make clear what the structure of the written
term is meant to be. For example to write the following nested structure
+(*(3,4), 5)
we can alternatively write
3 * 4 + 5
because the star binds stronger than the plus sign.
But to write the following differently nested structure
*(3, +(4, 5))
in infix-notation, we need extra parentheses:
3 * (4 + 5)
A full table of the predefined prefix, infix and postfix operators
with their relative precedences can be found in the appendix of the
User Manual.
-
Numbers
-
ECLiPSehas integers, floats, rationals and bounded reals.
- Strings
-
Character sequences in double quotes.
- Atoms
-
Symbolic constants, usually lower case or in single quotes.
- Lists
-
Lists are constructed from cells that have an arbitrary head and
a tail which is again a list.
- Structures
-
Structures have a name and a certain number (arity) of arbitrary arguments.
This characteristic is called the functor, and written name/arity.
|
Figure 3.1: Summary of Data Types