Warning: A Note on Terminology
3.2 Evaluating Goals
pred3(X,X,man) pred3(london,london,A)
Succeeds with variables X and A bound to atoms london and man, respectively.
This example shows a repeated variable in one of the arguments of a compound term.
pred(alpha,beta,mypred(X,X,Y)) pred(P,Q,mypred(no,yes,maybe)) Fails.
P successfully unifies with alpha. Next Q unifies with beta. Then Prolog attempts to unify the two third arguments, i.e. mypred(X,X,Y) and mypred(no,yes,maybe). The first step is to unify variable X with the atom no.
This succeeds with Xbound to no. Next the two second arguments are compared.
AsX is bound to no, instead of X and yes the second arguments are now no and yes, so the unification fails.
In this example, the second mypred argument is now no rather than yes, so unification succeeds.
pred(alpha,beta,mypred(X,X,Y)) pred(P,Q,mypred(no,no,maybe))
Succeeds with variables P,Q,X and Y bound to atoms alpha,beta,no and maybe, respectively.
Example
In this example, the goal is
?-pred(london,A).
It is assumed that the first clause in the database with predicate pred/2 and a head that unifies with this goal is the following rule, which we will call Rule 1 for ease of reference.
pred(X,'european capital'):-
capital(X,Y),european(Y),write(X),nl.
The unification binds X to the atom london and A to the atom 'european capital'. The binding of X to london affects all occurrences of X in the rule. We can show this diagrammatically as:
?-pred(london,A).
pred(london,'european capital'):-
capital(london,Y),european(Y),write(london),nl.
X is bound to london,A is bound to 'european capital'.
Next Prolog examines the goals in the body of Rule 1 one by one, working from left to right. All of them have to be satisfied in order for the original goal to succeed.
Evaluating each of these goals is carried out in precisely the same way as evaluating the user's original goal. If a goal unifies with the head of a rule, this will involve evaluation of the goals in the body of that rule, and so on.
We will assume that the first clause matched by goal capital(london,Y) is the fact capital(london,england). The first goal in the body of Rule 1 is thus satisfied, with Y bound to the atom england. This binding affects all occurrences of Y in the body of Rule 1, not just the first one, so we now have
?-pred(london,A).
pred(london,'european capital'):-
capital(london,england),european(england),write(london),nl.
capital(london,england).
X is bound to london.A is bound to 'european capital'.Y is bound to england.
It is now necessary to try to satisfy the second goal in the body of Rule 1, which in rewritten form is european(england).
This time we shall assume that the first clause in the database that has a head that unifies with the goal is the rule
european(england):-write('God Save the Queen!'),nl.
We will call this Rule 2.
Prolog now tries to satisfy the goals in the body of Rule 2: write('God Save the Queen!') and nl. It does this successfully, in the process outputting the line of text
God Save the Queen!
as a side effect.
The first two goals in the body of Rule 1 have now been satisfied. There are two more goals, which in rewritten form are write(london) and nl. Both of these succeed, in the process outputting the line of text
london as a side effect.
All the goals in the body of Rule 1 have now succeeded, so the goal that forms its head succeeds, i.e. pred(london,'european capital').
This in turn means that the original goal entered by the user
?-pred(london,A).
succeeds, with A bound to 'european capital'.
The output produced by the Prolog system would be:
?- pred(london,A).
God Save the Queen!
london
A = 'european capital'
We can now see why output from write/1 and nl/0 goals is referred to by the slightly dismissive term 'side effect'. The principal focus of the Prolog system is the evaluation of goals (either entered by the user or in the bodies of rules), by unification with the heads of clauses. Everything else is incidental. Of course, it is frequently the side effects that are of most interest to the user.
This process of satisfying the user's goal creates linkages between the goal, the heads of clauses and the goals in the bodies of rules. Although the process is lengthy to describe, it is usually quite easy to visualise the linkages.
?-pred(london,A).
pred(london,'european capital'):-
capital(london,england),european(england),write(london),nl.
capital(london,england).
european(england):-write('God Save the Queen!'),nl.
X is bound to london.A is bound to 'european capital'. Y is bound to england.
Note that the user's goal
?-pred(london,A).
has been placed to the right in the above diagram. That is because it has much in common with a goal in the body of a rule. A sequence of goals entered by the user at the prompt, for example
?- owns(X,Y),dog(Y),write(X),nl.
is treated in the same way as a sequence of goals in the body of an imaginary rule, say succeed:-owns(X,Y),dog(Y),write(X),nl.
The process of evaluating a goal is summarised (in much simplified form) in the following flowcharts. Note that the flowchart for evaluating a sequence of goals refers to the one for evaluating a (single) goal, and vice versa.
Figure 3.2 Evaluating a Sequence of Goals Yes
Sequence of goals succeeds
Are there No more goals?
Evaluate next goal Fails See Section 3.3 Succeeds
Figure 3.3 Evaluating a Goal
The principal issue that has been left unconsidered in this account is what happens if evaluation of any of the goals fails. If it does, the Prolog system tries to find another way of satisfying the most recently satisfied previous goal. This is known as backtracking and is the topic of the next section. Unification and backtracking together comprise the mechanism that Prolog uses to evaluate all goals, whether entered by the user at the prompt or in the body of a rule.