Lab: Prolog

CSC261 - Artificial Intelligence - Weinman



Summary:
We explore writing programs and posing queries to the GNU Prolog environment.

Preparation

  1. Make a directory for this lab.
    mkdir somewhere/prolog
    cd somewhere/prolog
  2. Open Emacs and create a new Prolog program called blocks.pl in your new directory.
  3. In emacs, type
    M-x prolog-mode 
    to change from Perl (the default for a pl extension) to Prolog mode.

Exercises

Consider the blocks world shown below.
blocks.png

A: Facts

  1. Using the predicate on, and the names of the blocks as well as table, define the ground facts for the blocks world above.
  2. Save your file, start prolog, and load your program. Fix any syntax errors. For example:
    prolog
    GNU Prolog 1.3.0
    By Daniel Diaz
    Copyright (C) 1999-2007 Daniel Diaz
    -  ?- ['blocks'].
    compiling somewhere/prolog/blocks.pl for byte code... 
    somewhere/prolog/blocks.pl compiled, 8 lines read - 963 bytes written, 6 ms
     
    yes
    -  ?- 
    Note that, like other shells, prolog allows you to use the up and down arrows to navigate through your command history.

B: Rules

Next, we will define a predicate above(X,Y) to indicate whether some block X is above another block Y in a single stack.
  1. What should the "base case" for this predicate relation be? That is, what is the simplest (or most direct) way for a block to be above another?
  2. Write the body for this form of the rule using the head above(X,Y).
  3. What should the "recursive case" for this predicate be? That is, what if you had a stack of ten blocks? How would you go about reasoning that the top one is indeed above the bottom block?
  4. Write the body for this form of the rule using the head above(X,Y).
  5. Save your file and re-load your program in your prolog shell. Fix any syntax errors.
  6. Test your "base case" of B.2. For example
    -  ?- above(a,b).
      
    true ?
    At this point, prolog is waiting for you press return to terminate the query, press ; to continue the search for another solution, or type a to print all solutions. What do you expect to happen if you type a? Verify your prediction.
  7. Test several other examples of this base case.
  8. Test your "recursive" case of B.4. For example
    -  ?- above(a,c).
    If prolog terminates with a stack overflow error, you haven't architected your recursive case in such a way that the chaining can terminate successfully. If you do not see how to fix this, review AIMA section 9.4.4. Remember that prolog tries to unify rule heads from top to bottom (in the file) and atoms from left to right (in a rule body).
  9. Ask prolog to identify all the blocks above a. What do you expect it to produce?
  10. Ask prolog to identify all the blocks below a for you. What result do you expect? You will need to use the same interaction commands mentioned in B.6.
  11. Ask prolog to identify all the blocks that are above one another.

C: [Optional] Interpreting failure

Imagine a robot wants to stack these blocks, but its weak arm can only lift and move one at a time. Furthermore, they are fragile and should not be toppled. Therefore the robot will need to know whether a block is clear of other blocks.
  1. Think about how you would define (in English) the clear predicate.
  2. What additional machinery do you need prolog to incorporate in order to define the predicate you've concocted?
  3. When you have your answer, review the note below.1
  4. Define the rule with head clear(X).
  5. Save your file and reload your program in prolog. Note that if prolog warns you about unused ("singleton") variables in an expression, you can replace these variables with the anonymous placeholder _.
  6. Test your definition of clear on blocks you know should succeed and blocks you know should fail.
  7. Ask prolog to list all the blocks that are clear. Explain the result.

Lab Assignment

You may now begin working on the lab assignment.

Copyright © 2011 Jerod Weinman.
ccbyncsa.png
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.

Footnotes:

1You likely have ascertained that because the Horn clauses used by prolog allow at most one negated atomic sentence (the head) in the disjunction, there is no way to incorporate other negated predicates. There are many times when we would like to take advantage of something like negation in the body of a Horn clause.
Interestingly, many (most? all?) versions of prolog allow one to tinker with the backward chaining machinery a bit in order to get at something like negation. The "negation" operator + when placed before a predicate, as in
+ P
in the body of a rule means "try to satisfy P; if it is satisfied then fail, otherwise, succeed." This behaves well as expected when P in fact is not satisfied. However, perhaps counterintuitively at first, it cannot be used to find the terms for which a predicate fails.