I'm not sure if I understand why you would want to do this; maybe I need
more background.  From my first reading of what you're describing, the flow
of rules should be fine (I don't see the recursion).  I also see mutually
exclusive conditionals, so that's not a problem either (none of the rules
you're showing overlap, so you're only going to assert one risk object).

Let me write some DRL that I think describes what you want to do, and you
can tell me if I'm getting it wrong.  Consider it pseudo-code, I might not
be getting all the syntax right but we'll stick with intent here:

package creditrules;

rule CheckHighRisk
when
 $credit: CreditReport(credit_score <= 500)
then
RiskCategory rc = new RiskCategory("HIGH");
assertLogical(rc);
end

rule CheckMediumRisk
when
$credit: (CreditReport(credit_score >= 501, credit_score <= 600)
then
RiskCategory rc = new RiskCategory("MEDIUM");
assertLogical(rc);
end


rule CheckLowRisk
when
$credit: (CreditReport(credit_score >= 501, credit_score <= 600)
then
RiskCategory rc = new RiskCategory("LOW");
assertLogical(rc);
end

#
# This rule is going to fire as soon as the RiskCategory is asserted and
meets
# the criteria of being High risk
#
rule IfHighRiskDecline
when
$risk : RiskCategory(categoryType == "High")
then
CreditAction action = new CreditAction("Decline");
assertLogical(action);
end

#
# This rule is going to fire as soon as the CreditAction of "Decline" gets
# asserted
#
rule HandleDeclineAction
when
$action: CreditAction(type == "decline")
then
# Do something with that action object that sends documents or whatever
end

That would be some rough DRL.   I added bindings for each rule match only
because I find it's handy to do so; often I'll at least be doing some
System.out calls inside the consequence to make sure I'm matching what I
think I should match while developing the rules.  Each rule potentially
creates some new facts that serve to trigger other rules.  This is the way a
rules engine works -- as facts are introduced into the system, they may
create new facts.  The firing of the rules continues until there are no new
facts to process, but until that is reached, every new fact that is asserted
*may* trigger (or retrigger) any rule it matches.

I would use it like this, taking advantage of the fact that I did
assertLogical() calls for all my assertions, so that retracting the
CreditReport results in implicit
retraction of all the "child" objects I might have created:


//
//  Code Sample
//
RuleBase rulebase = .... // create a rulebase somehow

WorkingMemory wm = rulebase.newWorkingMemory();
List<CreditReport> reports = getAllCreditReportsToProcess();

for (CreditReport report : reports)
{
 // Assert the report to process
 FactHandle handle = wm.assertObject(report);
 // Fire the rules
 wm.fireAllRules();
 // Retract that report, and essentially start "fresh"
 wm.retractObject(handle);
}

Note that if you had some side effects happen as a result of the
fireAllRules() call, you'll want to also reset those conditionals.

Now... *if* I missed something here, and you do need some ordering of the
rules, you have many options:

1) Use salience values to determine what runs in what order.  This can be
tricky, but if used sparingly, can solve the problem.
2) Use the "no-loop" directive to ensure that a rule cannot re-trigger
itself by calling modify() on an object that was used as part of the
qualifier for the
rule.  This can be *very* important to do -- usually you'll realize this
fairly quickly, as you get an infinite loop for that rule.
3) Use agenda-groups.  I had a very long example here, but I'll hold that
off until I can be sure I'm pointing you in the right direction.  However,
agenda-groups *do* provide
a way to order activations, by explicitly setting focus to whole groups of
rules and ensuring those rules all run before the implicit MAIN group (that
all rules belong to by default if not
put into another agenda-group) runs.

You can do a lot with agenda-groups.  I've found that they are a complex
subject, however -- it took me many days of playing around to use them
correctly in my engine.  Perhaps if you restated what you think your problem
is, I may be able to offer some help.

---
Michael J. Suzio
[EMAIL PROTECTED]

Reply via email to