## Convert to interface

This CIF to CIF transformation converts a specification to its interface (also known as skeleton). The interface contains the minimal elements to allow another specification to refer to its constants, types, events, functions and state. The generated interface can for instance be imported in other specifications, if it is undesired to import the full original specification.

The interface generated by the transformation has the same component structure as the original specification, but elements that cannot be referred to by name are removed. Some of the elements that are kept are replaced by simpler elements, such as algebraic variables that are replaced by input variables. There are two variants of this CIF to CIF transformation, one that generates the complete interface, and one that generates a reduced interface (without the functions and input variables of the original specification).

### Example

To give an impression of how the transformation can be used, consider the following example `plant.cif` file, a plant model used for synthesis:

    alg int[0..10] a = 8;
    input bool i;

It defines an integer algebraic variable `a` and a boolean input variable `i`. The value of the algebraic variable is fully defined in the model, while the value of the input variable is not defined in the model, but instead comes from the environment. The model is therefore an open model, with input variable `i` defining the interface to the environment.

If we implement this plant (or the supervisor synthesized from it), we can connect the input variable to the environment of the system. For instance, if we generate PLC code, we can connect it to a PLC input. Similarly, if we simulate the model, we may assign values to the input variable through clicks on an SVG image. Either the PLC or the SVG image then provides a concrete environment for the model, implementing the interface. The environment determines the value of the variable during execution, thus closing the model.

However, in some cases, we may not want to get the value(s) of an input variable from the environment. This can for instance be useful when the plant model is to be simulated, but the input is not provided by the user. Instead, a different (part of the) system — that is outside the scope of the plant model — provides values.

In such cases, the simulation model can be extended, such that it plays the role of the environment. This approach also closes the plant (or supervisor) model.

We may for instance make a simulation model that contains:

    alg bool i = true;

This model gives a concrete value to `i`, by defining it as an algebraic variable. To simulate the plant without user interaction, we need to combine the plant model (or the synthesized supervisor) with the simulation model into a single closed model. We can use the CIF merger tool for this. Note that the separate plant and simulation models are preserved, and we can thus still perform synthesis on the plant model.

In our example case, the CIF merger merges the input variable of the plant model with the algebraic variable of the simulation model:

    alg int[0..10] a = 8;
    alg bool i = true;

All input variables have then been made concrete, giving us the single closed model that we can simulate (in this case completely without user interaction).

We would prefer to have a single model of the plant for synthesis and simulation, rather than two separate models, but that is not possible:

- For synthesis, we want to explicitly leave the value of `i` to be decided by the environment, and we therefore model `i` as input variable in the plant model.

- For simulation, we want to concretely define the value of `i` in the model itself, and we therefore model `i` as an algebraic variable in the simulation model.

- Variable `i` can’t be both an input variable and an algebraic variable in the same model. Therefore, a single model is not possible.

Another reason for having to use two separate models, is that for simulation we may want to use features to specify the value(s) of `i` that are not supported by synthesis. We could for instance want to use a continuous variable in the simulation model:

    cont c = 0 der 1;
    alg bool i = c >= 10 and c <= 20;

The situation becomes more complex when the simulation model is also open. In such a case, it also needs values from its environment, like in this simulation model:

    cont c = 0 der 1;
    alg bool i = a > 3 and c >= 10 and c <= 20;

Since `i` is now defined in terms of both `c` and `a`, we need `a` to be available in the simulation model as well, as without it the model is invalid. Since `a` exists in the plant model, intuitively the solution seems to be to have the simulation model import the plant (or supervisor) model it aims to extend:

    import "plant.cif";
    cont c = 0 der 1;
    alg bool i = a > 3 and c >= 10 and c <= 20;

However, `i` is then defined twice: once as algebraic variable (from the simulation model) and once as input variable (from the plant model). As this is not allowed, the model is invalid. Instead of importing the plant model into the simulation model, we can resolve the missing `a` in the simulation model by defining it as an input variable:

    input int[0..10] a;
    cont c = 0 der 1;
    alg bool i = a > 3 and c >= 10 and c <= 20;

This is a nice solution. The plant model now concretely defines `a` and has `i` as an interface, while the simulation model concretely defines `i` and has `a` as an interface. Each variable is only defined concrete values in one model, and the part of the other model that it needs — but does not want to define — is specified as an interface, providing the minimal information of what it needs. In this way, changes to the concrete values have to made only in one model.

Both the plant model and the simulation model are open models. To simulate them, we can still use the CIF merger to merge them into a single closed model. For the example, merging the models results in:

    alg int[0..10] a = 8;
    cont c = 0 der 1;
    alg bool i = a > 3 and c >= 10 and c <= 20;

While both the plant and simulation models now look good and work as desired, the simulation model now contains the interface of the plant. Input variable `a` in the simulation model duplicates the relevant information about algebraic variable `a` from the plant model. Such duplicates must be kept consistent between the plant model and the simulation model. For instance, if algebraic variable `a` is renamed in the plant model, we have to rename input variable `a` in the simulation model. If we forget to do so, then the simulation model is still valid, but merging the plant and simulation models does not merge the variables anymore, and the simulation will no longer work as expected. Manually updating the plant interface in the simulation model can become tedious when the plant model grows or when large changes occur.

One of the problems in updating the plant interface in the simulation model, is that the simulation model contains both elements for simulation and elements that are part of the duplicated plant interface. We can split off the plant interface part to a separate file, say `plant_interface.cif`, and import that new file in the simulation model. Then it becomes easier to compare the plant model against its interface, and to keep them aligned.

However, the `plant_interface.cif` file still needs to be manually adapted if the plant changes. This Convert to interface CIF to CIF transformation solves that problem, as it automatically generates the plant interface from the plant model. For our example, we use the variant that generates a reduced interface. The reduced interface contains only the part of the interface of the plant that is concretely defined in the plant model, avoiding a duplicate definition of `i`. The transformation generates the following reduced interface:

    input int[0..10] a;

This reduced interface model can be imported into the simulation model, as follows:

    import "plant_interface.cif";
    cont c = 0 der 1;
    alg bool i = a > 3 and c >= 10 and c <= 20;

This simulation model still defines `i` concretely, and has access to `a` defined in the plant model. Since we have not modified the plant model, we can still use it for synthesis. We can also still merge the plant model (or synthesized supervisor) with the simulation model as before, and the merged model is also still as it was before. Furthermore, the plant interface is no longer manually duplicated in the simulation model, reducing the effort to keep the simulation model consistent with the plant model as the plant model evolves.

### Supported specifications

This transformation supports all CIF specifications.

### Preprocessing

No preprocessing is performed by this CIF to CIF transformation.

### Implementation details

The following are removed from the specification:

- Annotations.

- I/O declarations.

- Initialization and marker predicates (in components).

- Invariants (in components).

- Equations (in components).

- Functions (only if a reduced interface is generated).

- Input variables (only if a reduced interface is generated).

- Locations without a name.

- All parameters of component definitions, except for component parameters.

- All arguments of component instantiations for which the corresponding parameters of the instantiated component definitions are removed.

I/O declarations are removed as you can’t refer to them. Similarly, initialization and marker predicates, invariants and equations are removed. And also locations without a name are removed.

The parameters of component definitions are removed, as you can’t refer to them from outside the definitions. The corresponding arguments of component instantiations are then also removed, to ensure the model remains valid. Component parameters of component definitions are preserved, as there could be references to types via these component parameters. Since the component structure is preserved, these can be kept in the interface models.

Functions are only removed if the variant of the transformation is used that generates a reduced interface. If the variant is used that generates a complete interface, then they are obviously not removed.

Input variables are only removed if the variant of the transformation is used that generates a reduced interface. If the variant is used that generates a complete interface, then they are obviously not removed. Note that input variables generated by the transformation (see below) are never removed, regardless of which variant is used, as only input variables from the input model are removed.

Some elements of the specification are replaced:

- An algebraic variable is replaced by an input variable that has the same name and type.

- A continuous variable is replaced by an input variable that has the same name and a `real` type.

- A discrete variable is replaced by an input variable that has the same name and type.

- A location of an automaton with a name is replaced by an input variable that has the same name and a `bool` type.

- An automaton is replaced by a group with the same name.

Algebraic, continuous and discrete variables are replaced by input variables. The values of these variables are thus not specified in the interface specification. Still, this is sufficient to be able to refer to them, and thus serves as a proper interface.

Similarly, locations are replaced by input variables. Everything within locations, such as initialization predicates, marker predicates and edges, are thus removed. The contents of the location can’t be referred to, and the input variable is sufficient as interface for the location.

Automata are replaced by groups, to preserve the structure of the model, and to ensure that the declarations within the automata, such as their locations that become input variables, keep their absolute names. The declarations of the automata, such as types, constants, and discrete variables turned input variables, are all preserved in the groups. The other details of the automata, such as their alphabets and monitors, are removed. These details are also not relevant for an interface model, as you can’t refer to them. Similar to automata becoming groups, also automaton definitions become group definitions.

Note that various elements of the specification are explicitly kept:

- Component definitions and instantiations.

- Constants.

- Enumerations.

- Events.

- Groups.

- Input variables (only if a complete interface is generated).

- Type declarations.

- User-defined functions (only if a complete interface is generated).

The resulting interface specification may consist of these elements as well:

- Annotations (only a single `@@partial` annotation, see below).

- Component definitions and instantiations.

- Constants.

- Enumerations.

- Events.

- Groups.

- Input variables.

- Type declarations.

- User-defined functions (only if a complete interface is generated).

If a reduced interface of a model is imported into another model, that other model can be merged with the original model, assuming nothing else in the other model prevents such a merge.

### Renaming

n/a

### Size considerations

Various elements of the specification are removed, or replaced by simpler elements, reducing the size of the specification.

### Optimality

n/a

### Annotations

This transformation removes all annotations from the specification. Subsequently, a partial specification annotation is added to the specification.