When working with business decisioning, it’s common to have dependencies between conditions. Let’s see how we can work with such rule dependencies.
Dependencies between rules exist when the conditional expression of one rule evaluates data produced by the Action of another rule. The second rule is said to be “dependent” upon the first.
The first step in learning to use looping is to understand how it differs from normal inferencing behavior of executing rules, whether executed by Progress Corticon Studio or Server. When a Rulesheet is compiled (either by Studio during a Ruletest execution, or by Server during deployment), a dependency network for the rules is automatically generated. Corticon Studio and Server uses this network to determine the order in which rules fire in runtime.
To illustrate, let’s consider a medication prescribing scenario. Certain drugs are prescribed based upon a patient’s weight, but the prescriber must also consider whether the patient is overweight or underweight. When a patient is within the bounds of a clinically healthy weight, then that weight will serve as the input for calculating an appropriate dosage.
If a patient is 20-30% above their ideal body weight, then this input is adjusted—for some medications, instead of the patient’s actual weight, an adjusted body weight is calculated. For other medications, their ideal body weight is used.
In a Corticon rulesheet, we can implement all the necessary dosage guidances based upon their weight, sex, height and prescribed medication.
If we open the execution sequence diagram, we see how Corticon will evaluate data against these rules, using the default inferencing mechanism in Corticon called “Optimized Inferencing.”
Optimized Inferencing processing is a powerful capability that enables the rule modeler to “break up” complex logic into a series of smaller, less complex rules. Once broken up into smaller or simpler rules, the logic will be executed in the proper sequence automatically, based on the dependencies determined by the compiler.
An important characteristic of Optimized Inferencing processing: the flow of rule execution is single pass, meaning a rule in the sequence is evaluated once and never revisited, even if the data values (or data “state”) evaluated by its Conditions change over the course of rule execution. These rules are perfectly handled with the default Optimized Inferencing option.
When we test this rule sheet using the test case of a male patient who is 62 in. tall, 70 kg, with a prescription for Acyclovir, the order of execution of the rules is determined by Corticon based upon the logical dependencies between the rules.
Opening the Rule Trace panel, we see the order of the executed rules was rule #3, rule #2, rule #B0, rule #8, rule #7 and finally rule #11.
We can see how Corticon has made these inferencing decisions by viewing the logical dependency graph.
Occasionally, we want rules to be re-evaluated and re-fired (if satisfied). This scenario requires the
Corticon rule engine to make multiple passes through the same Rulesheet.
Any time a rulesheet has more than one rule, unless they are from completely different contexts (i.e., do not share any of the same aliases), they naturally have logical dependencies with each other. These logical dependencies can be seen by navigating to the Rulesheet menu -> Logical Analysis -> Logical Dependency Graph.
If there are no loops in the logical dependency graph—and in most cases, there will not be—then the rules can be processed by the default processing mode. This is because the Corticon engine automatically processes the rules in a sequence that considers the logical dependencies: Each rule is processed after all the other rules that it’s logically dependent on. As a result, the rulesheet can be processed in a single pass with no need for iteration. This is the most efficient means of processing the rules in a rulesheet because it only requires a single pass.
Here’s the key to understanding looping: when a looping processing mode is enabled, rules will be continually re-evaluated and re-fired in a sequence determined by their dependency network if data state has changed since their last firing. Once data state no longer changes, looping will cease.
Some loops, especially those inadvertently introduced, are not self-terminating. Because these loops will not end by themselves, they are called infinite loops. Infinite loops can be especially vexing to a rule modeler because it isn’t always apparent when a Rulesheet has entered one. A good indication, however, is that rule execution takes longer than expected to complete! A special control is provided to prevent infinite loops.
In some scenarios, the rules in a rulesheet happen to have a loop in their dependency graph. For example, when Rule 3 is dependent on Rule 1 which is dependent on Rule 2 which is dependent on Rule 3. In such a case, there is no clear way for the engine to “flatten out” the rules to a sequence. In fact, there are multiple valid sequences:
Furthermore, it may not be possible to achieve the desired solution by processing these rules in a single pass although in many cases this works just fine. So, we may need to keep iterating over the loop until no more rules fire. For example, we may need to process the above rules as follows: Rule 2 → Rule 1 → Rule 3 → Rule 2 → Rule 1 → Rule 3 → …
When this is the case, you can determine which of the two Advanced Inferencing modes are turned on based on the following steps.
If Optimized Inferencing mode does not produce the desired outcome, then perform a Logical Loop check on the rulesheet via the menus Rulesheet, Logical Analysis, Check for logical loops. If there are no logical loops, there is no reason to enable Advanced Inferencing (or to artificially try to create loops). If no loops are present, then Corticon will automatically generate the optimum code to execute the rules. Revisit your rule logic to determine why we are not getting the desired outcome.
When logical loops are found, a dialog box appears listing all the logical loops. If the dialog box reports that there are any self-triggering rules (e.g., Rule: IF a > 1 THEN a += 1) listed at the bottom of the logical loop dialog box:
With “Advanced Inferencing,” the rules will be re-evaluated and re-fired if they are satisfied. The loop is stopped because Condition A is not satisfied anymore. This is illustrated in the following rulesheet:
The outcome is:
Advanced Inferencing is needed when the conditions of some of the rules may be affected by the actions of other rules and the rules must be reevaluated when a rule’s action changes a value. Advanced Inferencing (when it is needed) is likely to be less efficient since it may need to reevaluate the same rules multiple times as the conditions are changed by other rules. Normal rule processing only evaluates each rule once.
Here, extra conditions are added. However, the first condition will stop the loop ([Cargo.weight]=21) before the second condition is evaluated ([Cargo.Volume]<531).
The outcome is the same as before:
Advanced Inferencing with Self-Triggering is needed when the conditions of a rule may be changed by its own actions (or the actions of another rule) and that rule must be reevaluated when the values change. Independent rules will not be re-evaluated when using Advanced Inferencing. Independent rules will be re-evaluated when using Advanced Inferencing with self-triggering and the rule depends logically on themselves.
For example, consider a set of workforce management rules which must plan into advance scheduling for a project across multiple workdays. The rules must assign a specified number of workdays for the project but consider both weekends and holidays.
The rules in this rulesheet do the following:
When we run the logical loop test upon these rules, we see several reported:
This window first identifies exactly which rules are involved in loops. Secondly, the window outlines the specific attribute interactions that create the loops.
When Weekday.nextWorkDay is a weekend day or holiday, then rules 1 or 4 fire to increment the next workday’s day of week. Data state has now changed, in other words, the value of at least one of the attributes has changed.
Because it was also Rule 1’s or Rule 4’s execution that caused the data state change, and since self-triggering is enabled, the same Rules 1 and 4 will be reevaluated until the day of the week is not 1 or 7 and is not a holiday.
We can see this in action by defining a ruletest like that shown below. The calendar dates of holidays are defined as November 23, November 24 and December 25 of 2023. When the weekday to be evaluated is November 22, 2023, then the value of the attribute Weekday.nextWorkDay is evaluated three times to “reach” the right answer of November 27, 2023.
Seth Meldon is a Pre-Sales Engineer with a primary product focus area of Progress Corticon Business Rules Engine. His work is focused on educating and demoing Corticon’s expansive functionalities, use cases, and architectural strategies to internal and external audiences. You can follow Seth on LinkedIn.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.Learn More
Subscribe to get all the news, info and tutorials you need to build better business apps and sites
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.