The reason why you experience this behavior is rooted in the difference
between rule evaluation and rule firing.
The custom accumulate is reevaluated, in your case, for each Long you
insert: since you only have the accumulate,
the result of the accumulate will be used to generate a tuple for the
RuleTerminalNode, which will result in
an activation, to be fired later when you call fireAllRules. By
(somewhat debatable) design, activations from
the same accumulate will override each other if not fired in between.
This said, we have two scenarios here:
1) 5 first, 15 second :
when you insert 5, 5 is now the highest. It is also < 10, so an
activation is generated on the agenda.
now you insert 15: it becomes the new highest value, but it is NOT < 10,
so the accumulate returns
null. Unfortunately, null does NOT match "Long() from accumulate ..." so
there will be no new activation
to override the preexisting one. That will fire and you will see
"inserted 5" in the working memory.
2) 15 first, 5 second
when you insert 15, it becomes the highest. The result is null, and for
the same reason above NO
activation will be generated. You now insert 5, but this value won't
change highest, so you will
not see any activations either.
Under the premises, the behavior is correct. You may want to replace the
result:
result( (highest < 10) ? highest : -1L; )
you should see a more coherent behavior :)
Let me know if you need more clarifications
Best,
Davide
On 10/26/2013 01:32 PM, mikerod wrote:
This is a follow up from my original post @
http://drools.46999.n3.nabble.com/rules-users-Question-about-custom-accum...
Using Drools version 5.5.0.Final
I am experiencing behavior I did not expect, regarding Drools accumulate
functionality.
The following demonstrates:
With an example (contrived) rule such as:
file <<example.drl>>
package drools
rule "testing"
dialect "mvel"
when
$res : Long() from accumulate( $l : Long(),
init( Long highest = null; ),
action( highest = ((null == highest) || ($l > highest)) ? $l :
highest; ),
result( (highest < 10) ? highest : null; ))
then
insertLogical( new String("inserted " + $res.toString()) );
end
endfile <<example.drl>>
I have the following, simple test case:
file <<ExampleDroolsTest.java>>
package drools;
import java.io.IOException;
import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.junit.Test;
public class ExampleDroolsTest {
@Test
public void test() throws IOException {
final KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("drools/example.drl"),
ResourceType.DRL);
final KnowledgeBase kbase = kbuilder.newKnowledgeBase();
final StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();
/** HERE the insertion order of these two facts, will result in
different outcomes for
* the rule "testing" in example.drl .
* In this order, I will get the RHS logic to insert the new
String("inserted" + $res.toString())
* The accumulate should be getting the max valued Long, in the end
and then the `result` of the
* `accumulate` should yield a null value.
*
* If I flip the inserts, no fact is inserted into the session.
*/
ksession.insert(new Long(5));
ksession.insert(new Long(15));
final int rulesFired = ksession.fireAllRules();
System.out.println("Rules fired: " + rulesFired);
System.out.println("Session objs:");
for (final Object o : ksession.getObjects()) {
System.out.println(o);
}
ksession.dispose();
}
}
endfile <<ExampleDroolsTest.java>>
As I note in the Java source comment above, the order of the insertions of
the Long's into the session, change the results of the rule execution. My
initial understanding of accumulate, would be that the LHS would be
invalidated once the highest Long value
was found to be 15 > 10, as the `result` portion of the `accumulate` tests.
Since the String object is inserted logically, I'd
expect the fact to be retracted from the working memory once the LHS of the
rule "testing" was found to be false.
If this were the case, the order of insertions above in the test case, would
result in the same working memory after rule execution.
Is this intended behavior of the accumulate node along with the
`insertLogical` operation?
Thanks!
--
View this message in context:
http://drools.46999.n3.nabble.com/Unexpected-behavior-of-accumulate-and-i...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users