I've embedded CLIPS in another program and am using it mostly as an inference engine. My rule conditions use the logical
keyword so that any facts that are assert
ed as a rule's action become automatically retracted when the rule becomes unsupported (BPG Section 5.4.8). I generally need to check for all asserted facts of type foo
(where foo
is the first field of the fact, e.g. (foo bar baz)
). To do this I've been parsing the entire fact list, however doing this has become a significant source of slowdown.
Every fact I care about is asserted in its own rule, so I've thought of instead using a callback within each rule to notify my program that a fact I am interested in has been asserted, however this would only tell me when a fact is asserted, not when it is retracted. I've tried to come up with a way of writing an inverse rule which would fire when a fact becomes unsupported, however I haven't been able to come up with something that works. I've tried the obvious approach of wrapping the entire rule condition with not
but this doesn't let you used variables outside of the not
clause, which is what I would need for the callback to work correctly.
Is there an obvious way to query for all facts of type foo
other than iterating over the facts list? Or is there a way to get a callback when a rule/fact loses support? Seems like this should be fairly easy to do, is there something I am missing here?
You can use the fact query functions to retrieve and perform actions on groups of facts:
CLIPS>
(assert (foo bar baz)
(foo yak)
(foo woz bin bly))
<Fact-3>
CLIPS> (find-all-facts ((?f foo)) TRUE)
(<Fact-1> <Fact-2> <Fact-3>)
CLIPS>
(do-for-all-facts ((?f foo)) TRUE
(printout t ?f:implied crlf))
(bar baz)
(yak)
(woz bin bly)
CLIPS> (deftemplate point (slot x) (slot y))
CLIPS>
(assert (point (x 1) (y 2))
(point (x 3) (y 4)))
<Fact-5>
CLIPS>
(do-for-all-facts ((?f point)) TRUE
(printout t ?f:x " " ?f:y crlf))
1 2
3 4
CLIPS>
When embedded, use the EnvEval function to execute the find-all-facts command and you then iterate over the facts stored in the return value rather than the entire fact list.
You can add callbacks for assertions and retractions using EnvAddAssertFunction and EnvAddRetractFunction although these are not documented APIs.