CS 161 Recitation Notes - Running Prolog on SEASnet

SICStus Prolog is available for your use on SEASnet. To use it, log on to your seasnet account and type prolog at the command prompt. For example:

   {olympic} 2> prolog
   booting, please wait...
   SICStus 3  #5: Fri Nov 6 18:11:16 PST 1998
   | ?-

At this point, you are in query mode. You can tell this by the | ?- prompt. If you want to enter facts or rules into the knowledge base, you can load them from a file using the consult predicate. It takes a single argument, which is the name of the file:

   | ?- consult(myfile.pl).
   {consulting /w/class.01/cs/cs161/cs161ta/risc/myfile.pl...}
   {/w/class.01/cs/cs161/cs161ta/risc/myfile.pl consulted, 150 msec 27088 bytes}

   yes
   | ?-
Prolog loads the file, and then responds yes, since the consult predicate succeeded. There's a short form for consult which can load several files at once. The form is just to give a list of the filenames. In other words, to load the files foo1, foo2 and foo3, you would do this command:
   | ?- [foo1,foo2,foo3].

If you'd prefer to type in some facts and predicates directly, you can do this by consulting the input stream, which is called user (if you're familiar with unix, "user" is equivalent to "stdin" in unix) in Prolog:
   | ?- consult(user).
   |
At this point, the prompt tells us that Prolog is expecting us to input facts and/or predicates at this point. For example:
   | ?- consult(user).
   | likes(john,mary).
   | likes(john,basketball).
   | likes(john,pasta).
   | likes(john,ozomatli).
   | likes(mary,X) :- likes(X,ozomatli).
   | {user consulted, 0 msec 536 bytes}

   yes
   | ?-
At this point, Prolog knows the following things: To exit user-consult mode, type <control-d> and Prolog will exit back to query mode. NOTE: user-consult mode is non-cumulative. Thus if you've typed in a bunch of facts in user-consult mode and then you go into user-consult mode again, you lose all the facts you typed in from the previous consult. This is not the case with consulted files; once you load them, they stay until you reconsult them or exit Prolog.

At this point we can make queries about the facts loaded in from the file or typed in to user-consult mode:

   | ?- likes(john,basketball).

   yes
   | ?- likes(john,eels).

   no
   | ?- likes(Who,pasta).

   Who = john ?

   yes
   | ?-
Note that in the "Who likes pasta?" example, I just hit return after the first answer was offered. If you want to see if Prolog can find more than one answer, type a semi-colon when it offers you an answer:
   | ?- likes(john,What).

   What = mary ? ;

   What = basketball ? ;

   What = pasta ? ;

   What = ozomatli ? ;

   no
   | ?-
Here, when I typed the "What does John like?" query, Prolog first gives me the answer What = mary ?, and waits for my response. At this point, I could either type a carriage return and be done, or I could type a semi-colon to get another answer. In the example, I typed a ';' after each answer it gave me until it ran out of answers, at which point it said "no".

If you want to trace the execution in Prolog, you can use the trace predicate:

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

   yes
   {trace}
   | ?- likes(mary,Who).
   1  1  Call: likes(mary,_193) ?
   2  2  Call: likes(_193,ozomatli) ?
   2  2  Exit: likes(john,ozomatli) ?
   1  1  Exit: likes(mary,john) ?

   Who = john ?

   yes
   {trace}
   | ?-
As when it offered me a possible answer to the queries above, after each step in the trace, Prolog puts up a question mark asking what I want to do next. In this case, I just hit a carriage return each time and stepped right through the debug. The SICStus debugger actually offers several possible actions at this point, and you can find out what they are by typing a ?. Here's what it will tell you:
   Debugging options:

      <cr>   creep           c      creep
      l     leap             s      skip
      r     retry            r <i>  retry i
      f     fail             f <i>  fail i
      d     display          w      write
      p     print            p <i>  print partial
      g     ancestors        g <i>  ancestors n
      &     blocked goals    & <i>  nth blocked goal
      n     nodebug          =      debugging
      +     spy this         + <i>  spy conditionally
      -     nospy this       .      find this
      a     abort            b      break
      @     command          u      unify
      e     pending exception
      <     reset printdepth < <i>  set printdepth
      ^     reset subterm    ^ <i>  set subterm
      ?     help             h      help

I won't try to explain these here, but if you decide to try out something more complex in prolog, you may want to know that they're there.

To turn off tracing, execute the notrace predicate:

   | ?- notrace.
   {The debugger is switched off}

   yes
   | ?-

To exit Prolog, you type a <control-d>, as in gcl.

Just for continuity's sake, here's a complete listing of a simple Prolog session I ran to get most of the examples shown above:

   {olympic} 2> prolog
   booting, please wait...
   SICStus 3  #5: Fri Nov 6 18:11:16 PST 1998
   | ?- consult(user).
   | likes(john,mary).
   | likes(john,basketball).
   | likes(john,pasta).
   | likes(john,ozomatli).
   | likes(mary,X) :- likes(X,ozomatli).
   | {user consulted, 0 msec 536 bytes}

   yes
   | ?- likes(john,basketball).

   yes
   | ?- likes(john,eels).

   no
   | ?- likes(Who,pasta).

   Who = john ?

   yes
   | ?- likes(john,What).

   What = mary ? ;

   What = basketball ? ;

   What = pasta ? ;

   What = ozomatli ? ;

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

   yes
   {trace}
   | ?- likes(mary,Who).
   1  1  Call: likes(mary,_193) ?
   2  2  Call: likes(_193,ozomatli) ?
   2  2  Exit: likes(john,ozomatli) ?
   1  1  Exit: likes(mary,john) ?

   Who = john ?

   yes
   {trace}
   | ?- notrace.
   {The debugger is switched off}

   yes
   | ?- I typed <control-D> here
   {olympic} 3>