U S I N G   P R O L O G
=======================
=======================


This document is based on a previous document describing
XSB Prolog, which in turn was based on (an earlier 
version of)

       http://www.cs.sunysb.edu/~sbprolog/xsb-page.html



Getting Started with SWI-Prolog
===============================



Invoking SWI-Prolog
-------------------

SWI-Prolog can be invoked by the command: 

       cslinux%  swipl

and you will find yourself in the top level interpreter.

       cslinux% swipl
       Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 5.6.63)
       Copyright (c) 1990-2008 University of Amsterdam.
       SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
       and you are welcome to redistribute it under certain conditions.
       Please visit http://www.swi-prolog.org for details.

       For help, use ?- help(Topic). or ?- apropos(Word).

       ?- 



Compiling SWI-Prolog programs
-----------------------------

All source programs should be in files whose names have the suffix .pl. One
of the ways to compile a program from a file in the current directory and
load it into memory, is to type the query: 

     [my_file].

where my_file.pl is the name of the file.

You can also compile and load predicates input directly from the terminal 
by using the command: 

     [user].

A CTRL-d or the atom end_of_file followed by a period terminates 
the input stream. 



Exiting SWI-Prolog
------------------

If you want to exit SWI-Prolog, issue the command halt., or simply type 
CTRL-d at the SWI-Prolog prompt. 



Getting help
------------

There is extensive built-in help. To get started, use the command:

     help.



Debugging
---------
SWI-Prolog allows you to trace through the execution of your code.

(IMPORTANT: The tracing facility is VERY USEFUL !)


Tracing
-------

To turn on tracing, use 
  trace. 

To turn tracing off, use 
  notrace. 


When tracing is on, the system will print a message each time a predicate
is: 

   1.initially entered (Call), 
   2.successfully returned from (Exit), 
   3.failed back into (Redo), and 
   4.completely failed out of (Fail). 

At each such event, a message is printed and the tracer stops and prompts 
for input.

In addition to single-step tracing, the user can set spy points to
influence how the tracing/debugging works. A spy point is set using spy/1. 
Spy points can be used to cause the system to enter the tracer when a 
particular predicate is entered. 

When the tracer prompts for input, the user may enter a return, or a single 
character followed by a return, with the following meanings:   

c, <CR>: Creep 
     Causes the system to single-step to the next port (i.e. either the 
     entry to a traced predicate called by the executed clause, or the 
     success or failure exit from that clause). 
a: Abort 
       Causes execution to abort and control to return to the top level 
       interpreter. 
b: Break 
     Calls the evaluable predicate break, thus invoking recursively a new 
     incarnation of the system interpreter. The command prompt at break 
     level n is 
     [n] ?- 
     The user may return to the previous break level by entering 
     the system end-of-file character (e.g. ctrl-D).
f: Fail 
     Causes execution to fail, thus transferring control to the Fail port
     of the current execution. 
h: Help 
     Displays the table of debugging options. 
l: Leap 
     Causes the system to resume running the program, only stopping when a 
     spy-point is reached or the program terminates. This allows the user 
     to follow the execution at a higher level than exhaustive tracing. 
n: Nodebug 
     Turns off debug mode. 
r: Retry (fail) 
     Transfers to the Call port of the current goal. Note, however, that 
     side effects, such as database modifications etc., are not undone. 
s: Skip 
     Causes tracing to be turned off for the entire execution of the 
     procedure. Thus, nothing is seen until control comes back to that 
     procedure, either at the Success or the Failure port. 
e: Exit 
     Causes immediate exit from SWI-Prolog back to the operating system. 



Other Debugging Predicates
--------------------------

debug 

       Turns on debugging mode. This causes subsequent execution of 
       predicates with trace or spy points to be traced. The predicates 
       trace/1 and spy/1 cause debugging mode to be turned on
       automatically. 

nodebug 

       Turns off debugging mode. This causes trace and spy points to be 
       ignored. 



Examples
--------


Here are some very simple old functions of mine. 
Note that comments in Prolog begin with a %. 



% within(+ Variable, + VarList)
%
% Test whether Variable is in VarList.

within(_,[]):-fail.
within(Var,[HeadOne|_]):-
	Var==HeadOne. 
within(Var,[_|VarList]):-
	within(Var,VarList).



% nth(+Number, +ListOfElements, -Element)
%       
% Element is the Number-th element in the list ListOfElements.
         
nth(N, List, Element):-
        N1 is N - 1,
        length(Head, N1),
        append(Head, [Element|_Rest], List).



I stored them in the file 

         test2.pl


Now, I had the following session. The examples are self-explanatory. For 
that, keep the above subsection on "trace" in mind.

 

As you see in the examples below, your variables X, Y, Z, ... 
are replaced by internaly generated variables  _G338, _G341, _G344, ... .
This does not matter for you to follow the computation of your program; 
just do a mapping from your original variables in the new ones to grasp 
what is going on.    


?- [test2].
% test2 compiled 0.00 sec, 2,072 bytes
true.

?- trace.              %%%% Here I am invoking trace/0.
Unknown message: query(yes)
[trace]  ?- within("X",[Y,Z,T,V,X,P]).
   Call: (7) within([88], [_G338, _G341, _G344, _G347, _G350, _G353]) ? creep
   Call: (8) [88]==_G338 ? creep
   Fail: (8) [88]==_G338 ? creep
   Redo: (7) within([88], [_G338, _G341, _G344, _G347, _G350, _G353]) ? creep
   Call: (8) within([88], [_G341, _G344, _G347, _G350, _G353]) ? creep
   Call: (9) [88]==_G341 ? creep
   Fail: (9) [88]==_G341 ? creep
   Redo: (8) within([88], [_G341, _G344, _G347, _G350, _G353]) ? creep
   Call: (9) within([88], [_G344, _G347, _G350, _G353]) ? creep
   Call: (10) [88]==_G344 ? creep
   Fail: (10) [88]==_G344 ? creep
   Redo: (9) within([88], [_G344, _G347, _G350, _G353]) ? creep
   Call: (10) within([88], [_G347, _G350, _G353]) ? creep
   Call: (11) [88]==_G347 ? creep
   Fail: (11) [88]==_G347 ? creep
   Redo: (10) within([88], [_G347, _G350, _G353]) ? creep
   Call: (11) within([88], [_G350, _G353]) ? creep
   Call: (12) [88]==_G350 ? creep
   Fail: (12) [88]==_G350 ? creep
   Redo: (11) within([88], [_G350, _G353]) ? creep
   Call: (12) within([88], [_G353]) ? creep
   Call: (13) [88]==_G353 ? creep
   Fail: (13) [88]==_G353 ? creep
   Redo: (12) within([88], [_G353]) ? creep
   Call: (13) within([88], []) ? creep
   Call: (14) fail ? creep
   Fail: (14) fail ? creep
   Redo: (13) within([88], []) ? creep
   Fail: (13) within([88], []) ? creep
false.

[debug]  ?- trace.
Unknown message: query(yes)
[trace]  ?- within("X",[Y,Z,T,V,X,P]).
   Call: (7) within([88], [_G635, _G638, _G641, _G644, _G647, _G650]) ? skip
false.

[debug]  ?- trace.
Unknown message: query(yes)
[trace]  ?- within(X,[Y,Z,T,V,X,P]).
   Call: (7) within(_G644, [_G632, _G635, _G638, _G641, _G644, _G647]) ? creep
   Call: (8) _G644==_G632 ? creep
   Fail: (8) _G644==_G632 ? abort
% Execution Aborted

?- within(X,[Y,Z,T,V,X,P]).
true .

?-  within(X,[Y,Z,T,V,X,P]).
true .

?- trace.
Unknown message: query(yes)
[trace]  ?- within(X,[Y,Z,T,V,X,P]).
   Call: (8) within(_G350, [_G338, _G341, _G344, _G347, _G350, _G353]) ? creep
   Call: (9) _G350==_G338 ? Options:
+:                  spy        -:              no spy
/c|e|r|f|u|a goal:  find       .:              repeat find
a:                  abort      A:              alternatives
b:                  break      c (ret, space): creep
[depth] d:          depth      e:              exit
f:                  fail       [ndepth] g:     goals (backtrace)
h (?):              help       i:              ignore
l:                  leap       L:              listing
n:                  no debug   p:              print
r:                  retry      s:              skip
u:                  up         w:              write
m:		      exception details
C:                  toggle show context
   Call: (9) _G350==_G338 ? skip
   Fail: (9) _G350==_G338 ? skip
   Redo: (8) within(_G350, [_G338, _G341, _G344, _G347, _G350, _G353]) ? skip
   Exit: (8) within(_G350, [_G338, _G341, _G344, _G347, _G350, _G353]) ? leap
true .

[debug]  ?- nodebug.       %%%% Here I exit from debug.
true.