CPSC 322 - Lecture 6 - September 20, 2004

CPSC 322 - Lecture 6

The Top-Down Ground Proof Query Procedure


I. Top-down ground proof query procedure

Today we talked about the details of the proof procedure that 
allows CILOG to turn our queries into yes or no answers.  The
procedure is called the top-down ground proof query procedure.
There's a corresponding bottom-up procedure that you should read
about in your textbook; we won't talk about it here.

The top-down ground proof query procedure begins with a 
generalization of modus ponens, the basic rule of inference:

  if "h <- b1 ^ b2 ^ ... ^ bm" is a clause in the knowledge
  base, and each bi has been derived, then h can be derived

Or in other words, if you know that each bi is true, then
"and"ing them all together is true, so you can infer that
h is true.  (The word "derived" means it can be computed 
from the knowledge base.  If g can be derived from KB, we
can denote this with KB |- g.)

Now when we say something like this to CILOG:

  "ask a1 & a2 & ... & am."

we're really saying 

  "prove this theorem: a1 & a2 & ... & am."

In Datalog, the almost-CILOG language used in your text,
you'd see "^" instead of "&", but otherwise it's the same 
thing.  Either way, the theorem gets converted to an answer clause
that looks like this:

  yes <- a1 ^ a2 ^ ... ^ am.

Given an answer clause, the proof procedure begins the real work.
First, the proof procedure selects on atom or conjunct from the
right hand side of the answer clause.  Let's say the selected atom
is ai.  Next the proof procedure chooses a clause from the 
knowledge base whose head matches ai.  The chosen clause might be

  ai <- b1 ^ ... ^ bx.

The proof procedure then resolves the answer clause with the 
clause chosen from the knowledge base by replacing the ai in
the answer clause with the body of the chosen clause from the
knowledge base:

  yes <- a1 ^ a2 ^ ... ^ b1 ^ ... ^ bx ^ ... ^am.

The proof procedure repeats this process until all of the atoms
in the body of the answer clause have resolved to True:

  yes <- a1 ^ a2 ^ a3 ^ ... ^ am.
  yes <- a1 ^ true ^ a3 ^ ... ^ am.  
  yes <- a1 ^ a3 ^ ... ^ am.
  yes <- a1 ^ true ^ ... ^ am.
  yes <- a1 ^ ... ^ am.
      :
      :
  yes <- .

A sequence of answer clauses that ends with "yes <- ." is called
a derivation, and the process is called definite clause 
resolution.  Here's a brief algorithmic description of a 
top-down definite clause interpreter:

  solve or prove: ?a1 ^ ... ^ ak.

  AC := yes <- a1 ^ ... ^ ak.
  repeat

    select a conjunct ai from the body of AC

    choose a clause C from KB with ai as its head

    replace ai in the body of AC with the body of C

  until AC is an answer (that is, until AC is yes <- .)

There are a couple of things to note here.  First, this 
description ignores what is to be done with variables.  We'll
deal with this next time.  The other thing to note is that
this description is nondeterministic -- there are points in the 
algorithm where decisions are to be made, but how the decisions
should be made isn't specified.  It just says "select" a conjunct
or "choose" a clause, but it never says which one.  Of course, 
you've learned in previous CS classes that it's possible to 
simulate nondeterminism, or in this case to find all derivations, 
by systematically considering all possibilities, right?


II.  "select" vs. "choose"

While we're on the topic of nondeterminism, it's worthwhile to 
mention that there are actually two kinds of nondeterminism 
involved here.

The first kind of nondeterminism is called "don't-care" 
nondeterminism, and it's indicated in the algorithm above by
the word "select".  In the case of our top-down interpreter, 
the interpreter selects any atom or conjunct from the body of
the answer clause and attempts to derive that atom from the 
knowledge base, thus showing the atom to be true.  If the 
interpreter can't find a derivation for that atom, it doesn't
care about looking at other atoms in the answer clause.  If
the selected atom isn't true, then the conjunction of the
selected atom and all the other atoms in the answer clause can
never be true, so there's no sense in trying another atom from
the answer clause.

The second kind of nondeterminism is called "don't-know"
nondeterminism, and it's indicated by the use of the word 
"choose".  When an atom from the answer clause has been selected,
the interpreter must then choose a clause from the knowledge
base to resolve with the selected atom in an attempt to derive
the atom from the knowledge base.  If that resolution ultimately
leads to a solution, then all is well.  If not, however, the
nondeterministic question to be answered is "will choosing a
different clause from the knowledge base make a difference?"  In
this case, the answer is that the interpreter doesn't know.  It
is possible, however, that choosing a different clause from the
KB could yield a different result, so the interpreter backtracks
to the decision point, chooses a different clause, and tries
again to find a derivation.  So in this case, the interpreter
does care about choosing another clause, it just doesn't know
if a different choice will yield a different result, thus it tries
another choice of clause.

Last revised: October 3, 2004