Infinite loops

In the Loop iterations example, looping between rules 2, 3, and 4 continues indefinitely because there is nothing to stop the cycle. 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 is not 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. This control is described in the Terminating infinite loops topic.

Trivial loops

Single-rule loops, or loops caused by rules that depend logically on themselves, are also known as trivial loops, a special kind of loop because they consist of a single rule that successively revisits, or triggers, itself.

To enable the self-triggering mode of looping, select Rulesheet > Processing Modes > Advanced Inferencing with Self-Triggering from the Corticon Studio menubar, as shown:

Figure 1. Selecting Advanced Inferencing with Self-Triggering processing mode for a Rulesheet

Notice the icon to the left of the Conditions header. It contains an additional tiny arrow, which indicates self-triggering is active.

Here is an example of a loop created by a self-triggering rule:

Figure 2. Example of an infinite single-rule loop

When Cargo.weight has a value equal to or greater than 0, then rule 1 fires and the value of Cargo.weight is incremented by 1. Data state has now changed—in other words, the value of at least one of the attibutes has changed. In this case, it is the value of Cargo.weight.

Because rule 1 executing that caused the data state change, and because self-triggering is enabled, the same rule 1 will be re-evaluated. Now, if the value of Cargo.weight satisfies the rule initially, it will do so again, so the rule fires again, and self-triggers again. And so on, and so on. This is also an example of an infinite loop, because no logic exists in this rule to prevent it from continuing to loop and fire.

An exception to self-triggering

Self-triggering logic can also be modeled in Column 0 of the Rulesheet, as shown:

Figure 3. Example of an infinite loop created by a self-triggering rule

This figure is also a good example of why it might be appropriate to disable self-triggering processing. You only want the weight to increment once, not enter into an infinite loop, which it would otherwise do, unconditionally. This is a special case where you intentionally prevented this rule from iterating, even though self-triggering is enabled. This rule will execute only once, regardless of the loop processing mode.

Another example of a loop caused by self-triggering rule, but one which is not infinite, is shown in the following figure. The behavior described only occurs when Rulesheet processing mode is set to Advanced Inferencing with Self-Triggering.

Figure 4. Example of a finite single-rule loop

In the preceding figure, the rule continues to fire until Cargo.weight reaches a value of 21, whereupon it fails to satisfy the condition, and firing ceases. The loop terminates with Cargo.weight containing a final value of 21.

It is important to note that in all three examples, an initial Cargo.weight value of 0 or higher was necessary to activate the loop. A negative (or null) value, for example, would not have satisfied the rule's condition and the loop would not have begun.

Multi-rule loops

As the name suggests, multi-rule loops exist when two or more rules are mutually dependent. As with single-rule loops, the Rulesheet containing the looping rules must be configured to process them. This is accomplished as before. Choose Rulesheet > Processing Mode > Advanced Inferencing from the Studio menubar, as shown previously in Selecting advanced inferencing processing mode for a Rulesheet.

Here is an example of a multi-rule logical loop:

Figure 5. Example of a finite multi-rule loop

In the figure, rule 2 is dependent upon rule 1, and rule 1 is dependent upon rule 2. Rule 3 was also added, which does not participate in the 1—2 loop, but generates a Violation message when the 1—2 loop finally terminates. Note, rule 3 does not cause the 1—2 loop to terminate, it just announces that the loop has terminated. Now you will see how they behave. In Ruletest for the multi-rule Rulesheet, you see a simple Ruletest.

Figure 6. Ruletest for the multi-rule Rulesheet

Cargo.weight has a starting value to get the loop going. According to the condition in rule 1, this value must be between 1 and 10 (inclusive).

Figure 7. Ruletest for the multi-rule Rulesheet

When intentionally building looping rules, it is often helpful to post messages with embedded attribute values (as shown in the Rule Statements section of Figure 5) so we can trace the loop's operation and verify it is behaving as expected. It should be clear to the reader that the Ruletest shown in Ruletest for the Multi-rule Rulesheet contains the expected results.