CIS Logo SVC Logo

   Computing & Information Systems
   Department

 

Schoology Facebook        Search CIS Site      Tutorials

Using spy in Prolog


It is possible to use the spy predicate in yap to trace the execution of a Prolog program. The following shows such a trace using the ancestor.pro program. Once you have loaded your Prolog program using consult, set up a spy point on the ancestor predicate as shown. The example shows the result of trying two goals: first, ancestor(fred, diane) and second, ancestor(tina,Who). Note the capital W on Who indicating a variable. After getting an answer for Who, the example entered a semicolon to tell yap to look for another answer.

   ?- consult('ancestor.pro').
 % consulting /home/carlsond/prolog/ancestor.pro...
 % consulted /home/carlsond/prolog/ancestor.pro in module user, 0 msec 10016 bytes
yes
   ?- ancestor(tina, Who).
Who = sally ? ;
Who = john ? ;
Who = diane ? ;
no
   ?- spy(ancestor).
% Spy point set on user:ancestor/2.
% Debug mode on.
yes
% debug
   ?- ancestor(fred,diane).
 *        (1)    call:ancestor(fred,diane) ? 
          (2)    call:parent(fred,diane) ? 
          (2)    fail:parent(fred,diane) ? 
          (3)    call:parent(fred,_131192) ? 
          (3)    exit:parent(fred,sally) ? 
 *        (4)    call:ancestor(sally,diane) ? 
          (5)    call:parent(sally,diane) ? 
          (5)    exit:parent(sally,diane) ? 
?*        (4)    exit:ancestor(sally,diane) ? 
?*        (1)    exit:ancestor(fred,diane) ? 
yes
% debug
   ?- ancestor(tina,Who).
 *        (1)    call:ancestor(tina,_131111) ? 
          (2)    call:parent(tina,_131111) ? 
          (2)    exit:parent(tina,sally) ? 
?*        (1)    exit:ancestor(tina,sally) ? 
Who = sally ? ;
 *        (1)    redo:ancestor(tina,_131111) ? 
          (3)    call:parent(tina,_131199) ? 
          (3)    exit:parent(tina,sally) ? 
 *        (4)    call:ancestor(sally,_131111) ? 
          (5)    call:parent(sally,_131111) ? 
?         (5)    exit:parent(sally,john) ? 
?*        (4)    exit:ancestor(sally,john) ? 
?*        (1)    exit:ancestor(tina,john) ? 
Who = john ? ;
          (5)    redo:parent(sally,john) ? 
          (5)    exit:parent(sally,diane) ? 
?*        (4)    exit:ancestor(sally,diane) ? 
?*        (1)    exit:ancestor(tina,diane) ? 
Who = diane ? ;
 *        (4)    redo:ancestor(sally,_131111) ? 
          (6)    call:parent(sally,_131412) ? 
?         (6)    exit:parent(sally,john) ? 
 *        (7)    call:ancestor(john,_131111) ? 
          (8)    call:parent(john,_131111) ? 
          (8)    fail:parent(john,_131111) ? 
          (9)    call:parent(john,_131563) ? 
          (9)    fail:parent(john,_131563) ? 
 *        (7)    fail:ancestor(john,_131111) ? 
          (6)    redo:parent(sally,john) ? 
          (6)    exit:parent(sally,diane) ? 
 *        (10)    call:ancestor(diane,_131111) ? 
          (11)    call:parent(diane,_131111) ? 
          (11)    fail:parent(diane,_131111) ? 
          (12)    call:parent(diane,_131631) ? 
          (12)    fail:parent(diane,_131631) ? 
 *        (10)    fail:ancestor(diane,_131111) ? 
 *        (4)    fail:ancestor(sally,_131111) ? 
 *        (1)    redo:ancestor(tina,_131111) ? 
 *        (1)    fail:ancestor(tina,_131111) ? 
no
% debug
Action (h for help): e

Reading the spy output

  • call: shows yap calling a particular predicate with certain parameters, i.e. trying to show that this is true.
  • exit: shows that the goal listed after exit: has succeeded.
  • fail: shows that the goal listed after fail: was not shown to be true, and so is assumed to be false.
  • redo: shows yap trying to show the goal after redo: to be true with some different value or values of the variable(s).
  • Note that numbers preceded by an underscore represent unbound variables, variables without values at this point.

Instructor: Br. David Carlson



Author: Br. David Carlson
Last updated: February 20, 2012
Disclaimer