Negative rule

62 views
Skip to first unread message

Thibault Daoulas

unread,
Sep 12, 2016, 4:52:14 AM9/12/16
to Drools Usage
Hi!
Using Drools in stream mode, I have been using workarounds this far to express this, but is there some best practice to express that a rule should be the negation of another rule, i.e. rule B being the negation of rule A, rule B should activate as long as conditions for rule A to activate are not met?

When I do the following, for example :
rule A
when
 a(value == 0)
 b(value == 0)
then
 insert(doubleZeros)
end

ruleB
when
 not(a(value == 0) and b(value==0))
then
 insert(notDoubleZeros)
end

In this case I get a NPE thrown when facing conditions where ruleB activates (see below) and if I write ruleB in this form :

ruleB
when
 not a(value == 0) or not b(value==0)
then
 insert(notDoubleZeros)
end

Then I get two insertions of notDoubleZeros.

Am I missing something obvious here?

java.lang.NullPointerException
at org.drools.core.phreak.RuleNetworkEvaluator.deleteChildLeftTuple(RuleNetworkEvaluator.java:725)
at org.drools.core.phreak.RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(RuleNetworkEvaluator.java:718)
at org.drools.core.phreak.PhreakJoinNode.doLeftDeletes(PhreakJoinNode.java:416)
at org.drools.core.phreak.PhreakJoinNode.doNode(PhreakJoinNode.java:50)
at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:519)
at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:505)
at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:341)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:301)
at org.drools.core.phreak.RuleNetworkEvaluator.doRiaNode(RuleNetworkEvaluator.java:573)
at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:500)
at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:341)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:301)
at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:136)
at org.drools.core.phreak.AddRemoveRule.forceFlushLeftTuple(AddRemoveRule.java:652)
at org.drools.core.phreak.AddRemoveRule.flushLeftTupleIfNecessary(AddRemoveRule.java:626)
at org.drools.core.reteoo.BetaNode.assertObject(BetaNode.java:299)
at org.drools.core.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:63)
at org.drools.core.reteoo.WindowNode.assertObject(WindowNode.java:184)
at org.drools.core.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:494)
at org.drools.core.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:384)
at org.drools.core.reteoo.ObjectTypeNode.propagateAssert(ObjectTypeNode.java:300)
at org.drools.core.phreak.PropagationEntry$Insert.execute(PropagationEntry.java:93)
at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:78)
at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:68)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.flushPropagations(StatefulKnowledgeSessionImpl.java:2011)
at org.drools.core.phreak.RuleExecutor.fire(RuleExecutor.java:128)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:74)
at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1007)
at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1350)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1288)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1306)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1297)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1278)

Thibault Daoulas

unread,
Sep 12, 2016, 5:03:14 AM9/12/16
to Drools Usage
And an interesting thing is that if I had "no-loop" to ruleB, then I don't get the NPE and the results are as expected. Does anyone have an idea of what could be happening?

Mario Fusco

unread,
Sep 16, 2016, 12:56:12 PM9/16/16
to Drools Usage
Hi,

I think you're experiencing the same problem reported here https://issues.jboss.org/browse/DROOLS-1285 and fixed a couple of days ago with this commit https://github.com/droolsjbpm/drools/commit/e6da071fa20de879d3f69176ab5f70b0db9a4f1f

If possible try to check (rebuilding drools from master) if it fixes your problem and in case it persists please send a complete reproducer.

Thanks and regards,
Mario

Thibault Daoulas

unread,
Sep 19, 2016, 5:12:45 AM9/19/16
to Drools Usage
Thank you Mario, I'll try and reproduce it and will submit a report if it persists.
For this specific scenario where I want a rule to activate if another one doesn't, I just gave both rules the same activation group, with the second rule with lower salience, activating as soon as there is a new event inserted in working memory.
Reply all
Reply to author
Forward
0 new messages