Type Inference of Simulink Hierarchical Block Diagrams in Isabelle

Simulink is a de-facto industrial standard for the design of embedded systems. In previous work, we developed a compositional analysis framework for Simulink models in Isabelle -- the Refinement Calculus of Reactive Systems (RCRS), which allows checking compatibility and substitutability of components. However, standard type checking was not considered in that work. In this paper we present a method for the type inference of hierarchical block diagrams using the Isabelle theorem prover. A Simulink diagram is translated into an (RCRS) Isabelle theory. Then the Isabelle's powerful type inference mechanism is used to infer the types of the diagram based on the types of the basic blocks. One of the aims is to handle formally as many diagrams as possible. In particular, we want to be able to handle even those diagrams that may have typing ambiguities, provided that they are accepted by Simulink. This method is implemented in our toolset that translates Simulink diagrams into Isabelle theories and simplifies them. We evaluate our technique on several case studies, most notably, an automotive fuel control system benchmark provided by Toyota.


Introduction
Simulink is a widespread tool from Mathworks for modeling and simulating embedded control systems.A plethora of formal verification tools exist for Simulink, both from academia and industry, including Mathwork's own Design Verifier.Formal verification is extremely important, particularly for safety critical systems.Formal verification techniques make steady progress and are increasingly gaining acceptance in the industry.
At the same time, we should not ignore more "lightweight" methods, which can also be very beneficial.In this paper, we are interested in particular in type checking and type inference.Type checking is regularly used in many programming languages, as part of compilation, and helps to catch many programming mistakes and sometimes also serious design errors.Type inference is a more advanced technique which usually includes type checking but in addition permits types to be inferred when those are not given by the user, thus automatically extracting valuable information about the design.Importantly, both type checking and type inference are typically much less expensive than formal verification.We therefore view both of them as complementary to formal verification for the rigorous design of safety-critical systems.
Simulink already provides some kind of type checking and inference as part of its basic functionality.In the version R2016b that we used while writing this article, the user has to open a diagram and then click on Display → Signals & Ports → Port Data Types, upon which Simulink (computes and) displays the typing information, for example, as shown in Fig. 1.Unfortunately, Simulink analyses are proprietary, and as such it is difficult to know what type checking and inference algorithms are used.Moreover, the way Simulink uses the typing information is often strange, as illustrated by the examples that follow.Consider first the two diagrams shown in Fig. 1.Both these examples capture implicit type conversions performed by Simulink.In both diagrams, there are two Constant blocks, with values 2 and 3 respectively.In the first block, we manually set the output type to be Boolean.This is done by clicking on the block and setting its Output data type under Signal Attributes.In the second block we manually set the output type to double.The outputs of the two constants are fed into an Add block which performs addition.In the rightmost diagram, the result is fed into an Integrator.The block Scope plots and displays the output over time.
Both diagrams of Fig. 1 are accepted by Simulink, meaning that they can be simulated.Although Simulink issues a warning that says "Parameter precision loss occurred . . .A small quantization error has occurred."the results of the simulation appear as expected: a constant value 4 in the case of the leftmost diagram, and a straight slope from values 0 to 40 for the rightmost diagram, when simulated from 0 to 10 time units.Simulink performs an implicit conversion of 2 to the boolean value true, and then another implicit conversion of true to the real value 1, in order for the addition to be performed.These implicit conversions are stipulated in the Simulink documentation (when the source block allows them).Therefore, the result is 3 + 1 = 4.
Although these examples seem unsual, they are designed to be minimal and expose possible problems, similar to those detected in a Fuel Control System (FCS) benchmark provided by Toyota [8].It is common practice to mix, in languages that allow it, Boolean and numeric values in a way exposed by these examples.We have tested this behavior extensively and we have observed that other languages that perform automatic conversions between Boolean and numeric values behave consistently with Simulink (e.g., C: (double)3 + (bool)2 = 4.0, Python: float(3) + bool(2) = 4.0).Now, consider the diagram shown in Fig. 2, where the output of the same Boolean constant block as the one used in the previous diagrams is fed directly into the integrator.In this case, Simulink rejects this diagram (meaning it refuses to simulate it).It issues an error message saying: "Data type mismatch.Input of Integrator expects a signal of data type 'double'.However, it is driven by a signal of data type 'boolean'."The Integrator, as well as other block types, accepts only inputs of type double and implicit conversions (from Boolean to double or vice-versa) are not allowed and performed.We remark that Simulink does not treat diagrams in a consistent way with respect to typing.One of the goals of this paper is to present a formal type checking and inference framework for Simulink, where such examples are treated consistently (and meaningfully).
The contribution of this work is a type inference mechanism for Simulink diagrams, on top of the type inference mechanism of the Isabelle theorem prover [11].One important feature of this approach is handling Simulink basic blocks locally, without knowledge of their environment.The challenge of this work is embedding the more relaxed type system of Simulink into the formal type system of Isabelle, while preserving the semantics, and as much typing information as possible.We apply this technique to several case studies, including the FCS benchmark.
This work is part of a larger project on translating Simulink diagrams into Isabelle theories suitable for analysis and verification.Because Isabelle's language is formal and precise, we can directly obtain concise and correct code in other languages that can be used for processing Simulink models.For example from the Isabelle model we easily obtain Python code for simulations, and Z3 SMT solver [3] model for automatically checking properties.

Related Work
The verification of Simulink diagrams has been extensively studied in the literature, by proposing model transformations of Simulink diagrams to a formal framework.Formal frameworks include Hybrid Automata [1], BIP [17], NuSMV [9], Boogie [15], Timed Interval Calculus [2], Function Blocks [20], I/O Extended Finite Automata [21], Hybrid CSP [22], and SpaceEx [10].Many of the target formalisms define a typing feature, and the proposed model translations make use of it: a basic block is mapped to some "expression" on inputs and outputs, where the types of inputs and outputs are dependent of the block type.The static type checking is then delegated to the target framework, if such functionality is available.However, these studies mostly aim for formal verification of Simulink diagrams and do not report about type checking.Also, it is unclear to what extent the model transformations perform an analysis of inputs/outputs dimensions (scalar, vector, and matrix) to be used in the generated expressions.
The most relevant work with respect to type checking Simulink diagrams is described in [19] and [16].In [19], a model transformation from discrete-time Simulink models to Lustre is presented, where type inference is used for computing the inputs/outputs type.Then the Lustre analyser performs type checking on the obtained model.In [16], the SimCheck contract framework for type checking the mathematical aspects of Simulink blocks is described.SimCheck allows the user to annotate ports and wires with types, but also with their units (e.g., cm).A translation to Yices [6] supports the automated checking of component compatibility within the model with respect to static and behavioral types.In contrast to SimCheck, we automatically infer the types and dimensions of signals from the Simulink diagrams, but we do not infer or check for physical units.
In previous work, we have presented the Refinement Calculus of Reactive Systems (RCRS) [13,5], a compositional framework for static analysis of hierarchical block diagrams in general, and Simulink models in particular.In the RCRS framework blocks are specified syntactically by general formulas (contracts) on input, output, and state variables.These contracts are then composed using serial, parallel and feedback composition operators.Such contracts can be seen as richer types, and the compatibility and contract synthesis methods developed in RCRS can be seen as type checking and type inference techniques.However, the contracts considered in RCRS are much more powerful than the types considered in this paper, and the compatibility and synthesis algorithms of RCRS are much more expensive (requiring in general quantifier elimination and satisfiability checking in expressive logics).Therefore, the framework proposed in this paper is much more lightweight.
In this work we use the Isabelle theorem prover which has a standard type inference mechanism.Our goal is to give an embedding of Simulink into a language and framework suitable for further processing (simplifications, checking of properties, and even simulation).Other systems for logical reasoning (PVS [12], Z3, . . . ) could also be used for this purpose.Some of the problems encountered in our translation may have simpler solutions in these systems, but some other aspects may become more difficult.All translation attempts to languages that do not allow automatic conversions between Boolean and numeric values would have similar challenges as the ones that we solve here.

Isabelle
Isabelle/HOL is an interactive theorem prover based on higher order logic.Isabelle provides an environment which consists of a powerful specification and proving language and it has a rich theory library of formally verified mathematics.Notable features of Isabelle include a type system with type inference, polymorphism and overloading, and axiomatic type classes.
Isabelle's type system includes the basic types bool, real, int, nat, type variables a, b, etc., and predefined type constructors a → b (functions from a to b) and a × b (Cartesian product of a and b).For term f (x, g(y)) we can specify that it has a type t by using : t after the term f (x, g(y)) : t.Isabelle uses type inference to deduce the type of a term.For example the next declaration introduces a function The type of f is the most general type such that the expression f (x)(y)(g) = g(x)(y) is well typed.A type t is more general than a type t if t can be obtained from t by instantiating the type variables in t with some type expressions.
We can also use lambda abstraction to define f : The term f (λx.g(x))(y) has the type (( We can also use specific types in definitions: In our translation of Simulink to Isabelle we use the type inference mechanism.
Another important feature of Isabelle that we use is the type classes [7].This is a mechanism that can be used, for example, to overload a polymorphic function + : a → a → a on different types for a.
We define the type class plus with the constant + of polymorphic type a → a → a, and two instantiations to natural and real numbers.In a term x + y, the type of x and y is not just a type variable a, but a type variable a of class plus.This is represented syntactically as x : a : plus.The terms (x : nat) + y and (x : real) + y are well typed because the types nat and real are defined as instances of plus.Moreover, in the term (x : nat) + y, the plus operator is the one defined in the instance of nat : plus, while x + y does not in general have a definition.The term (x : bool) + y is not well typed because bool is not defined as an instance of plus.
Classes in Isabelle may contain also assumptions, in addition to constants.These are axioms for the class, and they must be proved as theorems in instantiations.Classes can also extend existing classes.For example we can introduce a semigroup (a set with an associative binary operation) class as an extension of the plus class: instantiation nat : plus instance proof . . .proof that + for nat is associative . . .This is a very powerful mechanism that allows for modular and reusable developments.We can have type classes that in addition to the assumptions contain many theorems, and when we create an instantiation of the type class and prove the assumptions, then all these theorems become available for the instance also.

Representation of Simulink Diagrams as Predicate Transformers
A (fragment of a) Simulink diagram is modeled intuitively as a discrete symbolic transition system with input, output, current and next state.The intuition behind this representation is the following.Initially, the current state has a default value.The system representation works in discrete steps, and, at each step, it updates the output and the next state based on the input and the current state.For example, an integrator block like the one from Fig. 1 is discretized as a system parameterized by dt > 0, with input x and current state s, and output y := s and next state s := s + x • dt.
Formally, we model these systems in Isabelle as monotonic predicate transformers [4], mapping predicates (sets) over the output and next state into predicates (sets) over the input and current state.A monotonic predicate transformer S with input x, current state s, output y and next state s , for a set q of pairs (y, s ), S(q) returns the set of all pairs (x, s) such that if the execution of S starts in (x, s) then S does not fail and results in a pair (y, s ) ∈ q.A detailed discussion of the choice for this semantics is outside the scope of this paper, and is extensively presented in [13,18,5].
In Isabelle, the integrator block is represented as the predicate transformer and it has the type a → ( a : In what follows we do not make a distinction between the input and current state, and output and next state, respectively.In general, a Simulink diagram is modeled as a predicate transformer with input (and current state) of a type variable a, and output (and next state) of a type variable b.The type of this predicate transformer is ( b → bool) → ( a → bool) and we use the notation a • → b for it.Often a and b will be Cartesian products, including the empty product (unit).We denote by () : unit the empty tuple.
For a predicate transformer mapping, for example, inputs (x, y, z) into output expressions Using this notation, the constant and the integrator blocks become We denote by Id the identity predicate transformer ([x x]).A block diagram is modeled in Isabelle as an expression of predicate transformers corresponding to the basic blocks, using three composition operators: serial (•), parallel ( ), and feedback (fb).The serial composition of predicate transformers is exactly the composition of functions.The parallel and feedback compositions are described in [5,14].We just mention here that the parallel composition of [x e(x)] and [y f (y)] is [x, y e(x), f (y)].For this presentation, the typing of these operations is important.The typing of the serial composition is standard.The parallel and feedback compositions have the types: Using these notations, the predicate transformer for the rightmost diagram from Fig. 1 is given by We use here the Id predicate transformer to model and connect the current state of the integrator.We also use the polymorphic function s_bool which for 2 returns True if the type of the result is Boolean, and 1 if the type of the result is real.The type of the result in this case is real as it is inferred from the addition block (following the constant blocks).

Arity of Simulink Wires
Simulink blocks are modeled in our Isabelle based framework by monotonic predicate transformers.Yet, certain basic blocks require special attention when translating them.A first example is provided in Fig. 3a.
which is different from Mux.In order to solve this problem, we consider that all (sub)diagrams have as input and ouput tuples of single values, and not tuples of tuples.The parallel composition is one construct which does not preserve this property.Ideally we would define the parallel composition such that it splits the input tuple in two and concatenates the output tuples into a single one.Unfortunately, this cannot be easily achieved in Isabelle, because concatenation of tuples of arbitrary length cannot be expressed.
The solution is to use the parallel composition together with explicit splitting of the input and concatenation of the output: and this is now equal to Mux.However, to be able to do this we need to know how many signals are transferred on wires.This is not a local property (it does not depend only on the type of the current block).For example if we analyze the diagram from Fig. 3a, we see that Mux 1 has as output a tuple with four elements, and this can be inferred only by analyzing the entire diagram.So for every wire we need to compute its arity (the number of transferred signals).
The algorithm for computing the arities is given in Fig. 4 using classes to represent blocks in a Python style syntax.A diagram is represented as an instance x of the subsystem class that contains a list of basic blocks or subsystems (x.blocks).Each block x (basic or subsystem) has a list of input ports and a list of output ports (x.inport and x.outport).All ports p have arities (p.arity), and initially they are all set to 1.A wire between two blocks x, y in the diagram is represented by a port which is output port for x and input port for y.The idea of the algorithm is that it updates for every block the arities of the output ports, based on the arities of the input ports (function x.update_arity()).The function returns True if a change occurred, and False otherwise.Because of how wires are implemented, a change in the arity of an output port would result in a change in the arity of an input port of a connected block.We compute the arities of the diagram x using function x.compute_arity().We iterate x.update_arity() until the computation converges (there are no more changes) or until we exceed a bound on the number of iterations.The function x.compute_arity() returns True if the computation converges and False otherwise.The bound must be chosen such that the computation converges if and only if it converges within this bound.Using the total number of basic blocks in the model as the bound guarantees this property, regardless of the ordering of blocks.
However, there are diagrams for which the computation does not converge.An example is illustrated in Fig. 5.In this diagram, the arities of the input and output ports change continuously due to the feedback wire from Delay to Mux.This diagram is also not accepted by Simulink for simulation for the same reason.An alternative solution to the translation of mux blocks would be to use lists of values instead of tuples.Then we can define more easily the parallel composition (concatenation of lists is associative), but we would loose the typing information for individual inputs and outputs.In this situation we would need to use a single type that contains all values possible in a diagram (Booleans, reals).Another drawback of this approach would be also that we could not detect statically problems that occur when the algorithm from Fig. 4 does not converge (like in Fig. 5).By using a system like PVS that supports dependent types, we could improve the list representation of inputs and outputs to account for specific types of individual inputs.Yet, the convergence problem of the arity calculation needs to be solved by proving a type constraint condition theorem in these systems.

Constant Blocks
Simulink diagrams may contain constant blocks, parameterized by numeric constants.These are blocks without input and with one single output which is always equal to the constant's parameter.By default, Simulink constants do not have associated types.In order to have the possibility to instantiate these types later for reals, integers, Booleans, or other types, we use uninterpreted constants.By default, numeric constants in Isabelle are polymorphic.If no type is explicitly set to a constant in a term t = 12, then Isabelle associates a type variable a : numeral to this constant.If the term is used in a context where the type is more specific (t = 12 ∧ Suc(t) = t ) then Isabelle uses the type class instantiation to the specific type (in this case natural because of the successor function).
Due to this polymorphic treatment of constants, in some contexts it arises the problem that the types of these constants are not part of the type of the resulting predicate transformer.Consider for example the diagram from Fig. 6a.The Isabelle definition for this diagram is In this definition a is the inferred type of constants 1 and 2. The problem with this definition is that the type a is not part of the type of Compare : unit • → bool.If this definition would be allowed, then we will True] which is false.In order to instantiate unit for a, the type unit must be of class numeral.Although by default this is not the case in Isabelle, we can easily add an instantiation of unit as numeral and obtain this contradiction.
Isabelle allows this kind of definition, but it gives a warning message ("Additional type variable(s) in specification of Compare : a : numeral"), and it defines the function Compare to depend on an additional type variable: Compare When we generate the definition for the diagram from Fig. 6b we do not know that Compare needs the additional type parameter.To have control over the type parameters we add them systematically for all constants occurring in the diagram.However, using just type variables as parameters still results in several problems explained next.Assume again that we have three constants as in Fig. 6b.We define the three constant blocks as follows: and the diagram from Fig. 6b as: The problem with this definition is that both outputs of ConstA and ConstB are entering the same comparison block.This implies that the two constants must be of the same type.However, since we used the explicit type variables a and b, Isabelle cannot unify them.An alternative definition is to use the same type for all constants: We would need to use the same type for all three constants because we do not know during translation that only the types of ConstA and ConstB should be unified.This information could be extracted through type inference during translation, however our aim is to use Isabelle's mechanism for this feature.The drawback of this solution is that although, in the original diagram, the type of constant ConstC is independent of the  types of ConstA and ConstB, in this definition they are unified.We would like to obtain a definition of A where the types of constants ConstA and ConstB are unified, and the type of ConstC is independent.For this we define the constants with a variable parameter and the diagram is defined by In this approach, variables x, y, z are used only to control the types of the constants.In this definition, because outputs of ConstA and ConstB are entering the comparison block, the types of x and y are unified.
If we need an instance of A for type real for constants ConstA and ConstB and type Boolean for ConstC, then we can specify it using the term A(x : real, y : real, z : bool).This definition mechanism is implemented in our Simulink to Isabelle model translator under the −const option.When the option is set, then the constants are defined as in (1), and the diagrams using these constants are defined as in (2).When the option is not given, then the constants are defined as in:

Conversion Blocks
Simulink diagrams may also contain conversion blocks.The type of the input of a conversion is inherited and the type of the output is usually specified (Boolean, real, . . .).However we can have also situations when the output is not specified, and it is inherited from the type of the inputs of the block that follows a conversion.In Fig. 7a we illustrate an explicit conversion to real, while Fig. 7b presents an unspecified conversion.
As with the other blocks we want to define these conversions locally, without knowing the types of the inputs and outputs, when the output type is unspecified.In doing so, we use the overloading mechanism of Isabelle.Overloading is a feature that allows using the same constant name with different types.For the this coincides with the semantics of And in Simulink.However, if the input y is Boolean, then the expression y = 0 is not well typed, unless we add additional class instantiation in Isabelle: Intuitively this instantiation provides the interpretation of constant 0 as False, when 0 is used as a Boolean value.With this the expression (y : bool) = 0 is equivalent to y = False and it is equivalent to y.The same holds for the expression 1 : bool which is not well typed unless we provide an instantiation of bool as numeral, where every (non-zero) numeral constant is True.These definitions formalize the behavior described by Simulink in its documentation.Using this approach, the translation of the diagram from Fig. 6c is: and it is equal to because y is of type bool and (y = 0) = y.If we expand the serial composition and simplify the term, we obtain [() (3 : a : {numeral, zero}) = 0].The equality (3 : a : {numeral, zero}) = 0 cannot be simplified.This is because the type a : {numeral, zero} has all numeric constants 1, 2, . . .(numeral) and the constant 0 (zero), but no relationship between these constants is known.If we know that we only use the type a with instances where the numeric constants 1, 2, . . .are always different from 0, then we can create a new class based on numeral and zero that has also the property that n = 0 for all n ∈ {1, 2, . ..}. Formally we can introduce this class in Isabelle by The new class numeral_nzero contains the numeric constants {0, 1, 2, . ..} but also it has the property that all numbers 1, 2, . . .are different from 0 (∀a.numeral(a)= 0).In this property a ranges over the binary representations of the numbers 1, 2, . ... This property is called numeral_nzero, and the [simp] declaration tells Isabelle to use it automatically as simplification rule.Now the equality (3 : a : numeral_nzero) = 0 is also automatically simplified to True.
We provide the following class instantiation: Because in this class we have also the assumption (∀a.numeral(a) = 0), we need to prove it, and it trivially holds because False = True.Similarly we need to introduce instantiations of numeral_nzero to real, integer, and natural numbers.In these cases, since real, integer, and natural are already instances of numeral and zero, we do not need to define 0 and numeral(a), but we only need to prove the property (∀a.numeral(a) = 0).With this new class, the translation of diagram from Fig. 6c becomes: (Const(1.5: Because of the properties of types real, bool, and a : numeral_nzero, it is equal to and, after expanding the serial composition and symplifying the term, we obtain [() True].
Although the translation of Boolean blocks is rather involved, the result obtained especially after basic Isabelle simplifications is simple and intuitive, as shown above.Moreover, for the translation of a Boolean block we do not need to consider its context, and the correctness of the translation can be assessed locally.Basically an element e in a conjunction (e ∧ . ..) is replaced by ((e = 0) ∧ . ..).By creating the class numeral_nzero and the instantiations to bool and real, the typing of e (e : bool or e : real, . ..) defines the semantics of the expression e = 0.

Generic Translations
The approach described so far works well for diagrams that do not mix values of different types (Boolean, real) in operations.However, there are some diagrams that are accepted by Simulink and cannot be translated with the approach described above due to type mismatch.Fig. 1 and 2 give three examples of this kind of diagrams.
Fig. 1 illustrates diagrams accepted by Simulink, while the diagram represented in Fig. 2 is not accepted by Simulink.The simulation of leftmost diagram from Fig. 1 gives 4 (2 : bool results in True, and then converted to real is 1).The rightmost diagram from Fig. 1 is equivalent to a diagram where constant 4 is input for an integral block.However none of these diagrams result in correct translations when using the method presented so far.This is due to type mismatches: In the first case, we try to add a Boolean to a real.The second example contains the first example as a sub-diagram, and it has the same type incompatibility.In the third example the output of Const(2 : bool) of type bool is used as the input for the first component of [(x : real), s s, s + x • dt] which expects a real.To be able to translate these diagrams, we use type variables instead of the concrete types bool, real, . ... Because we work with expressions containing arithmetic and Boolean operations, we need to use type variables of appropriate classes.For example, to translate the leftmost diagram from Fig. 1, we cannot just use an arbitrary type a because a must be of class numeral for the constants 2 and 3, and of class plus.In fact only class numeral is required here because plus is a subclass of numeral.The generic translation of this diagram is: In this translation, we only need to specify the types for the constants as discussed in Section 5.However, when we use the type variable a for numeric constants 1, 2, . .., then we must specify it using the class numeral.
If the expression involving the elements of type a contains some other operators, then we must include also the classes defining these operators.For example we need to have: ConstA(x : a : {numeral, mult}) = Const((2 : a) • 3).To simplify this we introduce a new class simulink that contains all mathematical and Boolean operators as well as all real functions that can occur in Simulink diagrams.The inferred type of A is A(x : a : simulink, y : a, dt : a) : a • → a × a In this generic translation there are some details to consider when translating a constant block of type Boolean like the ones from Fig. 1 (2 : bool).In order to use A(x, y, dt) in the end, we still need to instantiate the type variable a.In this case, it would be appropriate to instantiate a with type real.If we simply use Const(2 : a) in definition of ConstA, then when instantiating a, we will obtain the constant 2 and we will add it to 3 resulting in 5, and this is not the result obtained when simulating the diagram in Simulink.To preserve the Simulink semantics in the generic case, we translate Boolean constants using a function s_bool which for a parameter x returns 1 if x is different from 0 and 0 otherwise: The typing of x : a and of s_bool(x) : b defines again a more precise semantics for s_bool(x).For example if both a and b are bool, then s_bool(x) = x.
Assume now that we have an expression with type variables of class simulink In the instantiation to type real we have chosen to implement the Boolean operations using real numbers.This definition is motivated by expressions that mix Boolean and real values as in the examples from Fig. 1.This formalization is fair, but also sufficient, because the Boolean values can be easily embedded within the real numbers.However, when we have an addition block Add : ( a : simulink) × a • → a in the generic translation it does not make sense to instantiate a to bool.If we do so accidentally, at least we do not provide definitions for the arithmetic operations within the Boolean domain.This will prevent any simplifications to occur for the wrongly interpreted expressions.However, we must provide definitions for the numeric constants 1, 2, . .., otherwise we cannot prove the assumption numeral_nzero for the Boolean instantiation.If we choose not to use the assumption numeral_nzero in simulink then we do not need these definitions, except for 1 that plays the role of True.
We implemented this strategy in our Simulink to Isabelle model translator under the −generic option.When this option is missing, then all blocks are defined using their specific types.If this option is given, then only type variables of class simulink are used.
Additionally, we implemented the option −type isabelle_type with an Isabelle type parameter, which adds a new definition where it instantiates all type variables to the type parameter.
For example, if we apply the translation using the options −const, −generic, and −type real to the rightmost diagram from Fig. 1, we obtain: In the generic version s_bool( 2) is automatically simplified to 1 using the definition of s_bool and the assumption numeral_nzero, and in A_type the expression 1 + 3 is further simplified to 4. In A_type we can eliminate the variables providing types for constants because these types are now instantiated to real.

Implementation and Correctness
The mechanism presented above for translating Simulink diagrams is implemented in the Refinement Calculus of Reactive Systems framework, available from http://rcrs.cs.aalto.fi.In this framework, Simulink diagrams are translated into Isabelle theories, where diagrams are modeled using predicate transformers.The framework allows to perform various analysis on the formal model such as simplification, compatibility checking, safety property verification and simulation.
In order to handle a large set of diagrams, we introduced three translation options: −const, −generic, and −type isabelle_type, where each solves different possible corner cases.These options allow some control over the translation process.
The option −const must be used when the diagram contains constants with types that are not reflected in the overall type of the diagram.In general these diagrams can be seen as pathological, and they can be re-factored to eliminate this problem.The option −const can be used for all diagrams, but when this issue is not present, it generates additional parameters that are not needed.Because well designed diagrams do not have this problem, we designed the translation such that the −const option is disabled by default.
The option −generic is needed in diagrams that mix Boolean and numeric values.When using this option, the typing of the translation is more general than the typing of the original diagram, as we use type variables everywhere.However, if some Boolean values are used in numerical calculations (like in Fig. 1), then the same type variable is used for the Boolean values as well as for the numerical expression.The idea is that this type variable is instantiated to the numerical type (by the user) and all Boolean operations are implemented using numbers.This is the only situation when a type of the original diagram (Boolean) is translated into a different (numeric) type.We can also see this case as pathological, and the user can decide to add explicit conversions in the diagram to avoid this problem.
Finally, the option −type isabelle_type does not influence the translation itself, but it can be used to easily instantiate all type variables in the translation to a given Isabelle type.This is the only option that may produce a more concrete translation, compared to the original Simulink diagram.
In most cases the translation results in representations that are more general (with respect to typing) than the original diagram.The only exception is when Boolean values in numeric expressions are used, as noted above and in Section 8. Instantiating the remaining type variables can be done such that the types of the translation match the types inferred by Simulink.Obtaining a more general typing ensures the correctness of this approach.When Boolean constants and operations are implemented using numeric constants and operations, the correctness is also ensured because this implementation is quite straightforward and standard.
We have extensively tested all combinations of interactions of numeric and Boolean blocks, and we carefully implemented the observed behavior.We have also tested this technique on several case studies, as well as an industrial example: the Fuel Control System (FCS) benchmark from Toyota [8].We validated our approach by simulation.We translated the Isabelle systems into Python and we simulated them, resulting in the same behavior (modulo a small simulation error) as the Simulink simulation.All examples have been translated using all combinations of the options.In each case the results obtained were as expected: either a type mismatch or the same values as those provided by Simulink simulation.For the FCS case study, when translating it only with the −const option, we have detected a type mismatch which was not signaled by Simulink.An easy correction is to add a conversion block.Even though Simulink, as well as other programming languages, implicitly perform this conversion we believe that having a fully correct type checked model will increase the confidence of the generated code.
b, c, d) (b) Equivalent Mux block

Figure 3 :
Figure 3: Diagrams motivating the arity notion and computation.
and use Id for all mux blocks.Using this technique the translation of the first diagram is [(a, b, c, d) (a, b), (c, d)] • (Id Id) • [(a, b), (c, d) (a, b, c, d)] • Id = Id

Figure 6 :
Figure 6: (a) Comparison on constants, (b) Comparison into conjunction, (c) And on typed constants ( a : numeral) = (Const(2 : a) Const(1)) • [x, y x = y] Now Compare(real) and Compare(unit) are different terms, so they are not equal anymore and we cannot derive [() False] = [() True].Assume now that we compose the Compare block with a conjunction block as in Fig. 6b.A = (Compare Const(1)) • And However, this definition is now incorrect because Compare has an additional type parameter.The correct definition would be: A( a : numeral) = (Compare( a) Const(1)) • And