3203. Introduction to Artificial Intelligence

Prolog (2)


1. Lists

List is a very useful data structure in Prolog. A list is a sequence of arguments written within a pair of square brackets. An argument can be a constant, a variable, or a list.

Examples of lists: [a, b, c], [biking, swimming], [X, a, mary], [], [1, [2, 3], Y].

Prolog uses a "bar operator" to indicate "the rest of the list". In list [X | Y], X indicates the first element of the list, and Y indicates the rest of the list (which is a list itself).

After defining the following facts in file "my_lists.pl":

my_lists([a, b, c]).
my_lists([biking, swimming]).
my_lists([X, a, mary]).
my_lists([1, [2, 3], Y]).
we get the following running log:
?- my_lists([X|Y]).
X = a,
Y = [b, c] ;
X = biking,
Y = [swimming] ;
Y = [a, mary] ;
X = 1,
Y = [[2, 3], _G3068].
An identifier proceeded by a "_" represents an internal variable. When a query variable is unified with an internal variable, some implementations (like the current SWI-Prolog) does not report it. Otherwise we may see a
X = _G1234
Y = [a, mary]


2. List processing

In Prolog, a predicate on list is usually defined recursively, that is, by reducing the relation to another one on a shorter list, until a boundary situation, where the relation is specified directly.

The following is a typical Prolog program:

/* member(X, Y) is true iff X is an element of list Y. */

member(X, [X | _]).
member(X, [_ | T]) :- member(X, T).
In the program "_" is an anonymous variable.

A more powerful program:

/* append(X, Y, Z) is true iff list Z equals X and Y appended together */

append([ ], L, L).
append([H | T], L, [H | R]) :- append(T, L, R).
Both predicates are already implemented in SWI-Prolog, so they can be directly called from any Prolog program.

Different ways to use the predicates:

?- member(a, [b, c, a, d]).
true ;

?- member(a, [a, b, a, c]).
true ;
true ;

?- member(X, [a, b, a, c]).
X = a ;
X = b ;
X = a ;
X = c.

?- append([a, b], [c, d], [a, b, c, d]).

?- append([a, b], [c, d], [a, b, c]).

?- append([a, b], [c, d, e], X).
X = [a, b, c, d, e].

?- append([b], X, [a, b, c, d]).

?- append(X, [c], [a, b, c]).
X = [a, b] ;

?- append(X, Y, [a, b]).
X = [],
Y = [a, b] ;
X = [a],
Y = [b] ;
X = [a, b],
Y = [] ;
Other implementations may be slightly different, such as in the first two queries usually a single answer is provided.

Compared with procedural programming language, a Prolog program often implements more than one functions, because it allows the input/output distinction among arguments to be determined at query time.