Hi Michael thanks for the quick response. As I understand it if I ran the
rules right now irrespective of salience (since this doesn’t impact the
agenda) the IfHighRiskDecline rule would not run on the first fireall. For a
credit score of 200 the only rule that would only evaluate to true would be
the CheckHighRisk. This would place onto the agenda RiskCategory= “HIGH.”
When this action is taken the rule set would be called again because the
working memory has been modified. On this pass the CheckHighRisk rule would
evaluate to true placing on the agenda the RiskCategory=High and the
IfHighRiskDecline rule would evaluate to true placing on the agenda the
CreditAction=Decline. When these objects modify the working memory it will
cause the rules to fire again, which isn’t true recursion but is
inefficient, as it will cause the amount of rule that evaluate to true to
increase with the number of stacked rules.

I guess it would be prudent to validate an assumption that I have, that
whenever working memory is modified the rule set is rerun?

This is all theoretically right now, as I was trying to anticipate the
problem, I’ll code it up and see how it works… Again, thanks for you time.

-punkij


Michael Suzio wrote:
> 
> 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]
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Rule-Execution-Flow-tf2884245.html#a8059052
Sent from the drools - user mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply via email to