IF Instruction

The statement conditionally executes a block of instructions. Additionaly it provides a blocking mechanism preventing further execution of the action from which it is invoked untill all the objects referenced by IF reach a stable state.

Syntax:

IF (condition) THEN

instructions

ELSE IF (condition) THEN

instructions

ELSE

instructions

END IF

Where:

condition         is described in detail here

instructions     is one or more SML instructions

Example:

if ( TAPE1 in_state END_OF_TAPE or ALARM in_state ON) and ( RUN not_in_state DORMANT) then do STOP RUN end if

The ELSE IF and ELSE clauses are both optional. You can have as many ELSE IF clauses as you want in an IF instruction, but no ELSE IF clause can appear after an ELSE clause. IF instructions can be nested within each other. This means that the instructions can contain other IF instructions.

Roughly speaking the instruction behaves in the usual fashion as in the most programming languages namely:
When an IF instruction is encountered, the condition following the IF clause is tested. If the condition is TRUE, the instructions following THEN are executed. If the condition is FALSE, each ELSE IF (if there are any) is processed one by one in the order in which they are specified. When a TRUE condition is found, the instructions immediately following the clause THEN of the associated ELSE IF are executed. If no condition evaluates to TRUE, or if there are no ELSE IF clauses, the instructions following ELSE are executed. After executing the instructions following THEN, or ELSE, execution continues with the instruction following END IF.

In SMI++ this is more complicated due to the possibility that it could be impossible, at a given moment, to evaluate the conditions. This is because some of the objects, on which the conditions depend are either executing an action, or actions are pending to be executed for some of these objects. An additional complication also arises from the fact that, during the execution of the IF instruction, the contents of some of the object sets on which the conditions depend could change.


IF instruction processing:

First a few definitions:

REF-OBJECT - an object which is referenced in a given condition, i.e. on which the condition depends. This can be either direct or indirect through a membership in an object set.

REF-OBJECT-SET - an object set which is referenced in a given condition.

LOCKED-OBJECT - idle object prevented from executing actions

FROZEN-OBJECT-SET - an Object Set that has been made 'frozen'. To make an object frozen is to make a copy of its contents at a given instance. Subsequently, even if the real contents changes, the copy is used.

When State Manager (further as SM) starts processing the IF, it attempts to lock the REF-OBJECTs in all the IF's conditions. Locking is possible only when the object beiing 'locked' is idle and there are no actions waiting for execution of that object. If locking is not possible, a locking request for that object is issued. (This locking request will eventually lock the object after the actions pending were executed.)

There are now two possibilities:

  1. there are some REF-OBJECTs that are now waiting for the lock.
    In this case all the REF-OBJECT-SETS are made frozen, and the IF processing is suspended and consequently is suspended the execution of the action that contains the IF. State Manager will continue with its other business. (It will eventually return to continue the execution of the suspended IF and its parent action when it receives a signal that all the IF's REF-OBJECTs were locked.)
  2. All the REF-OBJECTs are locked.
    In this case the conditions are evaluated one by one. When no TRUE condition is found, the IF instruction terminates, and SM continues with execution of the next instruction after END IF. (Unless the block ended with MOVE_TO instruction.) If TRUE condition is found, then REF-OBJECT-SETs are defrosted(made unfrozen) and the instruction block following the associated ELSE IF is executed. This can result in the following possible outcomes:
    1. The execution of the block is suspended because of a suspension of one of its instructions.
      In this case the IF processing is suspended and so is the execution of the action that contains the IF. State Manager will continue with its other business. It will eventually return to continue the execution of the suspended IF and its parent action when it receives a signal that the instruction that caused the suspension is ready to continue.
    2. The execution of the block completes.
      In this case the locks from all the locked objects are removed and SM continues with the instruction after the END IF. ( Unless the block ended with MOVE_TO instruction.)

NB: This behaviour can be changed by using option Unlocked IFs (see here). When set to 1, then REF-OBJECTs are unlocked once conditions are evaluated.