Condition Processing

A Condition in SMI++ is a Boolean expression composed of a combination of Boolean operators {and, or, not}, brackets { ( , ) } and Boolean statements.

In SMI++ these Boolean statements are so called Simple Conditions (SC) and are of the following 4 types:

type1 ( 'object-name' in_state 'state-name' )
type2 ( all_in 'objectset-name' in_state 'state-name' )
or
(any_in 'objectset-name' in_state 'state-name' )
type3 ( 'objectset-name' is_empty )
type4 ( 'item1' relational-operator 'item2' )
NB: this type is used for testing values of parameters. See details bellow.

NB: more advanced use for experts of 'object-name' and 'objectset-name' in type1, type2 and type3, see Variable Elements in SML

NB: in the above one can also have not_in_state instead of in_state and not_empty instead of empty

A condition is translated (decomposed) by SMI Translator in the following way: all the Simple Conditions (SC) are extracted and a series of elementary Boolean operations or Condition Instructions (CI), which are either binary or unary, is generated. At run time, firstly all the SCs are evaluated  and then the series of CIs is then evaluated from the beginning to the end with the result of the last CI being the overall desired answer. There are 3 possible forms of these CIs:

  1. operand1 and operand2
  2. operand1 or operand2
  3. not operand1

where operand1(operand2) is either result of evaluation of one of the SCs or one of the previous CIs.

Example:

( ( A in_state ERROR ) or (B in_state ERROR) ) and ( LHC in_state PHYSICS)

The following simple conditions are extracted:

SC1:( A in_state ERROR ); SC2:(B in_state ERROR); SC3: ( LHC in_state PHYSICS)

and the series of CI generated:

CI1 : result-of-SC1 or result-of-SC2

CI2 : result-of-CI1 and result-of-SC3

In 'normal' circumstances the result of evaluation of SC as well as CI is either TRUE or FALSE.

The complication arises when one or more simple conditions of type2 refer to empty set. We adopted rather ad-hoc way of dealing with this situation:

In addition to the two values TRUE and FALSE, we introduced yet another value which we call GHOST and define it as follows:

When simple condition of type2 refers to empty set, it's value is by definition GHOST.

For evaluation of CI we adopted the following rules:

In most common situations, it works like if the simple conditions referring to empty sets were not present. This is probably what one would like to do. The problem is when the overall result is GHOST. In this case we replace this result with FALSE. In case of when instructions this is exactly what is required. In case of if instructions it is not ideal because it will cause execution of else part of if (if any) without any justification. Obviously the better thing would have been to ignore the if instruction altogether.

Simple Condition Type4

Format:

( item1 relational-operator item2 )

Where:

item1(2)
are indiValues as described in indiValue
relational-operator is one of the following:
< less than
> greater than
<= less than or equal to
>= greater than or equal to
== equal to
<> not equal to

Generally, the comparison is done only between items representing values of the same type. If items do not represent values of the same type, then this can be achieved by type casting of one of them or both. See below.

Item Type Casting and Type Mixing

Format:

(cast-indicator)item

Where

item
is as described above
cast-indicator is one of the following:
string, int, float

example: (int)run-type

In this example run-type is a name of parameter that has been declared as string and this way it's value is temporarily cast into integer. And therefore can be compared with other integer values.

Restrictions

There are two basic restrictions which are imposed already at translation stage:

  1. Casting item representing constant value e.g. (float)3
  2. Casting item representing string value into floating point value

    In addition, at running (State Manager) stage:

  3. Casting item representing string value into integer when the string can not be interpreted as such.

When type casting is used, then Translator insists that both items (after casting) are of the same type

When type casting is not used and the items represent values of different types, then Translator will attempt its own type casting and will produce warnings (and possibly errors) in the process :