Constraint Propagation
This example demonstrates PowerLoom's constraint propagation facility
which provides simple propositional forward inference and
propagation of equality constraints. Truth-maintenance of
constraint propagation inferences is still under construction,
which means that the constraint propagation interface will most
probably change in future versions of PowerLoom.
;; Standard demo preamble:
|= (in-package "STELLA")
|= (defmodule "/PL-USER/CONSTRAINTS")
|MDL|/PL-USER/CONSTRAINTS
|= (in-module "/PL-USER/CONSTRAINTS")
|= (clear-module "/PL-USER/CONSTRAINTS")
|= (reset-features)
|i|()
|= (in-dialect :KIF)
:KIF
;; The already familiar `Person' class:
|= (defclass PERSON (STANDARD-OBJECT)
:documentation "The class of human beings."
:slots
((happy :type BOOLEAN)
(age :type INTEGER)))
|C|PERSON
|= (assert (Person Fred))
|P|(PERSON FRED)
;; In PowerLoom constraint propagation is performed on a per-module
;; basis. By default, it is turned off for every module. To enable
;; it, we can use PowerLoom's `propagate-constraints' command (we
;; leave out the optional module argument, which means that constraint
;; propagation will be enabled in the current module):
|= (propagate-constraints)
;; We start by asserting the following disjunction:
|= (assert (or (happy Fred) (= (age Fred) 40)))
|P|(or (HAPPY FRED)
(= (AGE FRED) 40))
;; When we ask for one of the disjuncts, we do not get an answer,
;; since nothing is known about the individual disjuncts:
|= (ask (= (age Fred) 40))
;; Now we assert the negation of the first disjunct, which, since
;; constraint propagation is turned on, will propagate to the second
;; disjunct and assert it to be true:
|= (assert (not (happy Fred)))
|P~|(HAPPY FRED)
;; To show that no inference is necessary to answer the next question,
;; we turn on goal-tracing of the inference engine:
|= (set-feature goal-trace)
|i|(:GOAL-TRACE)
;; Now the query below returns true. The goal trace shows that no
;; inference needs to be performed to get the answer, since the asked
;; proposition is available directly, just like a regular assertion:
|= (ask (= (age Fred) 40))
PATTERN: []
| GOAL: (= (AGE FRED) 40)
| SUCC:
|L|TRUE
;; Constraint propagation picks up certain inferences much more
;; efficiently than the backward chainer. Note that, currently,
;; PowerLoom would have not been able to make the above inference
;; without having constraint propagation turned on.
;; A shortcoming of the current implementation of constraint
;; propagation is that its inferences are truth-maintained only in a
;; very coarse-grained fashion (this will change in future versions).
;; As long as the assertions in a module grow monotonically, all
;; inferences are cached in a strict-inference world, but that world
;; gets blown away completely as soon as some retraction is performed
;; in the module. E.g., if we retract the following proposition, the
;; previous query will not return true anymore:
|= (retract (not (happy Fred)))
|P?|(HAPPY FRED)
|= (ask (= (age Fred) 40))
PATTERN: []
| GOAL: (= (AGE FRED) 40)
| FAIL
;; As mentioned above, after a retraction constraint propagation
;; inferences get blown away. Additionally, constraint propagation
;; gets turned off completely. To turn it back on we have to call
;; `propagate-constraints' again. Note, that `propagate-constraints'
;; not only enables constraint propagation, but it also performs
;; constraint propagation on all propositions currently asserted in a
;; module, which for large KBs could cause a significant amount of
;; recomputation.
|= (propagate-constraints)
;; Below, we run a variation of the previous example that makes use of
;; the violation of an equality constraint:
|= (assert (Person Fritz))
|P|(PERSON FRITZ)
|= (assert (= (age Fritz) 25))
|P|(= (AGE FRITZ) 25)
;; So far, we don't know whether Fritz is happy:
|= (ask (happy Fritz))
PATTERN: []
| GOAL: (HAPPY FRITZ)
| FAIL
;; Now we assert a similar disjunction as used in the example above.
;; Since the second disjunct clashes with the age asserted above,
;; constraint propagation asserts the first disjunct to be true:
|= (assert (or (happy Fritz) (= (age Fritz) 40)))
|P|(or (HAPPY FRITZ)
(= 25 40))
;; Now this query succeeds without any inference:
|= (ask (happy Fritz))
PATTERN: []
| GOAL: (HAPPY FRITZ)
| SUCC:
|L|TRUE
;; Propagation of equality constraints:
|= (assert (Person John))
|P|(PERSON JOHN)
|= (assert (Person Mary))
|P|(PERSON MARY)
;; John is the same age as Mary:
|= (assert (= (age John) (age Mary)))
|P|(= (AGE JOHN) (AGE MARY))
;; We don't yet know Mary's age:
|= (ask (= (age Mary) 25))
PATTERN: []
| GOAL: (= (AGE MARY) 25)
| FAIL
;; Now we set John's age to be 25:
|= (assert (= (age John) 25))
|P|(= (AGE JOHN) 25)
;; This assertion got propagated through the previously asserted
;; equality, thus, now we also know that Mary's age is 25:
|= (ask (= (age Mary) 25))
PATTERN: []
| GOAL: (= (AGE MARY) 25)
| SUCC:
|L|TRUE
|=
Last modified:
Nov 17, 1997