3.6 Jumping out of a Loop

Simply Jumping out of a Loop

The simplest approach to
jumping out of a loop is to do just that. Provided the purpose of the
rule is to undertake some processing and there are no return arguments,
this approach may suffice. A typical rule is:

IF ?ITEM IN SET AND <intermediate code> AND ( <test' on ?ITEM> OR <further code for successful ?ITEM> AND BREAK ?ITEM )

THEN < predicate >

This loops over elements of SET, does some intermediate
calculations and then performs <test' on ?ITEM>. This
is the complement to the test which we want ?ITEM to pass, i.e. test'
is TRUE if ?ITEM fails <test on ?ITEM>. If <test' on?ITEM>
is TRUE, the code proves the predicate and then loops back to set
?ITEM to the next value in SET. These iterations continue until
<test' on ?ITEM> is FALSE, i.e. <test on ?ITEM> is
TRUE, when it executes further code for the successful ?ITEM and then
BREAKs out of the loop.

Problems with a Simple Jump

This code performs all the calculations
which need to be done but has two problems:

it never proves the predicate if the
first ?ITEM in SET passes <test on ?ITEM>;

it doesn’t support passing the
successful ?ITEM back as a return argument on the predicate.

When the rule finishes without proving the predicate its status is
UNKNOWN. This means that the “Error on Unknown” flag must be set
to NO. This is unfortunate because the “Error on Unknown”
processing also detects unrecognised predicates, which are usually
caused by mistakes. As a result, mistakes which would otherwise have
been detected may persist in code.

Allowing Rules to End UNKNOWN

If the program is an old one with many rules liable to end
UNKNOWN, it may be accepted that the “Error on Unknown” flag has to be
set to “NO”. Such rules should be protected by having OR TRUE clauses immediately after assertion of the predicate.

In order to avoid
inadvertent misuse, it is recommended that any rule which is liable
to end UNKNOWN should only be called from within its own ruleset,
i.e. it should be a sub-rule within a ruleset rather than the main
rule. This may involve writing a “jacket” rule as the main rule
in a ruleset: such a jacket rule just asserts the predicate with an
OR TRUE after it.

Better Alternatives

There are two main ways
of tackling the problems of jumping out of a loop:

the delayed BREAK, where a flag is set
ready to break out of the next iteration;