Apologies if this question has been addressed before.
We generate our Drools rules automatically from a business rules repository we've had
here for years.
Currently, our code generator is doing something I'd rather not have to do - it
inspects assignments on the RHS and inserts "anti-recursion" logic into the
LHS.
This leads to rules like the following:
rule "RS6631.1.2"
no-loop true
dialect "mvel"
when
$policySet : PolicySet
(
marketType == MarketTypeEnum.FHA
# anti-recursion logic derived from assignments in action section
, isSetSelectedDecisionIndicator == false
|| selectedDecisionIndicator != true
# end anti-recursion logic
)
then
modify($policySet)
{
selectedDecisionIndicator = true
};
end
Notice the two lines between the comments - the code generator has analyzed the assignment
on the RHS and has inserted this defensive logic in order to prevent (possibly infinite)
re-firings of this rule anytime other rules also update the PolicySet object. This
approach does not work in all scenarios, however, and there is an occasional struggle by
our rule analysts to find ways to suppress the loops caused by rule "A" updating
an object versus rule "B" updating the same object, even when the attributes
changed by the two rules are different.
The root issue, I believe, is that the modify and update require fact handles that refer
to whole objects, not to individual attributes of those objects. When an attribute value
is updated, my intuition suggests that only the new value of that attribute should be
propagated through the network, not the whole object. Re-propagating the entire object
causes all rules that have already fired to be reactivated, since their conditions are
still true. All we really want is that the rules whose conditions NEWLY match both the
unchanged attributes and the changed attributes should be activated, not rules that
matched previously on the unchanged attributes and whose CE's or constraints have not
been affected by the change.
I've seen several conversations on this list about how to prevent infinite loops.
"No-loop" only seems to work within the context of the current rule. Two rules
that update an object, even if their changes are to non-overlapping attributes, cause each
other to be reactivated in the absence of some defensive logic like that shown above.
"Lock-on-active" doesn't appear to achieve the goal either, because it
suppresses firings that might in fact be desired.
Feel free to educate me if my limited understanding is showing here.
But does anyone know of a way to tell the Drools engine to only propagate the attributes
that have changed, and not the entire object?
Tom Murphy
Wells Fargo HCFG - CORE Deal Decisioning Platform