Merge enumerations
This CIF to CIF transformation merges all enumerations together to a single enumeration.
Supported specifications
This transformation supports a subset of CIF specifications. The following restrictions apply:
Component definitions and component instantiations are not supported.
Preprocessing
To increase the subset of specifications that can be transformed, apply the following CIF to CIF transformations (in the given order) prior to using this transformation:
The following CIF to CIF transformations are automatically applied as preprocessing (in the given order), to increase the subset of CIF specifications that can be transformed:
Implementation details
If there are any enumerations in the specification, a single new enumeration is created. This enumeration is named E
. All literals of the original enumerations are added to this new enumeration. Obviously, duplicate literals are only included once. The literals are added in sorted order.
The original enumerations are removed.
For instance, the following specification:
enum A = B, C;
automaton p:
enum A = C, B;
enum X = D, C;
disc A a = C;
disc X x = D;
location:
initial;
end
is transformed to the following specification:
enum E = B, C, D;
automaton p:
disc E a = C;
disc E x = D;
location:
initial;
end
Renaming
The newly created enumeration E
and its literals, may conflict with declarations already present in the specification. If this is the case, they are renamed. For instance, if E
is already in use, E2
, or E3
, etc, is used instead. If renaming is performed, a warning is printed to the console.
In general, renaming of enumeration literals may influence value equality for compatible enumerations (enumerations with the same number of literals, with the same names, in the same order). However, since the resulting specification has at most one enumeration, there are no multiple enumerations, and thus compatibility is not an issue (since the enumeration is always compatible with itself).
Default initial values
Consider the following specification:
group g1:
enum e1 = A, B;
end
group g2:
enum e2 = B, A;
end
automaton p:
disc g1.e1 v1;
disc g2.e2 v2;
location:
initial;
end
If we apply merging of enumerations directly, we get the following:
enum E = A, B;
group g1:
end
group g2:
end
automaton p:
disc E v1;
disc E v2;
location:
initial;
end
In the original specification, v1
had value A
, and v2
had value B
. After the merging of the enumerations, both v1
and v2
have implicit initial value A
. Thus, they had different initial values beforehand, and the same initial values afterward. To solve this problem, the Add default initial values CIF to CIF transformation is automatically applied as preprocessing before the actual elimination of the enumerations, to ensure that the explicit initial values are properly transformed.
Switch expressions
Consider the following specification:
enum E1 = A, B;
enum E2 = C, D;
input E1 i;
invariant switch i:
case A: true
case B: false
end;
After merging the enumerations, the single merged enumeration has four literals (A
, B
, C
and D
). The switch
expression is then incomplete, as it does not cover the extra literals from E2
(C
and D
) that got merged with E1
. To ensure that switch
expressions remain complete and valid, all switch
expressions that switch over a value that has a type that includes an enumeration type, but do not have an else
, are modified. Their last case
is converted to an else
, removing the key of the case
in the process. For the example above, this results in:
enum E = A, B, C, D;
input E i;
invariant switch i:
case A: true
else false
end;
Size considerations
Since enumerations are merged, duplicate literals become a single new literal. Therefore, this transformation may decrease the size of the specification.
The added default initial values may significantly increase the size of the specification.
Removing the key of the last case
of a switch
expressions may slightly decrease the size of the specification.
Annotations
This transformation does not process or add any specific annotations. The annotations of the original automata are moved to the enumeration declarations of the newly created location pointer enumerations, but only for automata with at least two locations. Similarly, the annotations of the original locations are moved to the enumeration literals of the newly created location pointer enumerations, but only for automata with at least two locations. For automata with a single location, the annotations of the automata and their locations are removed. The single new automaton and its single new location do not have any annotations.