Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Lists and backtracking in Prolog

After this lesson: I can explain how Prolog searches for answers and backtracks to try another.

60 min lesson6 commandsProlog lab: logic programming with facts, rules and questions, in the browser

How does Prolog search and backtrack?

Prolog answers a question by searching. When a choice leads nowhere, it goes back and tries the next one. This is called backtracking.

It matters because backtracking is how Prolog solves puzzles, plans routes and checks rules. In this lesson you watch it work, then list every route through a small bus network.

By the end of this lesson

Note

I can explain how Prolog searches for answers and backtracks to try another.

Key words

WordWhat it meansExample
Listitems in order, in square brackets[a, b, c]
Headthe first item of a list
Tailthe list that is left when the head is taken off
Choice pointa place where more than one fact or rule could be used
Backtrackinggoing back to the last choice point and trying the next option

The cells students fill in are left blank in this preview.

A list has a head and a tail

A list holds items in order, inside square brackets: [a, b, c]. Prolog splits a list into its head, the first item, and its tail, everything else.

The pattern [H|T] matches any list that has at least one item. H becomes the head and T becomes the tail. The empty list [] has neither.

Worked example: splitting lists

ListHeadTail
[a, b, c]a[b, c]
[7]7[]
[]nonenone
[[1, 2], 3][1, 2][3]

The cells students fill in are left blank in this preview.

Split a list into head and tail

Command
docker exec prolog swipl -q -g "[H|T] = [a, b, c], writeln(H), writeln(T)" -t halt

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Every way to cut a list in two

Command
docker exec prolog swipl -q -g "forall(append(X, Y, [1, 2]), (write(X), write(' + '), writeln(Y)))" -t halt

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Prolog goes back when a choice fails

The goal member(X, [4, 8, 15, 16]) means "X is one of these". There are four ways to answer it. Prolog takes the first, 4, and carries on with the rest of the question.

If a later step fails, Prolog goes back to the last choice point and takes the next option. It keeps going until a choice works or the options run out.

Worked example: look for a member above 10

TryX isIs X above 10?What Prolog does
14NoGoes back, takes the next member
28NoGoes back, takes the next member
315YesCarries on and stops with 15

The cells students fill in are left blank in this preview.

Watch the tries happen

Command
docker exec prolog swipl -q -g "member(X, [4, 8, 15, 16]), write(tried(X)), nl, X > 10, writeln(found(X))" -t halt

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Backtracking can list every route on a map

Here is a one-way bus network with five stops. A route is a list of stops from a start to an end, with no stop visited twice.

The rule trip says: the trip from a stop to itself is just that stop. Otherwise take a link, check the next stop is not yet visited, and make a trip from there.

The map file: links and the trip rule

Code: prolog
link(a, b).
link(a, c).
link(b, d).
link(c, d).
link(d, e).

trip(Y, Y, _, [Y]).
trip(X, Y, Seen, [X|Rest]) :-
    link(X, Z),
    \+ member(Z, Seen),
    trip(Z, Y, [Z|Seen], Rest).

Save the map file

Command
docker exec prolog sh -c "printf '%s\n' 'link(a, b).' 'link(a, c).' 'link(b, d).' 'link(c, d).' 'link(d, e).' 'trip(Y, Y, _, [Y]).' 'trip(X, Y, Seen, [X|Rest]) :- link(X, Z), \+ member(Z, Seen), trip(Z, Y, [Z|Seen], Rest).' > map.pl"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Every route from a to e

Command
docker exec prolog swipl -q -g "findall(P, trip(a, e, [a], P), L), writeln(L)" -t halt map.pl

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Every route from e to a

Command
docker exec prolog swipl -q -g "findall(P, trip(e, a, [e], P), L), writeln(L)" -t halt map.pl

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Worked example: the search from a to e

StepAtChoice takenWhat happens
1alink to bRoute so far: a, b
2blink to dRoute so far: a, b, d
3dlink to eReached e. Route one: a, b, d, e
4d, bno other linksGoes back to a
5alink to cThen c, d, e. Route two: a, c, d, e
6ano links leftThe search is finished

The cells students fill in are left blank in this preview.

A common mistake

Warning

Many people think Prolog looks at every route at once. It follows one route at a time, in the order the facts are written. It goes back only when a choice fails or you ask for more. If the map has a loop, a route can circle for ever unless the rule remembers the stops it has seen.

About this lab and its source: Prolog lab: logic programming with facts, rules and questions, in the browser

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.