Homework 5

Playing with Prolog


Due: Friday, October 27th


Introduction

In this homework you will first walk through a simple tutorial for using Prolog.  Second, you will create a simple knowledge base in Prolog and ask it to prove some simple facts.

 

 

Instructions

To complete this activity, you will need to download SWI-prolog on to your machine.

.

 

Typing in a Prolog program

Firstly, we want to type in a Prolog program and save it in a file, so, using a basic text editor such as Notepad++ or wordpad
type in the following program:



Try to get this exactly as it is

Once you have typed this in, save it as intro.pl  (Prolog files usually end with ".pl", just as Java files end with ".java" and python end with ".py")

 

Starting Prolog

If you are using SWI-Prolog launch the program. If you are using a command prompt type 'prolog'  Either way, you should get something like the following on screen:

Prolog is now running and waiting for you to type in some commands.

 

 

Loading the Program

Writing programs in Prolog is a cycle involving

1.    Write/Edit the program in a text-editor
2.    Save the program in the text editor
3.    Tell Prolog to read in the program
4.    If Prolog gives you errors, go back to step 1 and fix them
5.    Test it - if it doesn't do what you expected, go back to step 1

We've done the first two of these, so now we need to load the program into Prolog.  The program has been saved as "intro.pl", so in your prolog window select File -> Consult, and then load intro.pl wherever you just saved it. This tells Prolog to read in the file called intro.pl - you should do this every time you  change your program in the text editor.

(Note, you can also do this by simply double clicking the intro.pl file. This will relaunch prolog with this "knowledge base" loaded.)

 

Running a query

We can now ask Prolog about some of the information it has just read in.  Type in the following (and don't forget the full-stop at the end: Prolog won't do anything until it sees a full-stop)...

?      likes(mary,food).

When you do this you should get

At this point you should hit the semicolon key.  This tells the computer you wish to see any additional facts pertaining to your query.  Since there aren't any, it quits and returns "false."  Indicating that there is no more information to report..

Repeat this process for each of the following.  What do you observe for each?

?      likes(john,chess).
?      likes(john,food).

 

Notice that predicates and objects in Prolog are both done in lowercase letters.  For objects, this is the opposite of what we were to do in Predicate Logic.  Unfortunately, the opposite is also true for variables.  Variables must begin with capital letters in prolog.  Type in the following.  Remember to hit the ; key after each response until you see no more responses.


?      likes(john,What).
?      likes(mary,What).
?      likes(Who,food).
?      likes(Who,wine).

 

Next, we are going to edit our knowledge base again so we need to quit prolog.  To do this type:

?  halt.

(Of course, you can also just quit SWI-Prolog)

 

The Rules

The program we wrote in the last tutorial was a fairly small one containing few facts.  Thus, it doesn't make much sense to add very many rules, but to get you started consider the following:

?     John likes anything that Mary likes

 

In predicate logic this would read:

likes(Mary,something) ⇒ likes(John,something).

In prolog we write this:

likes(john,X) :-  likes(mary,X).

 

Notice three things that will mess you up with prolog. 

  1. The implication symbol is :-
  2. We reverse the antecedent and the consequent.  The consequent always comes first in prolog.
  3. The capitalization is also "backwards."  Objects start with lowercase and variables start with upper case.
     

 

Add this rule you your knowledge base using your text editor.  Test the impact of this rule by reloading and resubmitting the following queries against it:

?      likes(john,What).
?      likes(mary,What).
?      likes(Who,food).
?      likes(Who,wine).
 

 

Let's try one more idea.  Let's say that two people like each other if they share the same hobby.  That is:

likes(P1,P2) :-
    hobby(P1,H),
    hobby(P2,H).

I did two things differently here.  First, I took the rule and divided it out over several lines for ease of reading.  Prolog has no problems with this.  It knows that as long as it hasn't seen the period yet that the rule isn't over.  The second is that this rule has two parts to the antecedent (remember, that we are backwards from what we are use to and those are things to the "right" of the implication symbol) that are conjoined together.  In prolog the conjunction symbol (AND) is a comma.

hobby(john,cooking).
hobby(john,games).
hobby(tim,cooking).
hobby(helen,games).
 

You might be tempted to put the simple predicates from hobby up at the top with the predicates from likes, but if you don't do this correctly prolog will complain.  Prolog wants you to keep all similar rules together.  Thus, we have to have it look like it appears below:

 

Now reload prolog, reload this file [intro]. and then make the query:

likes(john,What).

 

The first couple probably make sense, but in the middle you suddenly see that john likes himself (and more than once). 

 

Where does that come from?  This is a little bit funny at first, but look at our rule again.  It says that P1 likes P2 whenever we can find a rule that says P1 likes a certain hobby and that P2 likes the same hobby.  The problem is, prolog starts binding variables to known rules and eventually discovers that hobby(john,cooking) means P1 = john and H= cooking.  But then hobby(john,cooking) can also mean P2= john and H=cooking.  Thus, likes(P1,P2) yields likes(john,john).  Prolog isn't "smart enough" (this isn't really a sense of dumb, but a design feature in prolog)  to recognize that maybe it shouldn't allow that.  Instead we have to be explicit here.  We need to let prolog know that P1 shouldn't be the same as P2.  We do this by adding one more line to the likes/hobby rule:

Resave this, rerun prolog and reload intro and you should get much better results.

 

 

 

The Family Tree Example

Suppose that we want to represent a family tree, so that we can ask questions like "is john related to ...", or "list all john's sisters" and so on.

The basic entities will be people; the properties we will want to look at will be father, mother, brother, sister, ..... We choose three basic predicates, male, female and parentOf, which will describe a family by a series of facts.

Take the following family tree as an example:

                              James I
                                 |                                  |                 +----------------+-----------------+                 |                                  |              Charles I                          Elizabeth                 |                                  |                 |                                  |      +----------+------------+                     |      |          |            |                     |  Catherine   Charles II   James II               Sophia                                                    |                                                    |                                                    |                                                 George I


In Prolog we represent this family tree by stating 8 facts regarding gender (one for each of the 8 people in the family tree) and 7 facts regarding parents.  Using what you have learned, add these 15 facts to a new file in your text editor (call it "family.pl").


We can now formulate some queries (try entering these yourself):
?     Was George I the parent of Charles I? 
Query: parentOf(george1,charles1).
  ?     Who was Charles I's parent?
Query: parentOf(X,charles1).
  ?     Who were the children of Charles I?
Query: parentOf(charles1,X).
 

In order to test your knowledge base, submit these queries, and observe if the correct answers come out.

Have at it...

Add  the following rules to the program, and check the results:
?     M is the mother of X if she is a parent of X and is female
?     F is the father of X if he is a parent of X and is male
?     X is a sibling of Y if they both have the same parent.

Remember that "and" in Prolog is represented using a comma.
 

In addition to the above rules, consider the following six relationships.  Add rules for these to your knowledge base.

With each of these you should use some concept of "code reuse."  That is, don't write rules that are long and complicated when you can make them less long/complicated -- use other rules you have written.

Submitting Your Work

Prior to the deadline, use the homework submission system

 to upload :

 

ALSO, please include a printout of family.pl in class. Make sure it has your name on it somewhere.