2007-10-17

Going from Clips to Lisa

I'm currently experimenting with (and thinking about moving my current after-work projects to) Lisa. It's close enough to Clips to make it very easy to pick up but there are a few things that will take some time to get used to.
CL-USER> (in-package LISA-USER)
#[PACKAGE LISA-USER]
LISA-USER> (deftemplate foo
(slot name)
(slot age))
; Evaluation aborted
LISA-USER> (deftemplate foo ()
(slot name)
(slot age))
#[STANDARD-CLASS FOO]
LISA-USER> (assert (foo (name "Johan") (age 34)))
#[FOO ; id 1 #x1A015B01]
LISA-USER> (defrule remove-old-people
?foo <- (foo (age ?age&:(> ?age 30)))
=>
(retract ?foo))
; Evaluation aborted
LISA-USER> (defrule remove-old-people
(?foo (foo (age ?age (> ?age 30))))
=>
(retract ?foo))
; Evaluation aborted
LISA-USER> (defrule remove-old-people ()
(?foo (foo (age ?age (> ?age 30))))
=>
(retract ?foo))
#[RULE REMOVE-OLD-PEOPLE]
LISA-USER> (agenda)
#[ACTIVATION (INITIAL-CONTEXT.RETRACT-PEOPLE-OVER-30 (F-1) ; salience = 0)
#x19FAED25]
#[ACTIVATION (INITIAL-CONTEXT.RETRACT-PEOPLE-OVER-30 (F-1) ; salience = 0)
#x19FAED25]
For a total of 2 activations.
; No value
LISA-USER> (facts)
#[FOO ; id 1 #x19FAEBDD]
For a total of 1 fact.
; No value
LISA-USER> (run)
1
LISA-USER> (facts)
For a total of 0 facts.
; No value
LISA-USER>
Each of the ; Evaluation aborted lines marks where I was sent into the debugger. I'm not sure how I managed to get two activations but I suspect that part of the rule was already created when I got the error of not having specified any keywords. No warning about redefining the rule though!

Anyway, Lisa allows me to use the full power of Common Lisp side by side with a Rete-engine and I must admit I kind of like that idea. Lately, one of the things I've come to miss in Clips is the ability to define rules dynamically. I've tried using eval:
CLIPS> (eval "(defrule blah (whatever) =>)")
[EXPRNPSR3] Missing function declaration for defrule.
FALSE
but without success.

Whenever such a need has appeared I have used Python to dynamically generate the source code which I then load and run in Clips but I'd prefer to keep it all in one place and since I know better than to have delusions about pyRete performance I *think* this might be the way to go.

[2007-10-17] Update: Less than an hour after I posted this I learned that there is indeed a way to generate rules dynamically. The function is called build and is described in chapter 12.3.6 Evaluating a Construct within a String of the Clips Basic Programming Guide. Thanks Gary and Peter for pointing this out.

4 kommentarer:

Gary Riley sa...

CLIPS> (assert (whatever))
Fact-0>
CLIPS> (build "(defrule blah (whatever) =>)")
TRUE
CLIPS> (agenda)
0 blah: f-0
For a total of 1 activation.
CLIPS>

woolfel sa...

On page 158 of the clips manual. There's an example of using (build) command to create rules dynamically.

(build "(defrule foo (a) => (assert (b)))")

woolfel sa...

gary beat me to it by one minute :)

Johan Lindberg sa...

I absolutely LOVE it!

Believe it or not but I've spent a lot of time with the Clips Basic Programming Guide lately. Honest! How I've been able to miss the build function is beyond me.

Thanks for taking the time to point this out, both of you.