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
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|]] [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.
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
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.
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
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.
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
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.
- ECLiPSehas integers, floats, rationals and bounded reals.
- Character sequences in double quotes.
- Symbolic constants, usually lower case or in single quotes.
- Lists are constructed from cells that have an arbitrary head and a tail which is again a list.
- Structures have a name and a certain number (arity) of arbitrary arguments. This characteristic is called the functor, and written name/arity.