## Merge enumerations

This CIF to CIF transformation merges all enumerations together to a single enumeration.

See also: Convert enumerations to integers and Convert enumerations to constants.

### 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:

- Eliminate component definition/instantiation

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:

- Add default initial values

### 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.

### Optimality

n/a

### 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.