Symbols
in Prolog:
atom
variable
number
list
(how to
assembly
and
take them apart
)
Lists are very
powerful
in prolog because we do not need to do similar but
repeated
tasks again and again. Instead, we can put all elements in a list and deal with them in a more general way.
If we have a look at the
difference
between
lists
in prolog and
arrays
in C, it is easy to notice that we
do not need to define the length of a list in prolog
. Instead, we use a
recursive
way to deal with them one by one until the remaining is empty.
How to
write
a list:
use
commas
to separate every element:
[A, B]
use
vertical bars
to divide head and tail:
[A | B]
The two definitions are quite
different
.
When using
[A, B]
, the list has
only 2
element A and B.
When using
[A | B]
, the list can have
at least 1
elements because B is a list and it can be empty or very large.
How to
operate
on a list:
Define a
stop condition
for the recursion;
Deal with lists
recursively
(always divide the list by head and tail)
decreasing the length
of it.
Examples:
example 1: members in a list
elem(A, [A | _]).
elem(A, [_ | B]) :- elem(A, B).
If we use the following instead, it will only hold when A is the tail of the list.
elem(A, [A]).
elem(A, [_ | B]) :- elem(A, B).
example 2: list of unique people
uniq([ ]).
uniq([H | T]) :- people(H), \+ member(H, T), uniq(T).
example 3: joining two lists
join([ ], T, T).
join([H | T], L, [H | W]) :- join(T, L, W).
We can learn from these examples that we use [H | T] to take the lists into head and tail decreasing the length of it to solve our problem.
Using
append
predicate
append predicate is powerful is because it can
analyze the structure of a list
.
Notice that the
parameter
of append predicate
must be lists or variables
not atoms.
append([a, b], [c, d], L).
L=[a, b, c, d].
Examples:
L1 is start of L2:
front(L1, L2) :- append(L1, _, L2).
E is last element of L:
last(E, L) :- append(_,
[E]
, L).
another version of member predicate:
mem(A, B) :- append(_, [A | _], B).
X is before Y in L:
before(X, Y, L) :- append(Z, [Y | _], L), append(_, [X | _], Z).