logo       

Re: [drools-user] Help on writing XML rules: msg#00165

java.drools.user

Subject: Re: [drools-user] Help on writing XML rules

I'll try to tackle your question on this DRL rule; I haven't used the XML syntax, but anything I say here should be expressible in XML also, it's just a different way
to say the same sort of things to the Rules Engine.

Let's look at your rule, and how it works:

when
                $cust  : Customer( region >= 1 )
                $order : Order( customer == $cust, totalAmount > 30 )
then
               something...

The when clause of a DRL rule specifies the conditions under which the then clause (the "consequence") will be evaluated.  It is based off of assertions we can make about the objects known to the system (which is what our working memory is).  Drools works on the basis of object types, which in Java means class types.  So, this rule is making assertions about the existence of some sort of Customer object and another sort of Order object within the Working Memory.  The exact type of the objects themselves isn't relevant -- if we had an EliteCustomer object in our libraries that was a subclass of Customer, it still passes the "instanceof" criteria to be a Customer, and would be a candidate for this rule.

On these types, we can make assertions beyond just the initial assertion that an object of the desired type exists in the WorkingMemory.  We do this by asserting that the object has certain properties.  By "property", we mean anything that the Java Bean Specification would call a property.  So, for the first example above, we're saying something about the 'region' property.  Typically, that means our Customer type has methods with the following signatures:

public void setRegion(int region);
public int getRegion();

The Drools documentation has more details on this, but the important thing is to know that Drools really wants to look at your objects as POJOs that it can use Java Bean introspectors on and get some information about the assertions you're making.

Assertions in a when clause are, by default, implicitly AND'ed together to satisfy a given rule.  So our Order and Customer assertions *are* intimately related.

So, in English, the rule is saying something like this:

when
   There exists in the WorkingMemory an object which is an instanceof Customer (which I'd like to just call $cust from now on for short) whose region property has the value of 1 or more
   AND
   There exists in the WorkingMemory an object which is an instanceof Order, and whose "customer" property must be equal to the $cust reference from the first assertion (here I'm a bit fuzzy about whether this is referential equality -- i.e., they must be the exact same object, or equality via the equals() method -- the Drools guys can correct me), and whose totalAmount property is more than 30).
then
 do something

So, as you can see, with the implicit AND'ing, I'm making a very specific assertion -- as point #1 of your email says.  Point #2 you make is *not* correct; leaving off the "customer == $cust" portion of the rule would make a big difference in the rule, removing the requirement that order and customer match.  Most likely, this is undesirable -- you *want* to be sure to evaluate the rule only for matching customers and orders.  If there ever were a case where a Customer and Order could exist in the system that were not related, then you might have a problem.

Suppose I had the following objects in the WorkingMemory:

Customer A:
 Name = "Bob"
 Region = 2

Customer B:
 Name = "Alice"
 Region = 2

Order C:
 Customer = "Bob"
 totalAmount = 55

Order D:
 Customer = "Alice"
 totalAmount = 60

With the original rule, I'm going to see two firings -- one for the combination of A and C, one for the combination of B and D.  The wording of the rule ensures those are the only combinations that will satisfy it.  However, if I remove the ties between customer and order in the rule, now I'll see a firing of A and C, A and D, B and C, and B and D -- to cover all possible pairings of any customer and any order.  Again, this is probably not what you want.

The Drools guys can correct me on the equality issue, but I think otherwise I've got this correct.

As far as point #4, yes, you can add more specifics to your assertions just like you showed there.  You want to add whatever specifics it takes to ensure the rule only fires for the exact combinations of interest, and it is best to push as much logic as possible into the when condition, so long as you can make those assertions through simple property fields of the object.  It gets more complex when the properties are not amenable to such examination (for instance, there does not exist a no-arg getter for the field of interest; in that case, Drools has to do much more work to pass an argument in, and I believe it cannot cache results for future evaluations, meaning that work has to be done many more times than would be needed for the no-arg case).

Let me know if I was confusing.  This is hard to get at first, you usually have to play with it and look at many examples.
--
Michael J. Suzio
msuzio@xxxxxxxxx
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise