Francis Drake
Francis Drake

Reputation: 315

CLIPS using (not (a-fact $?)) doesn't fire

I'm having a slight difficulty in understanding how the not function interacts with pattern matching. I'd like to write a pattern match that goes "such a fact doesn't exist".

Namely, what I want is:

(defrule init-count
    (not (highest-debt ?))
    (catherines ?debt)
    =>
    (assert (highest-debt ?debt))
)

and then:

(defrule continue-count
    ?debt-fact <- (highest-debt ?h-debt)
    (? ?a-debt)
    (test (> ?a-debt ?h-debt))
    =>
    (retract ?debt-fact)
    (assert (highest-debt ?a-debt))
)

But for some reason not doesn't work for me here. Replacing not with (not (exists /*pattern*/)) doesn't seem to work either. Is there something I'm missing and/or a nice way to implement finding the highest number with rules like that?

Update

The answer that I have just discovered is this: the not pattern shouldn't be the first one ((declare (salience 0)) doesn't count either). So, the following code works correctly:

(defrule init-count
    (catherines ?debt)
    (not (highest-debt ?))
    =>
    (assert (highest-debt ?debt))
)

Sorry for bothering :(

Upvotes: 2

Views: 3653

Answers (1)

Gary Riley
Gary Riley

Reputation: 10757

In versions 6.24 and earlier, when the not conditional element was the first pattern in a rule, the pattern (initial-fact) was added before it (this is described in section 5.4.9, Automatic Addition and Reordering of LHS CEs, in the Basic Programming Guide). The (initial-fact) fact is asserted when a (reset) command is performed. I think this is the cause of your problem. Your original rule would have worked if you'd performed a (reset) before asserting your other facts.

Upvotes: 3

Related Questions