Running PROLOG

                Running PROLOG 

1. Working with Prolog 

Examples of running Sicstus Prolog.

sturgeon> sicstus
SICStus 0.6 #18: Sun Oct 18 14:19:35 MDT 1992
Copyright (C) 1987, Swedish Institute of Computer Science.
All rights reserved.
| ?-               % Prolog is waiting 


| ?- [user].       % enter the mode for entering clauses from terminal
| p(a).           
| p(f(X)) :- p(X).   % ^D to get out of that mode
| {user consulted, 20 msec 349 bytes}  

yes
| ?- listing.      % a builtin predicate to see all the clauses in DB

p(a).
p(f(A)) :-
        p(A).

yes
| ?- p(X).         % enter the query

X = a ? ;          % proved with substitution, ";" to indicate
                   % you want one more answer
X = f(a) ? ;

X = f(f(a)) ? ;

X = f(f(f(a))) ?     % CT to indicate no more 

yes
| ?- ['grandp.pl'].      % load the file grandp.pl 
{consulting /usr/sunkay/prof/you/course/325/grandp.pl...}
{/usr/sunkay/prof/you/course/325/grandp.pl consulted, 30 msec 144 bytes}

yes
| ?- listing.        % list all clauses in DB

p(a).
p(f(A)) :-
        p(A).

father(ken, marry).

parent(A, B) :-
        father(A, B).
parent(A, B) :-
        mother(A, B).

mother(lily, marry).
mother(marry, john).

grandparent(A, B) :- 
        parent(A, C),
        parent(C, B).

yes
?- listing(mother).  % listing all clauses defining mother

mother(lily, marry).
mother(marry, john).

yes
| ?- grandparent(W, john).  % enter query

W = ken ? ;                 % one answer found

W = lily ? ;                % second found

no                          % no more
| ?- 

yes
| ?- grantparent(ken, lily).    
{Warning: The predicate grantparent/2 is undefined}
   1  1  Fail: grantparent(ken,lily) ? 

% When a predicate is undefined, the proof cannot 
% go through and backtracking should occur. Prolog has 
% a default mode that enters the debugging system.
% unknown is a builtin predicate to switch out of the 
% debugging mode or switch into it.

yes
| ?- unknown(trace, fail).   
{Undefined predicates will just fail (fail)} 

yes
| ?- grantparent(ken, lily).

no
| ?- unknown(fail, trace).     % switch back into the debugging mode
{Undefined predicates will trap to the debugger (trace)}

| ?- ^D
{ End of SICStus execution, user time 0.650 }
sturgeon> 


2. DEBUGGING

The simpliest way to figure out what possibly went wrong
is to trace the entire execution. But this is usually long and 
not very informative. So the debugging system in Prolog allows
the user to specify what parts of the execution should be
shown when tracing the execution. 

TRACE:

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

% use "notrace" or "nodebug" to set it off

yes
{trace}
| ?- grandparent(W, brian).
   1  1  Call: grandparent(_73,brian) ?  % stops at every question mark
   2  2  Call: parent(_73,_224) ?        
   3  3  Call: father(_73,_224) ? 
   3  3  Exit: father(ken,marry) ? 
   2  2  Exit: parent(ken,marry) ? 
   4  2  Call: parent(marry,brian) ?
   5  3  Call: father(marry,brian) ? 
   5  3  Fail: father(marry,brian) ? 
   5  3  Call: mother(marry,brian) ? 
   5  3  Fail: mother(marry,brian) ? 
   4  2  Fail: parent(marry,brian) ? 
   2  2  Redo: parent(ken,marry) ? 
   3  3  Redo: father(ken,marry)
   ........
% this is long

% for each predicate p, p may be called, the call may succeed,
% the call may fail, and p may be re-done upon backtracking
% Thus there are four "ports" associated with a predicate
% [call, exit, fail, redo], and you can specify a subset of this 
% to tell the interpreter on which ports, the trace should stop

| ?- leash([fail]).
{Using leashing stopping at [fail] ports}

yes
{trace}
| ?- grandparent(W,d).
   1  1  Call: grandparent(_73,d)   % printed but not stopped
   2  2  Call: parent(_73,_216)
   3  3  Call: father(_73,_216)
   3  3  Exit: father(ken,marry)
   2  2  Exit: parent(ken,marry)
   4  2  Call: parent(marry,d)
   5  3  Call: father(marry,d)
   5  3  Fail: father(marry,d) ?    % interpreter stops here
   5  3  Call: mother(marry,d)
   5  3  Fail: mother(marry,d) ?    % stops again
   .......

SPY-POINT:

Stops at some particular procedures when creeping through the 
entire program.

| ?- spy[mother,father].      % a list of spy points
{Spypoint placed on mother/2}
{Spypoint placed on father/2}

yes
{debug}
| ?- nospy[mother].          
{Spypoint removed from mother/2}

yes
{debug}
| ?- nospyall.
{All spypoints removed}

yes
{debug}
| ?- spy parent.             % also valid by giving an atom
{The debugger will first leap -- showing spypoints (debug)}
{There already is a spypoint on parent/2}

% current leashing mode does not affect spy-points: 
% interaction is required at every port.
% spy switches debug mode automatically
| ?- grandparent(W,d).
 + 2  2  Call: parent(_73,_139) ? h
Debugging options:
      creep            c      creep
    l     leap             s      skip
    r     retry            r   retry i
    d     display          p      print
    w     write
    g     ancestors        g   ancestors n
    n     nodebug          =      debugging
    +     spy this         -      nospy this
    a     abort            b      break
    @     command          u      unify
    <     reset printdepth <   set printdepth
    ^     reset subterm    ^   set subterm
    ?     help             h      help 
 + 2  2  Call: parent(_73,_139) ? l
 + 2  2  Exit: parent(ken,marry) ? l
 + 4  2  Call: parent(marry,d) ? l
 .....

% Finally, you can tell the state of your debugging mode

| ?- debugging.
{The debugger will first leap -- showing spypoints (debug)}
{Using leashing stopping at [call,fail] ports}
{Undefined predicates will trap to the debugger (trace)}
{Interpreter maxdepth is 100000}
Spypoints:
    parent/2