2008-02-05

Implementing backward chaining in PyCLIPS II.

In my previous post I described a proof-of-concept implementation for backward chaining in PyCLIPS. One of the drawbacks was that it doesn't work on deftemplates.

Consider the factorial example again:

CLIPS[001/01]> (deftemplate factorial
CLIPS[001/02]: (slot v)
CLIPS[001/03]: (slot r))
CLIPS[002/01]> (defrule print-factorial-10
CLIPS[002/02]: (factorial (v 10) (r ?r1))
CLIPS[002/03]: =>
CLIPS[002/04]: (printout t "The factorial of 10 is " ?r1 crlf))
CLIPS[003/01]> (defrule do-factorial
CLIPS[003/02]: (need-factorial (v ?x) (r nil))
CLIPS[003/03]: =>
CLIPS[003/04]: (bind ?r 1)
CLIPS[003/05]: (bind ?n ?x)
CLIPS[003/06]: (while (> ?n 1)
CLIPS[003/07]: (bind ?r (* ?r ?n))
CLIPS[003/08]: (bind ?n (- ?n 1)))
CLIPS[003/09]: (assert (factorial (v ?x) (r ?r))))
[PYCLIPS] C09: unable to understand argument
[PRNTUTIL2] Syntax Error: Check appropriate syntax for defrule.
ERROR:
(defrule MAIN::do-factorial
(need-factorial (
CLIPS[004/01]>
The problem is that the CE that matches need-factorial requires a deftemplate and we haven't provided one. The "solution" is to have the do-backward-chaining function define the neccessary deftemplate dynamically. So all you need to think of is that you must either call do-backward-chaining or define the appropriate need-template before defining any rules that try to match it.
CLIPS[001/01]> (deftemplate factorial
CLIPS[001/02]: (slot v)
CLIPS[001/03]: (slot r))
CLIPS[002/01]> (defrule print-factorial-10
CLIPS[002/02]: (factorial (v 10) (r ?r1))
CLIPS[002/03]: =>
CLIPS[002/04]: (printout t "The factorial of 10 is " ?r1 crlf))
CLIPS[003/01]> (do-backward-chaining factorial)
; + MAIN::need-factorial
; + MAIN::print-factorial-10/0
nil
CLIPS[004/01]> (defrule do-factorial
CLIPS[004/02]: (need-factorial (v ?x) (r nil))
CLIPS[004/03]: =>
CLIPS[004/04]: (bind ?r 1)
CLIPS[004/05]: (bind ?n ?x)
CLIPS[004/06]: (while (> ?n 1)
CLIPS[004/07]: (bind ?r (* ?r ?n))
CLIPS[004/08]: (bind ?n (- ?n 1)))
CLIPS[004/09]: (assert (factorial (v ?x) (r ?r))))
CLIPS[005/01]> (reset)
CLIPS[006/01]> (run)
The factorial of 10 is 3628800
CLIPS[007/01]>
The code is here, if you're interested. I'm not saying it's done or anything and I should probably have cleaned it up a bit more but I've been battling a cold for two weeks now and there are tons of other interesting things to try out. So this will have to do, at least for now.

Inga kommentarer: