CS440: Assignment #9
Assigned Nov. 19th
Due 12:30, Dec. 5th

Introduction to 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

In our cs440 directory, there is a file named initprolog.P that 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).

First, copy our initprolog.P file to your working directory, by doing

cp ~cs440/96/initprolog.P .

Then, on any of our machines, except the HP's, type xsb -i. The -i is to run it in an interactive mode. Then load the editting relations. Here's what you should see:

-> xsb -i
XSB Version 1.4.0 (94/5/9)
[sequential, single word, optimal mode]
| ?- consult(initprolog).
[Compiling ./initprolog]
[initprolog compiled, cpu time used: 0.581 seconds]
[initprolog loaded]
 
yes
| ?- 
This compiles the initprolog.P file, producing initprolog.O. The next time you consult this file, you will only see
| ?- consult(initprolog).
[initprolog loaded]
 
yes
because the file was already compiled. An alternative way to consult a file is to use square brackets:
| ?- [initprolog].
[initprolog loaded]
 
yes

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. \subsection*{Quitting}

Exitting Prolog

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

Your First Prolog Challenge

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. What is returned for the answer? Why?

Modification of gcd

What additional rule for the gcd/3 relation would catch such incorrect arguments so you could 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. Where should the additional rules be placed? The additional rule should catch non-integer arguments and fail immediately.

Hand This In

You may use the unix script command to save your interaction with xsb in a file.

By the Way

One 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