CS440 Fall 2001
Assignment 4

Due 5:00 PM, Tuesday, Dec. 4th
Department of Computer Science
Link
 to Colorado State University Home 
 Page


Prolog

The purpose of this assignment is to show you how to interact with our Prolog environment, xsb, and to get a little experience in writing Prolog programs.

Starting and Initializing Prolog

First, download the file initprolog.P to your working directory. This file defines a vi and an emacs relation. Think of these as commands for editting a file. Upon exiting from the editting session, the file is consulted (meaning the definitions are compiled and loaded into Prolog). Then, on any of Solaris machines type xsb and load the editting relations. Here's what you should see:

-> xsb
[xsb_configuration loaded]
[sysinitrc loaded]
[packaging loaded]

XSB Version 2.2 (Tsingtao) of April 20, 2000
[sparc-sun-solaris2.8; mode: optimal; engine: chat; scheduling: batched]
| ?- [initprolog].
[Compiling ./initprolog]
[initprolog compiled, cpu time used: 0.0500 seconds]
[initprolog loaded]

yes
| ?- 
This compiles the initprolog.P file, producing initprolog.O. The next time you load this file, you will only see
| ?- [initprolog].
[initprolog loaded]

yes
| ?- 
because the file was already compiled.

Editting Files from within Prolog

This is the contents of the initprolog.P file:

append([],L,L).

append([X|L1],L2,[X|L3]) :- append(L1, L2, L3).

vi(File) :-
     name(vi,V),
     name(File,FileString),
     append(V,[32|FileString],CommandString),
     name(Command,CommandString),
     unix(Command),
     consult(File).

emacs(File) :-
     name(emacs,V),
     name(File,FileString),
     append(V,[32|FileString],CommandString),
     name(Command,CommandString),
     unix(Command),
     consult(File).
To edit a file, say it is called try.P, do
| ?- emacs('try.P').
Emacs will be started, or vi if you use vi('try.P')., on the file that you name. When you save and quit the editor, you will see
[Compiling ./try]
[try compiled, cpu time used: 0.028999 seconds]
[try loaded]
 
yes
You see that your file as automatically compiled and loaded for you. An easy way to add new assertions while xsb is running, is to type [user]. For example,
| ?- [user].
[Compiling user]
ff.
[user compiled, cpu time used: 0.019997 seconds]
[user loaded]
 
yes
| ?- ff.

yes
When finished, you may exit the Prolog environment by typing control-d.

Problem 1: Greatest Common Divisor

Type the following definition for the relation gcd/3 into a file named gcd using an editting relation (like emacs('gcd.P').). When you save the file and exit the editting session, your relations will be consulted. If you get syntax errors, edit the file again and fix them.

gcd(X,X,X).

gcd(X,Y,D) :-
     X < Y,
     Y1 is Y-X,
     gcd(X,Y1,D).

gcd(X,Y,D) :-
     Y < X,
     gcd(Y,X,D).

Test this by finding the greatest common divisors for five different pairs of integers (like gcd(16,160,D).). Watch the execution of gcd/3 using the trace/0 relation. You may type h while tracing to see the available commands. Just pressing return will take a single step. notrace. will turn off tracing. For example:

| ?- trace.
 
yes
[trace]
| ?- gcd(5,20,D).
   (0) Call: gcd(5,20,_10003020) ? 
   (1) Call: gcd(5,15,_10003164) ? 
   (2) Call: gcd(5,10,_10003192) ? 
   (3) Call: gcd(5,5,_10003220) ? 
   (3) Exit: gcd(5,5,5) ? 
   (2) Exit: gcd(5,10,5) ? 
   (1) Exit: gcd(5,15,5) ? 
   (0) Exit: gcd(5,20,5) ? 
 
D = 5
 
yes
[trace]
| ?-

Now try a floating point number as an argument. Be sure you have called the trace. relation first. Explain the result you see to yourself. (You don't have to turn your explanation in.)

Modification of gcd

Add at least one additional rule for the gcd/3 relation that catches such incorrect arguments so you can exit when non-integer arguments are detected. You may use the not operator, the integer(X) relation, which succeeds if X is an integer, the cut operator !, and the term fail. Place the additional rule in the right place in your gcd.P file. The additional rule should catch non-integer arguments and fail immediately.

Problem 2: Automated Course Prerequisites

Take a look at the on-line chart of CS course prerequisites. Let's say you want to write some prolog code to build a knowledge base which you use to find out whether or not you have met the prerequisites for a given course. Ignore the CS154 and ST309 courses and also ignore the co-requisite of CS200 for CS270.

You must start by typing a prolog file defining the relations needed to represent all of the dependencies in the prerequisites chart. Call that file prereqs.P Then, write a second file named taken.P that contains assertions for the courses you have taken so far. Warning: you should define all assertions with consequents containing a particular relation, like taken, in the same file.

Once both of these files are loaded in xsb, you should be able to get the correct yes or no answer to the queries taken(cs301). and cantake(cs440). or for any other query using the same relation for courses at and below the 400 level. Once this is working, you can collect a set of all courses you have taken so far by doing setof(X,taken(X),L). and you can find out all courses you are qualified to take by doing setof(X,cantake(X),L). Also, define the relation deficiencies that determines the set of all courses you have not taken that must be taken before a given course. For example, if you have only taken m160, you will see this:

| ?- deficiencies(cs301,X).

X = [cs153,cs166,cs200,m121,m124,m161,m229]

yes

For purposes of grading, build your "courses taken" file to show that you have taken all courses at the 300 level and below, except CS370, ST301. If you have written the prolog correctly in both files, you should see this result:

-> xsb
[xsb_configuration loaded]
[sysinitrc loaded]
[packaging loaded]

XSB Version 2.2 (Tsingtao) of April 20, 2000
[sparc-sun-solaris2.8; mode: optimal; engine: chat; scheduling: batched]
| ?- [prereqs].
[prereqs loaded]

yes
| ?- [taken].
[taken loaded]

yes
| ?- cantake(cs440).

yes
| ?- cantake(cs470).

no.
| ?- cantake(cs370).

no.
| ?-  setof(X,cantake(X),L).

X = _h72
L = [cs153,cs166,cs200,cs253,cs270,cs301,cs314,cs410,cs414,cs420,cs430,cs440,cs453,cs486,cs495,m121,m124,m160,m161,m229,st301]

yes
| ?- deficiencies(cs370,L).

L = [st301]

yes
| ?- deficiencies(cs470,L).

L = [cs370,st301]

yes
| ?- deficiencies(cs440,L).

no

What to Check In

To check in your answers to this assignment, combine the prolog files into a tar file, then check in the tar file. You should have the following three prolog files:
  1. gcd.P
  2. prereqs.P
  3. taken.P
Combine these into one tar file named assign4.tar by doing the unix command
tar cvf assign4.tar gcd.P prereqs.P taken.P
Then simply run our checkin command as you have done before to check in assign4.tar.