Queries with Variables

To ask, "Who are the parents of Brian?", enter the query:

 ?- parent(X, brian).

Here, X, is a variable which stands for an object which the questioner does not know about yet. Remember, the name of a variable must begin with a capital letter or an underscore character, "_".

Prolog replies with:

X = jim ;
X = pat.

This is a listing of all values of X where the goal can be proven.

If you make the mistake of not using a capital letter, then Prolog will treat it as a constant. Try this to see:

?- parent(x, brian).

This is an occasional source of errors in submitted assignments :-(

You may also make the mistake of capitalising an intended constant. Try this to see:

?- parent(albert, Brian).
Brian = jim ;
Brian = Peter.

Here, Brian is a variable and there are two solutions to the query. Work out (in your head, or on paper) what Prolog should respond with when given the query:

 ?- parent(Albert, Brian).

then run the query to check your answer.

The special variable, _, can be used when the value of the variable is not important. Values bound to the variable are not printed, and different appearances of _ are treated as separate variables. Try the following.

Is Albert a parent...

?- parent(albert, _).

Who are the parents...

?- parent(Parent, _).

What does this one mean?

?- parent(_, _).

Recall from lectures that each _ variable is treated as a distinct variable. Try the query

?- parent(irene, _), parent(_, brian).

Press the ";" key each time Prolog stops after printing a response. You should see 4 true responses and then false. This means that Prolog has found four ways to satisfy the query, because the two _ variables are treated as distinct. No variable bindings are printed because bindings of _ variables are not reported by Prolog. Thus the query above is similar to:

?- parent(irene, X), parent(Y, brian).

which gives 4 solutions (try it) - except that the bindings are reported in this X, Y version of the query.

If we had instead done the query

?- parent(irene, X), parent(X, brian).

we would get a single answer:

X = jim ;
false.

Sometimes the order of the terms makes a difference. Try these two queries:

?- parent(pat, X), parent(pat, Y), X \= Y.
?- X \= Y, parent(pat, X), parent(pat, Y).

One of them succeeds but not the other. There are too many possible values of X and Y for which X is not equal to Y. Earlier versions of Prolog would get stuck in an infinite loop testing all the options. The current version of SWI-Prolog avoids the infinite loop, but in doing so it refuses to process the query and therefore fails to find any answer.

Conjunctions

We now ask, "Is Irene a grandparent of Brian?" This can be answered by finding out if Irene is the parent of someone who is the parent of Brian. Enter the following query to ask that question:

 ?- parent(irene, P), parent(P, brian).

The variable, P, represents that "someone" who is Brian's parent and Irene's child. Prolog will show all values for P, where the query is true.

Find all the grandchildren of Irene using the following query:

?- parent(irene, Child), parent(Child, GrandChild).
 Child = jim
 GrandChild = Brian ;
 Child = peter
 GrandChild = lee ;
 Child = peter
 GrandChild = sandra ;
 Child = peter
 GrandChild = James ;
 Child = peter
 GrandChild = Kate ;
 Child = peter
 GrandChild = Kyle .

The response shows there are six sets of values where the query is true. The six grandchildren are Brian, Lee, Sandra, James, Kate and Kyle.

Rules

The previous question can be restated (in English) as a general rule:

One person, Grandparent, is the grandparent of another person, Grandchild, if:
    Grandparent is the parent of Child, and
    Child is the parent of Grandchild.

In Prolog this rule is written as:

grandparent(Grandparent, Grandchild) :-
    parent(Grandparent, Child),
    parent(Child, Grandchild).

Use your preferred text editor in another window (e.g. emacs or vi) to append the rule to the family.pl file. Don't forget to save your changes.

Have Prolog read the modified family.pl using:

 ?- consult(family).

The consult command will force Prolog to re-read the family.pl file; it automatically supplies the ".pl". Prolog will now be aware of the changes you have made to the file, and in fact it issues warnings for each Prolog procedure that you have redefined by consulting "family.pl", just to sure you know which procedures (may) have changed.

Try the new rule to ask who are the grandchildren of Irene.

 ?- grandparent(irene, Who).

Use the family tree you drew to confirm the result. If the result is not what you expected, then check your program for typing mistakes.

Try the new rule to ask who are the grandparents of Jenny.

 ?- grandparent(Who, jenny).

Now add the following rule to family.pl and re-consult:

% older(Person1, Person2) :- Person1 is older than Person2

older(Person1, Person2) :-
    yearOfBirth(Person1, Year1),
    yearOfBirth(Person2, Year2),
    Year2 > Year1.

The first two lines are comments which serve as documentation for the new rule.

Also note the use of the built-in predicate ">".

The new rule, older, tests whether one person is older than another. Test this new rule by asking who is older than Pat and then who is younger than Darren.

Advanced Exercise

If you found all of the above too easy, try the following. In the family.plprogram, add a rule, siblings(Child1, Child2), to return whether two people are brothers or sisters (i.e. they share a common parent). Then add a rule, olderBrother(Brother, Person), to return whether Brother is an older brother of Person.

 ?- siblings(sandra, X).
 X = lee ;
 X = james ;
 X = kate ;
 X = kyle.

 ?- olderBrother(Brother, sandra).
 Brother = james ;
 false.

Note that siblings should not report Sandra being her own sibling. You may need to read the text book (Bratko) to find out how to do this. The issue deals with equality (or inequality) of two terms. Prolog has several notions of equality which are covered in the text book.

How does your program work when siblings share more than one parent? For example:

 ?- siblings(jim, X).

Why does this happen? You should be able to explain the reason for this perhaps unexpected result at some point, but you do not need to solve it at this stage.

Resource created Saturday 06 February 2021, 09:11:00 PM.


Back to top

COMP3411/COMP9814 21T1 (Artificial Intelligence) is powered by WebCMS3
CRICOS Provider No. 00098G