CAPÍTULO IV: CONCLUSIONES Y RECOMENDACIONES
Anexo 1. Test de pensamiento creativo de Torrance (expresión figurada)
1 /* post: return ->forAll(c|
c.modes ->collect(m| Signatures(m))->oclAsSet () ->size () = 1 ) */
Configurations(bt) = sigs = Set <Signature >{};
6 foreach bm : BlockMode in bt.modes do
sigs.addAll(Signatures(bm));
done;
configs = Set <Configuration >{};
11 foreach sig : Signature in sigs do
c = new Configuration(bt); if (sig.mode != null) then
c.modes.add(sig.mode); endif
16 c.variants.addAll(sig.variants); configs.add(c);
done;
foreach pair: (c1: Configuration , c2: Configuration) in configs do
21 if (c1.variants = c2.variants) then c1.modes.addAll(c2.modes); c2.delete; endif done; 26 return configs;
Listing 6.23: BlockType configuration extraction algorithm specification
6.5 Semantics modeling
In a BlockLibrary instance, extracted configurations hold semantics phases definitions provided through DEFINITION Annotation. Each semantic DEFINITION Annotation needs to be provided either as an axiomatic semantics – defining the pre-conditions and post-conditions for each phase of the seman- tics – or as an operational semantics definition or even both, that must be correct one against the other. The advantage of providing both axiomatic and operational specification is on the verification capabilities regarding the specified semantics.
The verification of a block semantics specification cannot be achieved by only relying on the content of the axiomatic and operational semantics definition. We should also rely on the StructuralFeature elements defined in the BlockVariant contained in the block configuration. In a configuration, each StructuralFeature has a defined data type and some additional constraints on its value. Regarding configurations themselves, BlockVariant elements are extended with MODE_INVARIANT annotations corresponding to additional constraints on the block configuration. These elements must be used as addi- tional pre-conditions of the semantics functions.
General purpose programming languages can be extended with annotations like C with ACSL, Java with JML, C# or F# with Spec#, Ada 2012, Eiffel or Why/WhyML that allows to express programs and related annotations specifying properties, assertions or contracts to be verified on the language constructs. As a Configuration element holds at least one semantics definition operations and variables declara- tions for ports, parameters and memories and their associated data types, we can envision a Configuration structure operational semantics definition to be translated as a function, its axiomatic semantics as a contract on the generated function, the StructuralFeature INVARIANT Annotation as annotations on the variables definitions and the BlockVariant and BlockMode MODE_INVARIANT as additional contract informations. We provide in Listing 6.24 such a hand-extracted function using the C programming language and ACSL as an annotation language.
In this section we will provide clarifications on the interpretation of a BlockLibrary specification in terms of executable functions. We will rely on the C language complemented with ACSL annotations to give a formalisation of the BlockLibrary specifications as function contracts. Simulink blocks specified
6.5. SEMANTICS MODELING
/*@ requires *delay > 0;
requires *delay = 1; // 1 is taken from the size of iC 3 requires \separated(mem , input , delay , output , iC);
assigns *mem;
ensures *mem == *iC; */ void init_Delay (
double *mem , double *input , int *delay , double *output , double *iC)
8 { *mem = *iC; }
/*@ requires *mem == *iC; requires *delay > 0;
requires \separated(mem , input , delay , output , iC); 13 assigns *output;
ensures *output == *mem; */ void compute_Delay (
double *mem , double *input , int *delay , double *output , double *iC)
{ *output = *mem; } 18
/*@ requires *output == *mem; requires *delay > 0 ;
requires \separated(mem , input , delay , output , iC); assigns *mem;
23 ensures *mem == *input; */ void update_Delay (
double *mem , double *input , int *delay , double *output , double *iC)
{ *mem = *input; }
Listing 6.24: Extracted annotation contract and function for the DelaySemantics BlockMode semantics phases
using the BlockLibrary approach are meant to be used for the verification of automatically generated code, in this purpose we will reuse the mapping provided here in Chapter 8.
6.5.1 Block semantics phases contracts
From the specification written for the Delay block provided in Listing 6.4, we shall be able to extract for each Configuration a function. Listing 6.24 provides an example of such contract for one Configuration extracted from the Delay BlockType (here the initial_condition parameter value is set to be a scalar). A function is extracted for each semantic phases declared in the DelaySemantics BlockMode: init_Delay, compute_Delay and update_Delay. Each function contract is then expressed using pre-conditions (requires ACSL annotations as in line 1) expressed from the INVARIANT Annotation of the
StructuralFeature elements and the MODE_INVARIANT of the Configuration BlockVariant (requires ACSL annotations as in line 2). The contract is completed with the pre/post conditions provided as axiomatic semantics of the BlockMode semantics phases specifications (ensures ACSL annotations as in line 3).
It is worth noting at this point of the specification that some INVARIANT have not been taken into account in our extracted annotation contracts: a) Data types: In the specification, the input port group is of type TDouble. In our translation as a contract clause, we only define this as declaring the input as a function parameter of type double. This should be specified carefully as the definition of this data type should be provided including its boundaries (minimum and maximum values) and its allowed precision (number of digits in the decimal part). Similar informations should be provided for any data type used in the specification. b) Dimensions: We specify two MODE_INVARIANT Annotation in the UVector BlockVariant. These constraints seem to be redundant in our specification as they specify that both input U and output V are vectors elements but they are declared as arrays of double values. This problem is implementation related and will be detailed in Chapter 7.
From this example we offer a template for the generation of function and their contracts annotation from a BlockLibrary specification in Listing 6.25. This shows the generic extracted function contract and code from configuration ConfZ of BlockMode BlockModeA initialisation computation phase.
6.5. SEMANTICS MODELING
/*@ requires ConfZ.BlockVariant1.input1.inv1; ... requires ConfZ.BlockVariant1.output1.inv1; ... requires ConfZ.BlockVariant1.memory1.inv1; ... 4 requires ConfZ.BlockVariantP ....
requires ConfZ.BlockVariant1. mode_invariant1 ; ... requires ConfZ.BlockVariantP ....
requires \separated(input_1 ,..., input_m ,ouput_1 ,..., output_n ,memory_1 ,..., memory_o ); requires ConfZ.BlockModeA.init.pre1; 9 ... requires ConfZ.BlockModeA.init.preN; assigns ...; ensures ConfZ.BlockModeA.init.post1; ... 14 ensures ConfZ.BlockModeA.init.postM; */ void BlockX_BlockModeA_ConfZ_Init_Semantics ( input_1 , ..., input_m , output_1 , ..., output_n , 19 memory_1 , ..., memory_o) { <initialisation code >; }
Listing 6.25: Extracted annotation contract and function body for an initialisation phase
6.5.2 Block semantics contract encoding with dynamic behaviors
As seen previously, some MODE_INVARIANT may apply on dynamic values of input PortGroup or MemoryVariable producing dynamic Configuration. These may also be specified through multiple BlockMode. This allows for a more fine grained specification of blocks semantics specially on the spec- ification of behaviors according to input PortGroup values. The BlockLibrary structure then allows to split the specification of a block semantics between multiple BlockMode, each one having a distinct MODE_INVARIANT. This is translated as distinct behaviors in function contracts.
From the specification of the Abs block in Listing 6.12 (page 97) we can extract only one Configuration element containing both BlockMode and one BlockVariant. The corresponding C + ACSL code for this Configuration must be as provided in Listing 6.26. In this listing we see that we define one behavior for each BlockMode, each one containing assumes clauses (lines 2 and 6) speci- fying the condition for the behavior to be considered applicable (these are the behaviors’ pre-conditions). The assumes clauses are extracted from the BlockMode MODE_INVARIANT. For each behavior the post- conditions are extracted from the post-conditions specified in the semantics phases axiomatic definition and inserted as ensures clauses (lines 3, 4, 7 and 8). Finally the code for the semantics phase is extracted according to both the dynamic MODE_INVARIANT (involving the if conditionals) and the operational se- mantics for the considered semantics phase (involving the code inside each then branch).
We model a generic full dynamic semantics for a block based on the previous examples in Listing 6.27. The phase function global preconditions (line 1 and 2) are taken from the StructuralFeature ele- ments INVARIANT. As a Configuration is composed of a set of Signature elements, each Signature holds a behavior definition for the overall block semantics.
Each behavior is characterised according to the MODE_INVARIANT constraints extracted from the Signature BlockMode and its list of BlockVariant. Constraints from the BlockVariant are com- mon to all BlockMode according to the Configuration definition, thus these constraints are to be in- cluded in the global pre-condition specification (as requires clauses – lines 3 and 4).
MODE_INVARIANT Annotation held in each BlockMode are used as pre-conditions for their respec- tive behaviors, thus they are used as assumes clauses as in line 6 and 11. Pre-conditions specified in the semantic phase axiomatic specifications are converted to assumes clauses as in line 7. Post-conditions spec- ified in the semantic phase are used as ensures clauses of their respective behavior as shown in line 8.
The function body is a combination of nested if-then-else constructs. Each then branch holds the code for a specific behavior. Each if condition is set to the conjunction of the MODE_INVARIANT constraints
6.5. SEMANTICS MODELING /*@ requires \separated(e1 , s1); assigns *s1; 3 behavior abs_Neg: assumes *e1 < 0.0; ensures *s1 >= 0.0; ensures *s1 == - *e1; behavior abs_PosOrNull: 8 assumes *e1 >= 0.0; ensures *s1 >= 0.0; ensures *s1 == *e1; */
void compute_Abs_Neg_Abs_PosOrNull (double *e1 , double *s1){ 13 if (*e1 < 0.0){ *s1 = - *e1; } else if (*e1 >= 0.0){ *s1 = *e1; } 18 }
Listing 6.26: Extracted annotation contract and function for the Abs BlockType semantics
taken from the BlockMode (lines 20 to 22), the then branch content is then the operational semantics code related to this behavior (line 23).
/*@ requires ConfZ.BlockVariant1.structuralFeature1 .inv1; ... 2 requires ConfZ.BlockVariantP ....
requires \separated(input_1 ,..., input_m ,ouput_1 ,..., output_n ,memory_1 ,..., memory_o ); requires ConfZ.BlockVariant1 .mode_invariant1 ; ...
requires ConfZ.BlockVariantP .mode_invariant1 ; ... assigns ...; 7 behavior ConfZ_Step_BlockModeA : assumes ConfZ.BlockModeA.mode_invariant1 ; ... assumes ConfZ.BlockModeA.pre1; ... assigns ...; ensures ConfZ.BlockModeA.post1; ... 12 ... behavior ConfZ_Step_BlockModeQ : assumes ConfZ.BlockModeQ.mode_invariant1 ; ... assigns ...; ... 17 */ void BlockX.ConfZ_Semantics (a input_1 , ..., input_m , output_1 , ..., output_n , memory_1 , ..., memory_p) 22 {
if (ConfZ.BlockModeA. mode_invariant1 && ... && ConfZ.BlockVariant1.mode_invariant1 && ... && ConfZ.BlockVariantP.mode_invariant1 && ...){ <ConfZ.BlockModeA.code >
27 //@ assert ConfZ.BlockModeA.post1 && ...
} else if (...) {
...
} else if (ConfZ.BlockModeQ.mode_invariant1 && ... ){
...
32 }
}
Listing 6.27: Generic specification for a block dynamic semantics phase for one Configuration (ConfZ)
The transformation depicted here has been implemented in order to translate BlockLibrary instance models to semantics functions in a formalism allowing to automatically and formally verify their correc- tion. This is detailed in Chapter 7 and model REQ-8.
Whereas this phase-specific verification allows to verify each phase of the block semantics correctness, it does not model the full semantics of the block. In dataflow languages semantics all the initialisation phases are executed once and then at every clock tick, all the compute phases and then all the update phases are executed. This verification is equivalent to verifying the generated code for a complete Simulink instance model and will be tackled in the second part of this manuscript.