Basic syntax
Lists in prolog are treated as having two parts: the head, or front, element of the list
and the tail of the list, which is a list of all the remaining elements (i.e. not including
the head element).
Lists can be described in one of two ways,
[10, -1, 8, 20]
[ HeadElem | TailList ]
[ 3, 'foo', [ x, [ y ] ], 17 ]
Unification and Lists
If we try and unify two lists, or a list with a variable, the prolog
engine will attempt to unify the list components appropriately. For example
[ X | Y ] = [ 1, 2, 3] % unifies X with 1 and Y with [2, 3]
[ X, Y ] = [ 1, 2, 3] % fails since we have only 2 elements on the LHS
Remember that such unifications are taking place "behind the scenes"
when we attempt queries such
as foo(A).
and the fact/rule database includes items such as
foo([X,Y]).
List functions
Some of the built-in list functions include:
list(List), length(List,Length), min_list(List, Elem),
max_list(List, Elem), append(List1, List2, Result), member(Elem,List),
delete(List, Elem, Result), last(List,Elem),
reverse(List, Result), permutation(List, PermutedList),
nth0(Position, List, Elem), length(List, Size), sort(List, Result)
Recursive operations
As with most aspects of prolog, recursive manipulation of lists is commonplace.
Consider the example below, which tests if an element is a member of a list.
% member(X, L) is supposed to succeed if X is an element of list L % if X matches the front element of a list then X is in the list % (note that we don't care what the rest of the list looks like) member(X, [X | _]). % if we get here, we know X didn't match the head element, so we'll % ignore the head element and see if X matches something in the tail member(X, [_|Tail]) :- member(X, Tail).
This is most commonly done with lists, but there are certainly other options.
The example below shows a representation of objects in a three-dimensional space, representing things using their X, Y, Z coordinates.
% a point is represented by a list of 3 numbers, the X, Y, and Z coordinates point([ X, Y, Z ]) :- number(X), number(Y), number(Z). % a line is represented by a list of 2 distinct points line([ Point1, Point2 ]) :- point(Point1), point(Point2), Point1 \= Point2. % a plane is represented by a list of 3 distinct points plane([ Point1, Point2, Point3 ]) :- point(Point1), point(Point2), point(Point3), Point1 \= Point2, Point1 \= Point2, Point2 \= Point3.
Note that at the user level this allows us to think of components in appropriate
abstract terms, such as plane(P)
, rather than thinking explicitly
about the underlying representation, which may be something like
[ [1, 2], [17, 0], [-3, -99] ]
.