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.
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] yesbecause the file was already compiled. An alternative way to consult a file is to use square brackets:
| ?- [initprolog]. [initprolog loaded] yes
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] yesYou see that your file as automatically compiled and loaded for you. \subsection*{Quitting}
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?
gcdgcd/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.
gcd.P file,
gcd(147,105,D) with trace
being used,
gcd.P file with the additional rules
to trap invalid arguments,
gcd(1.3,3.55,D) using your new
gcd.Pwith trace being used.
gcd.P file.
script command to save your interaction with
xsb in a file.
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