3.5 WHILE Loops

Ensuring that WHILE Loops Terminate

WHILE loops should be structured with a BREAK clause immediately after the WHILE statement. They may have further BREAK clauses later on as well, but an initial BREAK clause ensures that the loop will terminate after a known number of iterations rather than the upper limit CNTLE(LOOP,1). If the number of elements in the loop is a variable, it should be tested to check that it is greater than zero:

IF     ( ?NUM LE 0
          OR WHILE ?INUM
                 AND ( ?INUM LT ?NUM OR BREAK ?INUM )
                 AND < loop code >
        )

Changing CNTLE(LOOP,1) within the Code

WHILE loops suffer from the problem that there is an absolute upper limit on the number of iterations, CNTLE(LOOP,1). This is fixed when a program is linked and can only be changed within code if the program is relinked before the new limit is used. If there is a risk that the upper limit may be breached, it should be tested and reset, as shown here:

IF     ( ?NUM LE CNTLE(LOOP,1)
          OR CNTLE(LOOP,1) = ?NUM
             AND LINK
        )
AND    ( ?NUM LE 0 
          OR WHILE ?INUM
                 AND ( ?INUM LT ?NUM OR BREAK ?INUM )
                 AND < loop code >
        )

Using an IN Loop instead of a WHILE Loop

It is undesirable to be changing one of the control parameters for the Aspen SCM Expert System within the code of a rule. It is better to avoid the problem by using an IN loop over a loop set (RULELOOP in this example) which is “owned” by the rule and which is resized as required:

IF     ( ?NUM LE 0
          OR RULELOOP = ?NUM
             AND ?INUM IN RULELOOP
                 AND < loop code >
        )
Note that where a loop set is resized by a rule, that loop set must not be used by another rule which is calling this one; in particular the rule must not be recursive.

Sometimes the number of iterations of a loop may not be known when the loop is started but only becomes apparent as it is executed. This may appear to suggest use of a WHILE loop as one does not need to declare the upper limit at the start. But this is illusory as the upper limit is actually CNTLE(LOOP,1) . Instead an upper bound should be calculated on the number of iterations and then the loop should be implemented as an IN or WHILE loop over this number of elements with an appropriate BREAK statement.


Back                                Next
Comments