[rules-users] Just found a way to stop fact insert time evaluation (tested in 5.5)

Sonata plz.write.to at gmail.com
Sat May 25 13:58:57 EDT 2013


Originally I was asking for a method to stop LHS evaluation for a bunch of
rules in some other agenda-groups which I am not intended to trigger. But it
turned out that agenda-group filtering will only happen when you fire your
rules. *ALL* rules in *ANY* agenda-groups are evaluated anyway when you are
inserting fact.

Then according to this post
http://drools.46999.n3.nabble.com/Agenda-group-in-fact-insert-time-tp4023749p4023783.html,
Wolfgang suggested to use an extra object to control the LHS evaluation by
changing the value, e.g. Focus( value == "one" ). After many tests in
5.5.0.Final, this has no effect.

Say if you have a rule:
public static class MyClass {
  private Integer i;
  public MyClass(Integer i) {
    this.i = i;
  }
  public Integer getMyInteger() {
    System.out.println("getMyInteger is called for " + i);
    return i;
  }
}
rule test agenda-group "one"
when
  String ( toString == "agenda-group one")
  MyClass ( myInteger == 10 )
then end

when you call ksession.insert(new MyClass(10)); in your java code, no matter
what the value of Focus() is, or even you dont have Focus() object inserted,
getMyInteger() of MyClass is still called/evaluated to match with == 10.
This is highly undesired when you actually only want to trigger rules in
agenda-group "two".

And then finally I found that if you use the keyword "from", it seems it is
way smarter because *it will not be evaluated unless all the preceding
conditions are matched!*

Try the following example:
rule try agenda-group "one"
when
  not Object() from System.out.println(1)
  MyClass ( myInteger == 10 )
  not Object() from System.out.println(2)
  MyClass ( myInteger == 9 )
  not Object() from System.out.println(3)
then end

If you call ksession.insert(new MyClass(10)), you will only see the output
1, 2 but not 3 because MyClass ( myInteger == 9 ) does not match. This is
really smart!

Now we just need a dummy function to return us the object we want then we
can use the agenda-group blocker to stop "fact insert time evaluation" as
follow:

function Object dummy(Object o) {
  return o;
}

rule smart agenda-group "one"
when
  String ( toString == "agenda-group one")
  m : MyClass()
  MyClass ( myInteger == 10 ) from dummy(m)
then end

rule blocker agenda-group "one"
when
then
  insert(new String("agenda-group one"));
end

There! No more unwanted evaluations during fact insert time! In fact, all
the evaluations are pushed back to rule firing time and that can be *truly*
filtered by agenda-group.

Please let me know if I am doing stupid thing or if there is a big price or
consequence to pay for when I use this technique?

Thank you



--
View this message in context: http://drools.46999.n3.nabble.com/Just-found-a-way-to-stop-fact-insert-time-evaluation-tested-in-5-5-tp4023967.html
Sent from the Drools: User forum mailing list archive at Nabble.com.


More information about the rules-users mailing list