[Progress News] [Progress OpenEdge ABL] A Difference in Inference: Handling Interdependencies Between Rules

Status
Not open for further replies.
S

Seth Meldon

Guest
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.

Coritcon rulesheet with dosage guidelines for weight, sex, height for drug and patient

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.”

Logical Analysis menu option selected with Execution Sequence Diagram below that


Optimized Inferencing example with flow chart steps




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.

Patient input and output with height, sex, weight, drug. Drug uses adjusted body weight

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.

Rule Trace shows sequence of rules needed and applied

We can see how Corticon has made these inferencing decisions by viewing the logical dependency graph.

logical dependency graph diagrams decision chart

Types of Logical Loops​


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.

Rulesheet menu - Logical Analysis - menu options include execution sequence diagram, Logical Dependency Graph, clear analysis results, check for logical loops, check for completeness, check for conflicts, etc.


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.

Advanced Inferencing: Handling Intentional Logical Looping​


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:

  • Rule 2 → Rule 1 → Rule 3
  • Rule 1 → Rule 3 → Rule 2
  • Rule 3 → Rule 2 → Rule 1

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:

  1. If the self-triggering rules do not result in infinite loop(s) (e.g., Rule: IF a > 1 and stop = F THEN a += 1, stop = T) then we use Advanced Inferencing with Self-Triggering.
  2. If they do result in infinite loop(s), we use Advanced Inferencing to avoid the infinite loop(s).

Understanding Advanced Inferencing​


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:

advanced inferencing with cargo weight and volume

The outcome is:

Rule Messages tab with severity, message, entity

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).

cargo weight exceeds the rule

The outcome is the same as before:

Rule Messages tab with severity, message, entity

Understanding Advanced Inferencing with Self-Triggering​


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:

  • Set the attribute Weekday.nextWorkDay to today’s date + 1 by default, in the action only zero column.
  • If that next workday is a holiday, then again add 1 to the next workday date.
  • If the next workday’s day of week = 1 (Sunday), then add 1 to the next workday date.
  • If the next workday’s day of week = 7 (Saturday), then add 2 to the next workday date.

When we run the logical loop test upon these rules, we see several reported:

Window identifying which rules are in loops and which attribute interactions create the loops.

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.

Holiday 1, Holiday 2, Holiday 3, Weekday 1 - next workday 11 27 2023

Continue reading...
 
Status
Not open for further replies.
Top