Yeah, the docs rightly state that you shouldn't depend too heavily on a given rule
firing order:
Scroll down to "3.3.4.1. Conflict Resolution"
They also say that the default strategies are salience and LIFO, so the example I gave
might just work by accident. :) I'll have to peek at the source tonight to be sure.
--- On Wed, 9/2/09, Bill Tarr <javatestcase(a)yahoo.com> wrote:
From: Bill Tarr <javatestcase(a)yahoo.com>
Subject: [rules-users] Trouble getting Dynamic Salience working - add in rules-templates
To: rules-users(a)lists.jboss.org
Date: Wednesday, September 2, 2009, 2:26 AM
Thank you for the response Greg.
For starters, I did NOT know about specificity... very
helpful to know, and I feel certain I will be using it in
the future. I don't feel any of the documentation I've
read on Drools really got this subject across for me, I not
sure the the Drools developer book really covers it at
all.
Back to my actual implementation. We are
using rules-templates, which have a "unique behavior" I've
been calling a feature, but some might consider a bug...
or have found a way to work around. Templates do
not render rule lines which contains NULL parameters.
This hasn't bit my too badly to this point, but MAY pose an
interesting issue for specificity (now that I know about
it!)
My real world example is a good bit more
complicated. My LH includes:
PARAMETERS
--------------------------
Product - NOT NULL
Start Date
End State
Price Group - NOT NULL
State Group
Some of the info is coming from a single instance of an
object I'm calling "transporter" I use to gather info from
other rules. It will have a list of state groups and price
groups. So psuedocode for my template LH will look
something like:
template.pricegroups.contains( "@{PRICE_GROUP}" )
template.stategroups.contains( "@{STATE_GROUP}" )
policy (
startDate >
@{START_DATE}
endDate < @{END_DATE}
product = "@{PRODUCT}"
)
The problem I run into here, is that in any given rule,
only a subset of these will appear. So one rule may
produce:
// this rules parameters have a NULL STATE_GROUP
template.pricegroups.contains( "pg1" )
policy (
startDate > 2009-01-01
endDate < 2010-01-10}
product = "prod1"
)
and another might produce
// this rule has a STATE_GROUP, but no START_DATE and
END_DATE
template.pricegroups.contains( "pg1" )
template.stategroups.contains( "NY" )
policy (
product = "prod2"
)
In this example, I actually want the SECOND rule to win the
conflict. It is "more specific" for our business rule, a
policy for NY should match, but the the first rule should
not. In reality, the first rule has more facts, so which
one will actually fire first by rules of specificity?
My activation-group and salience hack was one workaround
for this condition. I set the second rule with a higher
salience, and add them both to the same activation-group.
I will try different combinations of rule-templates and
specificity when I am in the office tomorrow (midnight here
in San Diego.) If you have any further feedback on this, I
do appreciate your taking the time to show a Drools newbie
some very useful stuff.
Thanks!
Bill
Message: 2
Date: Tue, 1 Sep 2009 19:29:40 -0700 (PDT)
From: Greg Barton <greg_barton(a)yahoo.com>
Subject: Re: [rules-users] Trouble getting Dynamic Salience
working
To: Rules Users List <rules-users(a)lists.jboss.org>
Message-ID: <52492.42683.qm(a)web81501.mail.mud.yahoo.com>
Content-Type: text/plain; charset="iso-8859-1"
I hope you're not going through all of that trouble just to
get the functionality from that concrete example. You get
that for free with Drools' default conflict resolution,
which includes "specificity." Specificity means that rules
with the more specific conditions, and all else equal, are
fired first. So between these two rules, only the
CheeseSausagePepperoniPepper one fires:
rule "CheeseOnly"
when
p : Pizza( )
t1: Topping( pizza == p, name == "cheese" )
then
System.out.println( "Eating cheese pizza" );
retract( t1 );
retract( p );
end
rule "CheeseSausagePepperoniPepper"
when
p : Pizza( )
t1: Topping( pizza == p, name == "cheese" )
t2: Topping( pizza == p, name == "sausage" )
t3: Topping( pizza == p, name == "pepperoni"
)
t4: Topping( pizza == p, name == "pepper" )
then
System.out.println( "Eating cheese sausage
pepperoni pepper pizza" );
retract( t4 );
retract( t3 );
retract( t2 );
retract( t1 );
retract( p );
end
See the attached project.
--- On Tue, 9/1/09, Bill Tarr <javatestcase(a)yahoo.com>
wrote:
> From: Bill Tarr <javatestcase(a)yahoo.com>
> Subject: [rules-users] Trouble getting Dynamic
Salience working
> To: rules-users(a)lists.jboss.org
> Date: Tuesday, September 1, 2009, 7:28 PM
> We have a winner!? Many thanks
> Michal, hope I can return the favor one day.
>
> salience ( return getSalience4() )
>
> for the record, my function looks something like
(after
> tempate evaluation):
>
> <pre>
> function int getSalience4(){
> ??? int salience = 0;
> ??? if("VALUE"=="VALUE") salience += 1000;
>
> ??? return salience;
> }
> </pre>
>
> I think the combination activation-group and dynamic
> salience for rule-template projects are pretty useful.
>
> Just for anyone interested,?the tempate code looks
> something like this:
>
> <pre>
> rule "Some Rule_(a){row.rowNumber}"
>
> ??? activation-group "@{PARAM1}-@{PARAM2}"
> ??? salience ( return getSalience(a){row.rowNumber}() )
> </pre>
>
> where PARAM1 and PARAM2 make up a kind of key. I only
want
> to execute one rule that matches that key, no matter
how
> many options there are.
>
> Rules that have additional parameters get higher
salience
> than rules with less parameters, so here is my
function.
>
> <pre>
> function int getSalience(a){row.rowNumber}(){
> ??? int salience = 0;
> ??? if("@{PARAM3}"=="@{PARAM3}") salience += 1000;
> ??? if("@{PARAM4}"=="@{PARAM4}") salience += 1000;
> ??? return salience;
> }
> </pre>
>
> A concrete example could be pizza.? So there are?3
types
> of pizza, all are grouped in the same
activation-group.
>
> cheese, pepperoni
> cheese, pepperoni, sausage
> cheese, pepperoni, meatball, pepper
>
> Any cheese and pepperoni pizza should could match all
these
> rules, but more toppings is always better for me.
>
> So cheese, pepperoni, onion, pepper getts a salience
of
> 2000, and is the only rule evaluated.
>
>
>
> On Tue Sep 1 18:39:13 EDT 2009, Michal Bali michalbali
at
> gmail.com? wrote:
>
> does this work?
> salience ( return getSalience() )
>
> or this:
>
> salience ( getSalience();)
>
>
> On Tue, Sep 1, 2009 at 6:50 PM, Bill Tarr
<javatestcase
> at yahoo.com> wrote:
>
> > Possibily just a simple MVEL error, but I've
been
> struggling for a while
> > and thought I'd see if anyone could help.
> >
> > I just want to run a logic test to determine
salience
> for some rules I am
> > generating with rules-templates.??Even after
making
> the logical test "true"
> > I can't get any of variation to compile.
> >
> > (true ? "1000" : "0")
> > **produces**
> > Unable to build expression for 'salience' : not
a
> statement, or badly
> > formed structure
> >
> > ( true ? 1000 : 0)
> > **produces**
> > Unable to build expression for 'salience' :
invalid
> number literal: 1000
> >
> > salience ( getSalience() )
> > ...
> > function int getSalience(){return 0;}
> > **produces**
> > Unable to build expression for 'salience' :
> org.mvel2.util.MethodStub
> > cannot be cast to java.lang.Class'(
> getSalienceNONCDW() )'
> >
> > Seems like I am missing something simple, but
I've
> tried many variations on
> > the above, and have been unable to find any
working
> examples of using a
> > logical test in salience, so if anyone has any
> direction it would be greatly
> > appreciated.
> >
> > Thanks!
> >
> > Bill
>
>
> ? ? ?
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users