The Absolute Minimum Every CLIPS Developer Absolutely, Positively Must Know About the Not-CE and Template-Pattern-Constraints (No Excuses!)
Ok. So I stole the title from Joel's very popular article about Unicode, but it's not just a way to get attention. The point is that there are some things about how CLIPS (and other Rule Engines) handle not that might not be all that obvious to programmers used to languages such as Python or Java.
More specifically, I'm talking about the difference between
|CLIPS> (defrule rule1and
| (spam (eggs ?eggs) (bacon ?bacon))
| (test (not (and (eq ?eggs 1) (eq ?bacon 2))))
|CLIPS> (defrule rule2You're not alone if you've ever made the mistake of thinking that wrapping a template-pattern-CE with a not would negate the constraints inside it. That's, however, not what the Not-CE does.
| (not (spam (eggs 1) (bacon 2))
A logical not is the simplest possible operator. It simply returns True if the expression it applies to returns False and vice versa. In CLIPS, it's easy enough to figure out what expression a not applies to, but you might be surprised at how that expression is evaluated?
The Not-CE evaluates to True if there are no facts in Working Memory matching the pattern it applies to. You should think of not as short hand for Not-in-Working-Memory and not as a Not-Equals variant. I know it's not at all that obvious since there are no hints (compare Java's !=) but it should make it's behaviour less of a surprise.