EXERCISE SHEET 1

{The idea with these exercises is that you look at what you're
supposed to type, and see if you can guess what the result will be.
Then you try it out and discover whether you were correct or not! My
comments are in curly brackets, {like this}, and what you're expected
to type is not, and is indented so you can see it easily.}

{This series of exercises revolves around a family tree.  A file which
contains the program is available in the same page where this exercise
is located. So you don't have to type in yourself. The program is a
plain text file that can be open using any known text editor. To run
Prolog, open a shell, go to the command line, and just type:}

	yap

Alternatively, you can use SWISH (a web-based browser for Prolog
programming, based on the SWI-Prolog).

{After some uninteresting information, you'll get the ?- prompt. You
can now make Prolog read in the TREE file by typing:}

	[tree].

{The '[' and ']' are important, the '.' is VERY important, miss it out of
any of these examples and Prolog will wait patiently until you type it...
OK, now for a few easy exercises. Looking at the program listing, what
will happen if you type the following queries:}

	female(helen).

	husband(william, violet).

	husband(violet, william).

	father(paul, robert).

	female(oscar).

	female(kevin).

	femail(elaine).

{Yes, that last one was a deliberate msspelling... In the next batch,
answer all the 'X = blah' sort of results with a ';' (followed by a
return) so you get all the answers. Don't put the quotes round the
semi-colon, please...  Also, don't worry if you were expecting 'X =
blah Y = blahblah' and get 'Y = blahblah X = blah' instead; what's
important is that X and Y are instantiated to the correct things - the
order they're reported in a particular answer doesn't really matter.}

	father(ian, X).

	father(X, ursula).

	father(arthur, X).

	father(X, Y), female(Y).

	father(william, X) ; father(john, X).

	father(arthur, Y) ; husband(Y, glenda).

	father(X, Y), father(Y, Z).

	father(Y, Z), father(X, Y).

{This next bit means you have to type in a couple of relations
yourself. The square brackets notation is used to read in files,
'[user]' being the special case of reading from the keyboard. The ^D
at the end is a control-D, obtained by holding the control key down
and hitting the D. Notice that the prompt changes while you're typing
in the clauses.  The '\+' means 'not'.  The '\+' function succeeds if
it cannot find a match in the database, and fails if it can.}

	[user].
	wife(X, Y):- husband(Y, X).
	male(X):- \+ female(X).
	^D

{It'll then say some rubbish about consulting user, and come up with
the ?- prompt again (unless you made a typing mistake...). OK, now you
can try these new functions out.}

	wife(violet, X).

	wife(ursula, X).

	wife(paul, linda).

	wife(linda).

	male(tom).

	male(carol).

	male(H).

	male(catapult).

{Those last 2 may surprise you! Now for some more clauses, this time
I'm not actually going to tell you what they do, you're supposed to
guess... The '\==' operator means 'not equal to'.}

	[user].
	p(X, Y):- father(X, Y).
	p(X, Y):- father(F, Y), husband(F, X).
	c(X, Y):- p(P, X), father(F, P), father(F, C), C \== P, p(C, Y).
	^D

{To test these out, you might like to try the following:}

	p(X, david).

	p(katherine, K).

	c(ursula, C).

	c(linda, X).

	c(X, linda).

	c(oscar, X) ; p(Y, oscar).

{Using any of the functions defined so far (which will always be
assumed in these exercises) define for yourself the two functions
'grandfather' and 'aunt'. To make it easy, I'll give you the
definitions in English: G is the grandfather of M if P is the parent
of M and G is the father of P; A is the aunt of M if P is the parent
of M, F is the father of P, F is the father of A, A and P are not the
same, and A is female. Once you've defined the relations, try them out
on the following:}

	g(john, P).

{You should get P = oscar; P = linda; P = malcolm.}

	g(X, linda).

{You should get X = arthur; X = john.}

	aunt(X, violet).

{You'll should only find X = elaine.}

	aunt(X, malcolm).

{X = carol; X = elaine; X = helen. That should be enough of that! Here's
another couple of relations, sister and brother (you could actually write
them better yourself if you used a relation 'sibling', ie. someone who is
either your sister or your brother).}

	[user].
	sister(S, M):- father(F, M), father(F, S), S \== M, female(S).
	brother(B, M):- father(F, M), father(F, B), B \== M, male(B).
	^D

	sister(carol, S).

	brother(B, robert).

{Use these to write your own function 'bil', for brother-in-law. There are
three ways someone can be your brother-in-law: they're your sister's
husband; they're your wife's brother; they're your husband's brother. Once
you have defined them, try out:}

	bil(B, frank).

{You should get frank's brothers-in-law as being stephen and ian. Now for
another mystery function: what does 'd' do here?}

	[user].
	d(M,D):- p(M,D).
	d(M,D):- p(M,X),d(X,D).
	^D

{Try it on:}

	d(glenda,X).

	d(X,xavier).

{The hardest part is deciding for yourself the order in which the
instantiations for X come. Look at the listing closely! Once you have
figured out what it does, write a not-too-dissimilar function of your
own, 'top', where T is the top of M if T is M's parent and T has no
parents, or if Z is M's parent and T is the top of Z. You can then try
it out on

	top(X, linda).

{See if you get all four.}

{That's the end of this exercise sheet, if you managed this far then
get someone close by to pat you on the back.}

