Types of loops
- Last Updated: March 24, 2022
- 5 minute read
- Corticon
- Version 6.3
- Documentation
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 from the Corticon Studio menubar, as shown:
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:
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:
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.
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 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:
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.
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).
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.