If and switch expressions
In some models one wants to produce different values under different circumstances. Or one needs to convert from one type to another type. if
and switch
expressions provide means to do this in a concise manner. This lesson provides an introduction to both these expressions. For more practical examples, see the simulation model of the synthesis-based engineering example elsewhere in the documentation.
If expression
Consider the following expression:
if x > 0: 1 elif x < 0: -1 else 0 end
This expression takes a real number x
and produces its sign. The if
expression is used to detect the different situations, and to produce the correct result in each of those situations.
An if
expression always consist of the if
and the else
parts. In between can optionally be any number of elif
parts:
if x > 0: 1 elif x < 0: -1 else 0 end
if x > 0: 1 else 0 end
if x > 0: 1 elif x < -10: -2 elif x < 0: -1 else 0 end
If the 'guard predicate' of an if
or elif
(the expression before the :
) holds, that alternative is chosen. In the following example, if x
has a value of 2
and y
a value of 3
, then value -2.8
is produced:
if x > 0 and y = 2: 1.5 elif x > 0 and y != 2 or x < 0: -2.8 else 0.1 end
The if
and elif
alternatives are considered in order. The first alternative that has a guard that holds determines what value is produced by the if
expression. Consider the following if
expression:
if x > 0: 1.5 elif x > 0: -2.8 else 0.1 end
For any value x > 0
, this if
expression produces 1.5
. It will never produce -2.8
, as the if
part is considered before the elif
part.
Switch expression
Similar to an if
expression, a switch
expression can be used to produce different values under different circumstances. Consider the following partial CIF model:
enum mode = OFF, ON1, ON2, ON3, DISCONNECTED;
automaton rotary_switch:
disc mode m = OFF;
...
end
alg int speed = switch rotary_switch.m:
case ON1: 5
case ON2: 10
case ON3: 15
else 0
end;
end
This switch
expression takes the operation mode rotary_switch.m
and provides the speed corresponding to that mode. If the value of m
matches one of the cases, the switch
expression will produce the corresponding value. For example, if m
has value ON2
, this switch
expression produces 10
. If none of the cases match, the value of the else
case is taken. For example, if m
has value DISCONNECTED
, this switch
expression produces 0
. Note that multiple values can be captured by the else
case, i.e., you do not have to cover each possible value with a separate case.
One can use different kinds of types as long as the types of the cases match the type of the switch
expression. In the example above, m
is of type mode
, which is an enumeration. Hence all cases should be of type mode
as well. Below is an example using a ranged integer in the switch
expression:
alg int[0,2] num_products;
alg string display_text = switch num_products:
case 0: "There are no products in the buffer."
case 1: "There is one product in the buffer."
case 2: "There are two products in the buffer."
end;
One can also use an automaton as a variable of the switch
expression, where the cases have to be locations of that automaton:
automaton controller:
location accelerate: ...
location decelerate: ...
location steady: ...
end
alg int acceleration = switch controller:
case accelerate: 5
case decelerate: -3
case steady: 0
end;
Note that in this switch
expression we omitted the else
case, as the three cases together already cover all possible locations of automaton controller
.
It is possible to rewrite a switch
expression into an if
expression (the other way around is not always possible). This rewrite can be automated using a CIF to CIF transformation.