198:515 - Programming Languages and Compilers I
Fall 2005
Useful Stuff about Prolog


Running Prolog

We will be running Sicstus Prolog 3.7 on the graduate server paul. The interpreter executable is located at /usr/local/bin/prolog. If you PATH variable includes /usr/local/bin/, then you should be able to launch the Prolog interpreter by typing prolog on the command line. WARNING: there are several Prolog interpreters on different machines in the department. Make sure that the first two lines printed after you launch Prolog are:

SICStus 3.7: Tue Sep 08 19:55:50 MET DST 1998
Licensed to cs.rutgers.edu
| ?-
to show that you are using Sicstus Prolog. Note that the interpreter is now ready for you to either type a query or to read in a Prolog program (i.e., some rules). At this point commonly, you load a file containing Prolog rules. This is accomplished as follows: [filename]. -- consults (or reads) the file named filename for input to the data base of Prolog rules. The system assumes that the file extension is .pl. For example, the Prolog program
memberof(A,[A|B]).
memberof(A,[B|C]) :- memberof(A,C).
in file mem.pl can be input as follows:
24 paul!programs> prolog
SICStus 3.7: Tue Sep 08 19:55:50 MET DST 1998
Licensed to cs.rutgers.edu
| ?- [mem]. 
{consulting /grad/users/ryder/prolog/programs/mem.pl...}
{Warning: [B] - singleton variables in memberof/2 in lines 1-2}
{Warning: [B] - singleton variables in memberof/2 in lines 2-3}
{/grad/users/ryder/prolog/programs/mem.pl consulted, 0 msec 808 bytes}

yes

The final yes indicates that a Prolog program has been input. The warnings are because the program could optimized by using a don't care variable for the B since it never appears on the righthandside of a rule.

Now if you want to see all the rules in the current database you use the listing command.

| ?- listing.

file_search_path(library, A) :-
        library_directory(A).

mem(A, [A|_]).
mem(A, [_|B]) :-
        mem(A, B).

library_directory('/igor/sicstus37/lib/sicstus37/library').

memberof(A, [A|_]).
memberof(A, [_|B]) :-
        memberof(A, B).

yes

Example Prolog programs that you can run can be found on paul in /grad/users/ryder/prolog/programs/*. Execution traces that correspond to these programs can be found in /grad/users/ryder/prolog/newtraces/*. The expected Prolog source file extension is .pl. All rules and facts with the same lefthandside predicate must be defined on the same file. Because the listing command needs filenames relative to your working directory, you first should connect to the subdirectory containing your Prolog programs before launching the Prolog interpreter.

More Prolog interpreter commands

The following commands are typed in at the Prolog prompt. listing. --creates a listing of the current data base of Prolog facts and rules.

[filename]. --``consults'' (reads) the file named filename for input to the data base; assumes that the file extension is .pl. Other files can be consulted by surrounding their full filename (with extension) in quotes.

When running Prolog, Control-c interrupts execution and results in the Prolog prompt for help. If you reply to the prompt h thus asking for help, the following choices are open to you:

Prolog interrupt options:

a abort - cause abort

b break - cause break

c continue - do nothing

e exit - cause exit

d debug - start leaping

z zip - start zipping

t trace - start creeping

h help - get this list

t will turn on a step-by-step trace of your execution (see below).

d turns on a ``skipping'' trace.

e allows you to exit from Prolog gracefully.

Online Help

The SICStus Prolog manual is available online. To get information on the basic use of prolog and the help facility, type help. at the Prolog prompt. To get information on a particular Prolog predicate, use the predicate as the argument to help, e.g. help(format). The argument to help can also be a keyword that you're guessing. Prolog will return a list of relevant manual sections when you request help on a predicate. To see a manual section, type manual(< section>).

Debugging and tracing

To trace a running Prolog program there are many options. You can trace the step-by-step execution of the program. You can trace the program, but skip some of the intermediate steps. You can watch just one predicate as the rules defining it are executed; this means execution procedes as normal until that predicate is hit and then step-by-step tracing begins and continues as long as a rule for that predicate is executing.

trace. --starts the step-by-step execution; end by the interrupt (Control-c Control-c) followed by e; if you specify notrace the trace is turned off.

spy() --causes a trace of the execution of the specified clause only. During execution, once that clause is reached, the trace is presented and several options are shown below. The command nospyall removes any spy points you have used.

Options: Return - single step trace

l - leap trace (allows you to skip over subgoals)

? - help

g - shows the ancestor list of current goals not yet satisfied

debug --starts the debugging. Normally this goes in steps larger size than the tracing steps. if you have set spypoints the output will show execution of those predicates. The manual calls this "leaping". The command nodebug turns off debugging.

>Reading a trace

The following informal discussion is to help you understand the meaning of the labels on the traces you are generating. It makes the most sense using the procedural semantics of Prolog.

Think of each Prolog function as a box containing all the rules with the same head. Each corner of the box is labelled with an arrow coming into the box (on the left) or leaving the box (on the right). The labels on the arrows are the same as the labels you see in the trace of a Prolog function.

If the Prolog function is recursive, then there is one box for each recursive invocation of the function (like copies of a recursive Pascal procedure). They are all labelled with the four arrows given above. If you trace a recursive computation, you can watch execution travel in/out of these boxes along these arrows. On the trace, the levels are numbered.

The following exerpt of a program was run on paul and traced as shown below. The annotations which follow the % on the right, were inserted after the run of the program.

{\bf Program Used:}
SICStus 3.7: Tue Sep 08 19:55:50 MET DST 1998
Licensed to cs.rutgers.edu
| ?- ['mem'].
{consulting /grad/users/weileiz/Courses/cs515_2003f/prolog/programs/mem.pl...}
{Warning: [B] - singleton variables in memberof/2 in lines 1-2}
{Warning: [B] - singleton variables in memberof/2 in lines 2-3}
{/grad/users/weileiz/Courses/cs515_2003f/prolog/programs/mem.pl consulted, 10 msec 808 bytes}

yes
| ?- listing.

file_search_path(library, A) :-
        library_directory(A).
                               %these clauses test the first arg for
mem(A, [A|_]).                 %membership in the second arg;          
mem(A, [_|B]) :-               %these use the ``don't care'' variable.
        mem(A, B).

library_directory('/igor/sicstus37/lib/sicstus37/library').

memberof(A, [A|_]).
memberof(A, [_|B]) :-
        memberof(A, B).

yes
| ?-trace. trace. 
{The debugger will first creep -- showing everything (trace)}

yes
{trace}
| ?- | ?-  mem(Z,[a,b]).    
        1      1 Call: mem(_246,[a,b]) ?%initial call of recursive clause.
?       1      1 Exit: mem(a,[a,b]) ? 

Z = a ? ;                              %successful return with A bound to a
        1      1 Redo: mem(a,[a,b]) ?  %forced re-execution by ;
        2      2 Call: mem(_246,[b])? 
?       2      2 Exit: mem(b,[b]) ? 
?       1      1 Exit: mem(b,[a,b]) ?  %successful return with A bound to b

Z = b ? ;
        1      1 Redo: mem(b,[a,b]) ? 
        2      2 Redo: mem(b,[b]) ? 
        3      3 Call: mem(_246,[]) ? 
        3      3 Fail: mem(_246,[]) ?   %can't unify  with []  
        2      2 Fail: mem(_246,[b]) ? 
        1      1 Fail: mem(_246,[a,b]) ? 

no                                     %report failure to user.
{trace}
| ?- 
Prolog interruption (h for help)? a
{Execution aborted}
| ?- 
Prolog interruption (h for help)? e     %e was typed to exit.

Process prolog finished

Process prolog finished

First time Prolog programmer hints

Last edited by BGR at 4pm on September 19, 2005.