A second attempt at NotNodes

Hmm... there are a couple of things that doesn't work right. I should've known something was wrong when it only took 15 minutes to implement Single Not Nodes ;-)

1. The AlphaNotNodes are inserted in the wrong place by the RuleCompiler and will therefore not yield the correct results when combined with another (not negated) conditional element.
2. According to CLIPS, a LHS with only a Single Not Node is matched against the whole Working Memory. So...

CLIPS> (deffacts foo (digit 1) (digit 2))
CLIPS> (defrule bar
(not (digit 2))
CLIPS> (reset)
==> f-0 (initial-fact)
==> Activation 0 bar: f-0,
==> f-1 (digit 1)
==> f-2 (digit 2)
<== Activation 0 bar: f-0,
Currently it doesn't work like that. Oh well... back to work.

[Update 2007-02-06] The equivalent of the above CLIPS session works now.
>>> import pyRete
>>> from pyRete.flags import *
>>> @pyRete.Rule
... def foo(a = int):
... if Not(a == 2):
... pass
>>> ruleengine = pyRete.RuleEngine()
>>> ruleengine.watch(ALL)
>>> ruleengine.add_rule(foo)
>>> ruleengine.reset()
>>> ruleengine.assert_fact(range(1,3))
# foo: +O+N+o+P
# Activation 1/100, foo: {'?': }
# ==> Object-1 :
# ==> Object-2 : 1
# Deactivation 3/100, foo: {'?': }
# ==> Object-3 : 2
The only really irritating thing is that the Deactivation message shows up *before* the assertion message. Sigh...

3 kommentarer:

woolfel sa...

here is a tip for you :)

Not is normally implemented as a beta node, even for cases like (not <boolean express> ). Although you can implement (not <boolean expression> ) as an alphaNode, the trick is that the boolean expression could evaluate against several facts. A Not node that supports multiple facts will by default support a single fact.

on assertLeft for Not, it should propogate if the match count is zero. On assertRight, it should propogate a retract if the match count goes from zero to one. on retractLeft, it should just propogate the retract. On retractRight, it should propogate an assert if the match count goes from 1 to zero.

hope that helps

Johan Lindberg sa...

Thanks Peter.

You know, I've read the section on Not Nodes probably a hundred times now. I've read about the counter for matches several times. I even want to say that I understand how to implement it. However, I can't really explain why I thought I had something worth posting about. My only excuse is that it was late and I was tired ;-)

Anyway, the day after I wrote the first post I started implementing it for real and damn... those Not Nodes are a can of worms aren't they? I thought, for example, that I would be able to escape the Initial Fact but that one bit me hard and I had to spend a lot of time making sure that the nodes behave correctly.

All in all though it's starting to look quite good. I think I've managed to get most of the situations straightened out (we're still only talking about single expressions). All that is missing now is the unit tests to prove it :-)

woolfel sa...

yeah, not node has a steep learning curve. once you do it right once, it isn't so mysterious.