eats(fred,pears).
eats(fred,t_bone_steak).
eats(fred,apples).
So far we have only been able to ask if fred eats specific things. Suppose
that I wish to instead answer the question, "What are all the things that
fred eats". To answer this I can use variables again. Thus I can type in
the query
?- eats(fred,FoodItem).
As we have seen earlier, Prolog will answer with
FoodItem = pears
This is because it has found the first clause in the database. At this
point Prolog allows us to ask if there are other possible solutions. When
we do so we get the following.
FoodItem = t_bone_steak
if I ask for another solution, Prolog will then give us.
FoodItem = apples
If we ask for further solutions, Prolog will answer no, since there are
only three ways to prove fred eats something. The mechanism for finding
multiple solution is called backtracking. This is an essential mechanism
in Prolog and we shall see more of it later.
birthday(fred).
birthday(helen).
happy(mary).
happy(jane).
happy(helen).
If we now pose the query
?- hold_party(Who).
In order to solve the above, Prolog first attempts to find a clause of
birthday, it being the first subgoal of birthday. This binds X to tom. We
then attempt the goal happy(tom). This will fail, since it doesn't match
the above database. As a result, Prolog backtracks. This means that
Prolog goes back to its last choice point and sees if there is an
alternative solution. In this case, this means going back and attempting
to find another clause of birthday. This time we can use clause two,
binding X to fred. This then causes us to try the goal happy(fred). Again
this will fail to match our database. As a result, we backtrack again.
This time we find clause three of birthday, and bind X to helen, and
attempt the goal happy(helen). This goal matches against clause 3 of our
happy database. As a result, hold_party will succeed with X=helen.
fun(X) :- /* something is either fun because its .... */
red(X), /* red */
car(X). /* and a car */
fun(X) :- /* or its fun if its.... */
blue(X), /* blue */
bike(X). /* and a bike */
/* database of red items */
red(apple_1).
red(block_1).
red(car_27).
/* database of cars */
car(desoto_48).
car(edsel_57).
This program says that red cars or blue bikes are fun. It then goes on to
name some examples of each type of object.
?- fun(What).
We first attempt to prove something is fun. To do this we have two clauses
of fun that we can use
/* clause 1 */
fun(X) :-
red(X),
car(X).
/* clause 2 */
fun(X) :-
blue(X),
bike(X).
Using the first clause, we can now look to see if we can find some red
object
/* database of red items */
red(apple_1). first choice
red(block_1).
red(car_27).
The first red item that we find is apple_1. This gives us the
instantiation X=apple_1. Next we have to see if this is a car, so we
ask the question car(apple_1). Does this match with our existing
database of facts about cars?
/* database of cars */
car(desoto_48).
car(edsel_57).
The answers is that it will not. apple_1 will not match with desoto_48 or
with edsel_57. So what do we do next? In such cases, Prolog backtracks in
order to find another solution. Thus we go back to the red database, and
see if we can find another possible solution. In this case we can
red(apple_1).
red(block_1). second choice
red(car_27).
We can use the next clause and see if block_1 is a red car.
red(apple_1).
red(block_1).
red(car_27). third choice
We now attempt the car goal again, but this time for car_27. Now
recall what we said earlier about the dangers of over estimating the
powers of Prolog. Prolog will try to match the goal car(car_27)
against the database
car(desoto_48).
car(edsel_57).
This will fail. car_27 does not match with either desoto_48 or
edsel_57. Although the programmer probably meant car_27 to mean car
number 27 to be a car, Prolog has no way of gleaning this intended
semantics, and fails the call based on a simple pattern match. Well, what do we do now. The first step is to go back and see if there are any more possible red items. Well we have now exhausted all three choices, hence there are no more red items to choose from. Given that there are no more possible ways that we could satisfy clause 1, we now more on to clause 2, as we see on the next card.
fun(X) :- we've tried this clause but without luck
red(X),
car(X).
/* clause 2 */
fun(X) :- so lets have a go with this clause now
blue(X),
bike(X).
Thus we will now try to prove that something is fun, by trying to find
something that is blue, using the blue database:
/* clause 1 */
blue(flower_3).
blue(glass_9).
blue(honda_81).
In this case we now choose blue(flower_3)
/* database of blue items */
bike(my_bike).
bike(honda_81).
This again must fail, since flower_3 does not match against iris_8,
my_bike, or honda_81. So as before, we must backtrack and find an
alternate blue item. Recall our database:
bike(iris_8).
blue(flower_3).
blue(glass_9).
blue(honda_81).
We have tried flower_3 without luck, so next we try the second blue fact,
blue(glass_9). We now try goal bike(glass_9). Again this fails to unify.
As a result we must go back yet again and find another blue object. This
time we will use the third clause of blue, blue(honda_81). We will now
give us the goal bike(honda_81). This matches clause three!. So at last
we have found something which is blue and a bike. As a result we can now
conclude that it is fun, Prolog then displays the following:
?- fun(What).
What=honda_81
yes
fun(X) :- /* fun if .... */
red(X), /* red */
car(X). /* and a car */
fun(X) :- /* or its fun if its.... */
blue(X), /* blue */
bike(X). /* and a bike */
Below you will see pairs of goals. These may either be output of a goal e.g. red(my_hat) or calls to another goal e.g. car(my_hat).
Indicate which of the following goals you you would expect to see first, for the above query, by checking the button beside it:
/* database of red & blue items */
red(cricket_ball). blue(cheese).
red(my_hat). blue(raleigh).
red(car_27). blue(honda).
/* database of cars and bikes*/
car(peugot). bike(yamaha).
car(rover). bike(raleigh).
bike(honda).
Exercise 7
Consider the following program.
a(X):-
b(X), c(X), d(X).
a(X):-
c(X), d(X).
a(X):-
d(X).
b(1).
b(a).
b(2).
b(3).
d(10).
d(11).
c(3).
c(4).
Given the query ?- a(X). Indicate in the box below the successive
variable bindings that the variable X gets when the above query is run, and all solutions are asked for (by using ;).
NB you should list even those bindings which do not lead to overall success, and you should list each answer even if it occurs more than once.Separate bindings by a comma (ie. 1,3,5.....)