Logic Programming 1 Lab

Step 1

This lab requires SWI Prolog. Download and install for your platform (Linux, Mac OS X, WIndows). In my favorite operating system, all I had to do is type sudo apt-get install swi-prolog. Your mileage may vary.

Download the family.pl file and put it into a directory such as /home/me/cs252/lp1lab.

Start SWI Prolog:

  1. Open a shell window
  2. Change to the lab subdirectory
  3. On Linux, run swipl. On Mac OS X, be sure to install X Windows first (http://developer.apple.com/darwin/runningX11.html), then open an X terminal and run xpce. On Windows, run plwin or, if all planets are aligned perfectly, double-click on a file with extension .pl.

In the Prolog shell, type

consult(family).

This loads the family.pl facts into Prolog. Note the period at the end of the command.

If you get a message that the file was not found, perhaps you are not in the right directory. Run the cd command, like this:

cd('/home/me/cs252/lp1lab/').

Note that there is no space after cd, the quotes are single quotes, and there is a period at the end of the command.

Step 2

  1. Issue queries to find the children of charles1 and the parents of george1. Which queries did you issue, and what was the result?
  2. Define a grandparent predicate. Add it to family.pl. Reload the file again with consult. What is the rule defining your predicate? Which query yields the grandparents of sophia? The grandchildren of james1? What are the results?
  3. Define a sibling predicate in the same way. What query did you use to test it?

Step 3

  1. Add the following rules to family.pl:
    ancestor(X, Y) :- parent(X, Y).
    ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

    Which query yields the ancestors of sophia? The descendants of james1? What are the results?

  2. Type the command
    trace.

    (Remember the period at the end.)

    Now issue the query

    ancestor(X, sophia).

    Each time execution halts with a ? prompt, hit Enter. Each time you get another answer, type a semicolon (;) as you did previously.

    What happens?

    Turn debugging off by typing

    nodebug.
  3. Change the second rule for ancestor to
    ancestor(X, Y) :- ancestor(Z, Y), parent(X, Z).

    Intuitively, this should not change the behavior of ancestor. Reload family and try out

    ancestor(X, sophia).

    Be sure to enumerate all answers.

    What happens?

    (Hit a to abort.)

  4. Turn tracing on, study the behavior and explain the reason for the behavior. (I found this less tedious after commenting out all but two of the parent facts in family.pl. In prolog, a line starting with % is a comment.

Step 4

Save this Prolog.scala file. In a shell window, type

scala -i Prolog.scala

When you get a prompt, type these commands:

import Prolog._
val member = new Predicate
member('X, 'X::'Xs)!
member('X, 'Y::'Ys) :- member('X, 'Ys)
member('X, 'john :: 'mary :: 'nil)?
more
more

What happens?

As you can see, the implementor of this interpreter cleverly overloaded operators ! (fact), :- (provided that) and ? (query).

Note the single quote that is used for variables. These are Scala "atoms".

Look inside the source code.

  1. How many LOC?
  2. What is the class for logical variables?
  3. What is the class for functors?
  4. Why are there additional classes for lists and constants?
  5. Where is that cleverly overloaded ? operator defined?
  6. What other operator is overloaded there, and why?
  7. Why does the interpreter use ! and not . for the end of fact?
  8. Translate the rules for subtypes into Scala and determine all subtypes of 'array('object). What is your program, and what does it print?