Monitoring with verified guarantees

Runtime monitoring is generally considered a light-weight alternative to formal verification. In safety-critical systems, however, the monitor itself is a critical component. For example, if the monitor is responsible for initiating emergency protocols, as proposed in a recent aviation standard, then the safety of the entire system critically depends on the correctness of the monitor. In this paper, we present a verification extension to the Lola monitoring language that extends the efficient specification of the monitor with Hoare-style annotations that guarantee the correctness of the monitor specification. We add two new operators, assume and assert, which specify assumptions of the monitor and expectations on its output, respectively. The validity of the annotations is established by an integrated SMT solver. We report on experience in applying the approach to specifications from the avionics domain, where the annotation with assumptions and assertions has lead to the discovery of safety-critical errors in specifications. The errors range from incorrect default values in offset computations to complex algorithmic errors that result in unexpected temporal patterns. We also report how verified specifications can be monitored efficiently at runtime.


Introduction
Cyber-physical systems are inherently safety-critical due to their direct interaction with the physical environment -failures are unacceptable.A means of protection against failures is the integration of reliable monitoring capabilities.A monitor is a system component that has access to a wide range of system information, e.g., sensor readings and control decisions.When the monitor detects a failure, i.e., a violation of the behavior stated in its specification, it notifies the system or activates recoveries to prevent failure propagation.
The task of the monitor is critical to the safety of the system, and its correctness is therefore of utmost importance.Runtime monitoring approaches like Lola [5,6] address this by describing the monitor in a formal specification language, and then generating a monitor implementation that is provably correct and has strong runtime guarantees, for example on memory consumption.Formal monitoring languages typically feature temporal [18] and sometimes spatial [16] operators that simplify the specification of complex monitoring behaviors.However, the specification itself, the central part of runtime monitoring, is still prone to human errors during specification development.How can we check that the monitor specification itself is correct?
In this paper, we introduce a verification feature to the Lola framework.Specifically, we extend the specification language with assumptions and assertions.The framework verifies that the assertions are guaranteed to hold if the input to the monitor satisfies the assumptions.The prime application area of Lola is unmanned aviation.Lola is increasingly used for the development and operation monitoring of unmanned aircraft; for example, the Lola monitoring framework has been integrated into the DLR unmanned aircraft superAR-TIS3 [1].The verification extension presented in this paper is motivated by this work.In practice, system engineers report that support for specification development is necessary, e.g., sanity checks and proves of correctness.Additionally, recent developments in unmanned aviation regulations and standards indicate a similar necessity.One such development is the upcoming industry standard ASTM F3269 (Standard Practice for Methods to Safely Bound Flight Behavior of Unmanned Aircraft Systems Containing Complex Functions).ASTM F3269 introduces a certification strategy based on a Run-Time Assurance (RTA) architecture that bounds the behavior of a complex function by a safety monitor [15], similar to the well-known Simplex architecture [21].This complex function could be a Deep Neural Network as proposed in [4].A simplified version of the architecture 4 of ASTM F3269 is shown in Figure 1.

External Data Safety Monitor
Complex Function Recovery Control Function(s) Switch Fig. 1.Run-Time Assurance architecture proposed by ASTM F3269 to safely bound a complex function using a safety monitor.
At the core of the architecture is a safety monitor that takes the inputs and outputs of the complex function, and decides whether the complex function behaves as expected.If not, the monitor switches the control from the complex function to a matching recovery function.For instance, the flight of an unmanned aircraft could be separated into different phases: e.g., take-off, cruise flight, and landing.For each of these phases, a dedicated recovery could be defined, e.g., braking during take-off, the activation of a parachute during cruise flight, or a go-around maneuver during landing.Further, it is crucial that recoveries are only activated under certain conditions and that only one recovery is activated at a time.For instance, a parachute activation during a landing approach is considered safety-critical.The verification extension of Lola introduced in this paper can be used to guarantee statically that such decisions are avoided within the monitor specification.Consider the simplified Lola specification input event_a, event_b, value: Bool, Bool, Float32 assume <a1> !(event_a and event_b) output braking : Bool := ...computation... output parachute : Bool := ...computation... output go_around : Bool := ...computation... assert <a1> !(braking and parachute) that declares an assumption on the system input events and asserts that braking and parachute never evaluates to true simultaneously.
In the following, we first give a brief introduction to the stream-based specification language Lola, then present the verification approach, and, finally, give details on the tool implementation and our tool experience with specifications that were written based on interviews with aviation experts.Our results show that standard Lola specifications are indeed prone to error, and that these errors can be caught with the formal verification introduced by our extension.

Related Work
Most work on the verification of monitors focuses on the correct transformation into a general programming language.For example, Copilot [17] specifications can be compiled into C code with constant time and memory requirements.Similarly, there is a translation validation toolkit for Lola monitors implemented in Rust [6], which is based on the Viper verification tool.Translation validation of this type is orthogonal to the verification approach of this paper.Instead of verifying the correctness of a transformation, our focus is to verify the specification itself.Both activities complement each other and facilitate safer future cyber-physical systems.
Our verification approach is based on classic ideas of inductive program verification [11,7], and is closely related to the techniques used in static program verifiers like KeY [2], VeriFast [12], and Dafny [14].In a verification approach like Dafny, we are interested in functional properties of procedures, specified as post-conditions that relate the values upon the termination of the procedure with those at the time of entry to the procedure, e.g., ensure y = old(y).By contrast, a stream-based language like Lola allows arbitrary access to past and future stream values.This makes it necessary to unfold the Lola specification in order to properly relate the assumptions and assertions in time.
Most closely related to stream-based monitoring languages are synchronous programming languages like LUSTRE [10], ESTEREL [3], and SIGNAL [8].For these languages, the compiler is typically used for verification -a program representing the negation of desired properties is compiled with the target program and a check for emptiness decides whether the properties are satisfied.Furthermore, a translation from past linear-time temporal logic to ESTEREL was proposed to simplify the specification of more complex temporal properties [13].Other verification techniques also exist like SMT-based k-Induction for LUSTRE [9] or a term rewriting system on synced effects [22].A key difference in our approach is that we do not rely on compilation.Our verification works on the level of an intermediate representation.Furthermore, synchronous programming languages are limited to past references, while the stream unfolding for the inductive correctness proof of the Lola specification includes both past and future temporal operators.Similar to k-Induction, our approach is sound but not complete.

Runtime Monitoring with Lola
We now give an overview of the monitoring specification language Lola.The verification extension is presented in the next section.
Lola is a stream-based language that describes the translation from input streams to output streams: where input streams carry synchronous arriving data from the system under scrutiny, output streams represent calculations, and triggers generate notification messages at instants where their condition ϕ becomes true.Input streams t 1 , . . ., t m and output streams s 1 , . . ., s n are called independent and dependent variables, respectively.Each variable is typed: independent variables t i are typed T i and dependent variables s i are typed T m+i .Dependent variables are computed based on stream expressions e 1 , . . ., e n over dependent and independent stream variables.A stream expression is one of the following: an atomic stream expression c of type T if c is a constant of type T ; -an atomic stream expression s of type T if s is a stream variable of type T ; -a stream expression ite(b, e 1 , e 2 ) of type T if b is a Boolean stream expression and e 1 , e 2 are stream expressions of type T .Note that ite abbreviates the control construct if-then-else; -a stream expression f (e 1 , . . ., e k ) of type T if f : operator and e 1 , . . ., e k are stream expressions of type T 1 , . . ., T k ; -a stream expression o.offset (by : i).defaults(to : In general, Lola is a specification language that allows to specify complex temporal properties in a precise, concise, and less error-prone way.The focus is on what properties should be monitored instead of how a monitor should be executed.Therefore, the Lola monitor synthesis automatically infers and optimizes implementation details like evaluation order and memory management.The evaluation order [6] of Lola streams is automatically derived by analysis of the dependency graph [5] of the specification.This allows to ignore the order when taking advantage of the modular structure of Lola output streams, e.g.,: output alt_avg := alt_count / (position+1) output alt_count := if altitude ≤ 200.0 then 0 else alt_count.offset(by:-1).defaults(to: 0) + 1 output position := position.offset(by:-1).defaults(to: 0) where position and alt count are used before their definition.Further, the dependency graph allows to detect invalid cyclic stream dependencies, e.g., output a := a.offset(by: 0).defaults(to: 0).

Assumptions and Assertions
In this section, we present the verification extension for the Lola specification language.The extension allows the developer to annotate the Lola specification with assumptions and assertions in order to verify the desired guarantees on the computed streams.As an example, consider the simplified specification in Listing 1, which is structured into stream computations in Lines 1 to 23, and assumptions and assertions from Line 26 onwards.∨ (parachute ∧ gain_alt) ) // Parachute SHALL ONLY be activated 100 m above ground.assert <a2> parachute → alt > 100.0 Listing 1.A simplified Run-Time Assurance Lola specification with three recovery functions for three different flight phases.Assumptions and assertions are used to show that only one recovery function is activated at once.
The computation part specifies a safety monitor within a RTA architecture that triggers recovery functions for three different flight phases.First, the takeoff recovery function is triggered (Line 21) when the targeted take-off speed was not achieved on a runway up to a predefined point (Line 13).The distance between the current position and the end of the runway with local coordinates (0, 0) is computed in Line 8. Second, in-flight a parachute is activated (Line 22) when virtual barriers for the aircraft, i.e., a geofence, are exceeded (Line 15).For more details on a Lola geofence specification (Line 9), we refer to [20].Last, during landing, up to a point of no return (alt < 10.0), a new landing attempt is initiated (Line 23) if the aircraft's speed is too fast or its landing gear is not yet ready.To be more robust, the current and the previous value of the landing gear ready is taken into account (Lines 17 -18).
With the verification extension, the specification assures that recoveries are not activated simultaneously (Lines 30-31), i.e., for instance there is no possibility that a parachute is activated during a landing approach.The first two conjunctions in Line 30 evaluate to false because relevant outputs use a disjoint altitude condition.The last conjunction requires an assumption.In fact, here, two assumptions are linked by the identifier a1 to the assertion.The assumptions specify: the known bound of received speed data (Line 27) as well as operational information (Line 26), e.g., given by the concept of operation a nominal landing is only foreseen within the predefined operational airspace.Further, a second assertion is stated in Line 33 that guarantees that the parachute should only be activated when the aircraft is 100 meters above ground.In this case, the property can be shown assumption-free.Assertions help engineers to show that certain properties are true.The given assertions indicate how specification debugging and management can benefit from the extension -it avoids digging into potentially complex stream computations.
The extension and its verification approach are presented in the following.In general, the verification extension is used if a Lola specification is annotated in the following way: where α 1 , . . ., α m+n ∈ Γ are identifiers for θ 1 , . . ., θ m , ψ 1 , . . ., ψ n , which are Boolean stream expressions with possibly temporal operators.For convenience, we define functions which return all θ and ψ that are linked to a given α identifier: The set of assertion ψ 1 , . . ., ψ n is correct for all input streams iff whenever an assumption is satisfied, its corresponding assertion is satisfied as well.
The verification of assertions relies on the encoding of the Lola execution in Satisfiability Modulo Theory (SMT).We define the smt function that encodes a stream expression next.It can be used to encode independent and dependent variables as well as expressions of assumptions and assertions.

Definition 1 (SMT-Encoding of Stream Expressions).
Let Φ be a Lola specification over independent stream variables t 1 , . . ., t m and dependent stream variables s 1 , . . ., s n .Further, let the natural number N + 1 be the length of the input streams, c be an SMT constant symbol, and τ 0 1 , . . ., τ N 1 , . . ., τ 0 m , . . ., τ N m , σ 0 1 , . . ., σ N 1 , . . ., σ 0 n , . . ., σ N n be SMT variables.Then, the function smt recursively encodes a stream expression e at position j with 0 ≤ j ≤ N in the following way: -Base cases: where ite is an SMT encoding of if-then-else; f is an interpreted function if f is from a theory supported by the SMT solver and an uninterpreted function otherwise.
Next, Proposition 1 shows how the correctness of asserted stream properties can be proven for finite input streams.If the set of assertions is correct, asserted stream properties are guaranteed to be valid in each step of the monitor execution.In practice, such specifications are preferable.In the following, let Φ be a Lola specification with verification annotations.Further, we refer to the set of input streams and computed output streams as stream execution.

Proposition 1 (Assertion Verification of a Finite Stream Execution).
The set of assertions is correct for a finite stream execution with length N + 1 under given assumptions, if the following formula is valid: The formula in Proposition 1 unfolds the complete stream execution and informally expresses that an assertion must hold in each stream position whenever its corresponding assumption and implementation are satisfied.
To avoid the complete unfolding and allow arbitrary stream lengths, an inductive argument is given in Proposition 2 that defines proof obligations for an annotated Lola specification.Next, we present a template for the stream unfolding that helps to define the proof obligation at the Beginning (Definition 3), during Run (Definition 4), and at the End (Definition 5) of a stream execution.

Definition 2 (Template Stream Unfolding).
We define the template formula φ t that states proof obligations as: where c asm, c asserted , c streams, and c assert are template parameters for the unfolding of assumptions, previously proven assertions, output streams, and assertion, respectively.
The template formula in Definition 2 uses template parameters for the stream unfolding.For instance, the parameter assignment c asm := 0 ≤ i < 10 adds assumptions at the first ten positions of the stream execution.Further, the parameter c asserted allows to incorporate the induction hypothesis.
In the following, we will use the Lola specification as a running example for the template stream unfolding.Here, the input reset represent a reset command for the output stream o1 that counts how long no reset occurred.Output o1 is used by output o2 which aggregates over the previous, the current, and the next outcome of o1 .As assertion, we show that o2 is always positive and never larger than three given the assumption that in each execution step either the previous or the next reset is true.The assumption ensures that at most two consecutive resets are false.Given the reset sequence of input values true; false; false that satisfies the assumption, the resulting o1 stream evaluates to 0; 1; 2 .Here, at the second position of the sequence, o2 evaluates to three.To show that the assertion also holds at the first and the last position of the sequence, out-of-bounds values must be considered.We show how the template φ t can be used at the beginning of a stream execution.Here, default values due to past stream accesses beyond the beginning of a stream need to be captured by the obligation to guarantee that the assertions hold in these cases.The combination of past out-of-bounds and future outof-bounds default values must also be covered by the obligations in case the stream is stopped early.These scenarios are depicted for the running example in Figure 2. The figure shows four finite stream executions with different lengths.All stream positions are colored gray, while only some positions contain a single red dot.These features indicate the unfolding of stream variables and annotations using the template φ t .A gray-colored position means that the assumptions have been unfolded and a dotted position means the assertion has been unfolded.Further, arrows indicate temporal stream accesses where solid lines correspond to accesses by outputs and dashed lines correspond to accesses by annotations, i.e., assumptions and assertions.For each stream execution, only the arrows for a single position are depicted -the arrows for other positions have been omitted for the sake of clarity.For example, for N = 0, the accesses of output o2 are both out-of-bounds, i.e., the default value zero is used.While for N = 3, the accesses at the second position are shown where only the past access of the assumption leads to an out-of-bounds access.The figure depicts all necessary stream execution that cover all combinations of past out-of-bounds accesses, i.e., with and without future bound violations.The described unfoldings of Figure 2 are formalized as proof obligations in Definition 3.

Definition 3 (Proof Obligations for Past Out-of-bounds Accesses).
Let where k > 0}) be the greatest positive offset.The proof obligations φ Begin for past out-of-bounds accesses are defined as the conjunction of template formulas: φ t (c asm, c asserted , c streams, c assert ) with template parameters: • c asm Next, the case where no out-of-bounds access occurs is considered.Hence, the obligations capture the nominal case where no default value is used.Since we have shown that past out-of-bounds accesses are valid we can use these proven assertions as assumptions.Figure 3 depicts a stream execution with a single dotted position, i.e., the position where the assertion must be proven.As can be seen, all accesses from this position are within bounds.Further, note that the accesses of the first and the last unfolded assumption, i.e., the first and the last gray-colored position, are also within bounds.The described unfolding is formalized as proof obligations in Definition 4.

Definition 4 (Proof Obligations for No Out-of-bounds Accesses).
The proof obligations φ Run without out-of-bounds accesses are defined as φ t (c asm, c asserted , c streams, c assert ) with template parameters: • c asm Last, we consider the case where only future out-of-bounds accesses occur.Hence, the respective obligations need to incorporate default values of future out-of-bounds accesses.As before, we can use the previously proven assertions as assumptions.Figure 4 depicts a stream execution with two dotted positions, i.e., positions where the assertion must be proven.The position where arrows are given represents the case where only the assumption results in a future outof-bounds access.The last position of the stream execution represents the case in which both the assumption and the stream result in future out-of-bounds accesses.The presented unfolding is formalized as proof obligations in Definition 5.

Definition 5 (Proof Obligations for Future Out-of-bounds Accesses).
The proof obligations φ End for future out-of-bounds accesses are defined as the template formula φ t (c asm, c asserted , c streams, c assert ) with template parameters: • c asm So far, we have defined proof obligations for certain positions in the stream execution with and without out-of-bounds accesses.Together, the proof obligations constitute an inductive argument for the correctness of the assertions, see Proposition 2. Here, the base case is given by Definition 3 and induction steps are given by Definitions 4 and 5.The induction steps use the induction hypothesis, i.e., valid assertions, due to the template parameter c asserted.

Proposition 2 (Assertion Verification by Lola Unfolding).
The set of assertions is correct if the formula φ Begin ∧ φ Run ∧ φ End is valid.
Proposition 2 proves the soundness of the verification approach.Soundness refers to the ability of an analyzer to prove the absence of errors -if a Lola specification is accepted, it is guaranteed that the assertions are not violated.The converse does not hold, i.e., the presented verification approach is not complete.Completeness refers to the ability of an analyzer to prove the presence of errors -if a Lola specification is rejected, the counter-example given should be a valid stream execution that results in an assertion violation.The following Lola specification is rejected even though no assertion is violated: Here, since the if-condition in Line 3 evaluates to true at the beginning of the stream execution, sum is a constant stream with value zero.Hence, the assertion in Line 4 is never violated.The verification approach rejects this specification.
The reason for this is that sum ≤ 100 is added as an asserted condition in φ Run .Therefore, the SMT solver can assign a value between 91 and 100 to the earliest sum variable of the unfolding, resulting in an assertion violation of the next sum variable.

Application Experience in Avionics
In this section, we present details about the tool implementation and tool experiences on practical avionic specifications.

Tool Implementation and Usage
The tool is based on the open source Lola framework5 written in Rust.Specifically, it uses the Lola frontend to parse a given specification into an intermediate representation.Based on this representation, the SMT formulas are created and evaluated with the Rust z3 crate 6 .At its current phase of the crate's development, a combined solver is implemented that internally uses either a non-incremental or an incremental solver.There is no information on the implemented tactics available, but all our requests could be solved within seconds.For functions that are not natively supported by the Rust Z3 solver, the output is arbitrarily chosen by the solver with respect to the range of the function.The tool expects a Lola specification augmented by assumptions and assertions.
The verification is done automatically and produces a counter-example stream execution, if any exists.The counter-example can then be used by the user to debug its specifications.Two different kinds of users are targeted.First, users that write the entire augmented specification.Such a user could be a systems engineer who is developing a safety monitor and wants to ensure that it contains critical properties.Second, users that augment an existing specification.Here, one reason could be that an existing monitor shall be composed with other critical components and certain behavioral properties are expected.Also, similar to software testing, the task of writing a specification and their respective assumptions and assertions could be separated between two users to ensure the independence of both.

Practical Results
To gain practical tool experience, previously written specifications based on interviews with engineers of the German Aerospace Center [19] were extended by assumptions and assertions.The previous specifications were tested using logfiles and simulations -the authors considered them correct.We report several specification errors in Table 1 that were detected by the presented verification extension.In fact, the detected errors would have resulted in undetected failures.After the errors in the previous specifications were fixed, all assertions were proven correct.Note that the errors could have been found due to manual reviews.However, such reviews are tedious and error-prone, especially when temporal behaviors are involved.The detected errors in violated assertions due to incomplete specifications.Next, we give one representative example for each group.We reduced the specification to the representative fragment.

Example 1 (Classical Bug).
The Lola specification in Listing 2 monitors the fuel level.A monitor shall notify the operator when one of the three different fuel levels are reached: half (Line 8), warning (Line 9), and danger (Line 10).The fuel level is computed as a percentage in Line 7. It uses the fuel level at the beginning of the flight (Line 6) as a reference for its computation.Given the documentation of the fuel sensor, it is known that fuel values are within R + and decreasing.This is formalized in Line 4 as an assumption.As an invariant, we asserted that the starting fuel is greater or equal to fuel (Line 15).Further, in Lines 16 to 18, we stated that once a level is reached it should remain at this level.During our experiment, the assertion led to a counter-example that pointed to the previously used and erroneous fuel level computation: In short, the output computed the consumed fuel and not the remaining fuel.The computation could be easily fixed by converting consumed fuel into remaining fuel, see Line 7. Therefore, Listing 2 satisfies its assertion.Note, that offset accesses were used to assert the temporal behavior of the fuel level output stream.Further, trigger once is an abbreviation which states that only the first raising edge is reported to the user.

Example 2 (Operator Error).
An important monitoring property is to detect frozen values as these indicate a deteriorated sensor.Such a specification is depicted in Listing 3. Here, as an input, the acceleration in x−direction is given.The frozen value check is computed from Line 6 to Line 10.It compares previous values using Lola's offset operator.To check this computation, we added the sanity check that asserts that no frozen value shall be detected (Line 13) when small changes in the input are present (Line 4).In the previous version, the frozen values were computed using the abbreviated offset operator: This resulted in a counter-example that pointed to wrong default values.Although the abbreviated version is easier to read and reduces the size of the specification, it is unfortunately not suitable for this kind of property.The tool detected the unlikely situation that the first value of ax is 0.0 which would have resulted in evaluating frozen ax to true.Although unlikely, this should be avoided as contingencies activated in such situations depend on correct results and otherwise could harm people on the ground.By unfolding the operator and adding a different default value to one of the past accesses, the error was resolved (Line 6).Listing 3 shows the fixed version which satisfies its assertion.

Example 3 (Wrong Interpretation).
In Listing 4, two visual sensor readings are received (Lines 2-3).Both, readings argue over the same observations where avgDist represents the average distance to the measured obstacle, actual is the number of measurements, and static is the number of unchanged measurements.A simple rating function is introduced (Lines 5-8) that estimates the corresponding rating -the higher the better.Using these ratings, the trust in each of the sensors is computed probabilistically (Lines 9-10).When considering the integration of such a monitor as an ASTM switch condition that decides which sensor value should be forwarded, the specification should be revised.This is the case because the assertion in Line 14 produces a counter-example which indicates that both trust triggers (Lines 11-12) can be activated at the same time.A common solution for this problem is to introduce a priority between the sensors.The examples show how the presented Lola verification extension can be used to find errors in specifications.We also noticed that the annotations can serve as documentation.System assumptions are often implicitly known during development and are finally documented in natural language in separate files.Having these assumptions explicitly stated within the monitor specification potentially reduces future mistakes when reusing the specification, e.g., when composing with other monitor specifications.Listing 5 depicts such an example specification.Here, the monitor interfaces are clearly defined by the domain of input a (Line 5) and output o (Line 13).Also, reset is assumed to be valid at least once per second (Line 5).Further, no deeper understanding of the internal computations (Lines 7-10) is required in order to safely compose this specification with others.

Conclusion
As both the relevance and the complexity of cyber-physical systems continues to grow, runtime monitoring is an essential ingredient of safety-critical systems.When monitors are derived from specifications it is crucial that the specifications are correct.In this paper, we have presented a verification approach for the stream-based monitoring language Lola.With this approach, the developer can formally prove guarantees on the streams computed by the monitor, and hence ensure that the monitor does not cause dangerous situations.The verification extension is motivated by upcoming aviation regulations and standards as well as by practical feedback of engineers.
The extension has been applied to previously written Lola specifications that were obtained based on interviews with aviation experts.In this process, we discovered and fixed several serious specification errors.
In the future, we plan to develop automatic invariant generation for Lola specifications.Another interesting direction for future work is to exploit the results of the analysis for the optimization of the specification and the resulting monitoring code.Finally, we plan to extend the verification approach to RTLola, the real-time extension of Lola.

Fig. 2 .
Fig. 2. Four stream executions of different length N + 1 with the respective template unfolding are depicted.The stream executions consider all cases with past out-ofbound accesses.A gray-colored box indicates that an assumption has been unfolded at this position, while a red dotted box indicates that an assertion has been unfolded at this position.Solid and dashed arrows indicate accesses by streams and annotations, respectively.

Fig. 3 .Fig. 4 .
Fig. 3.A stream execution of length N +1 with the corresponding template unfolding is depicted.The stream execution considers the case where no out-of-bound access occurs.Gray-colored and red dotted positions represent unfolded assumptions and assertions, respectively.Solid and dashed arrows indicate accesses by streams and annotations, respectively.

Table 1 .
Detected errors by the verification extension, where #o, #a, and #g represent the number of outputs, assumptions, and assertions given in the specification, respectively.
The fixed version of the Lola ctrl output specification that monitors the fuel level.Three level of engagement are depicted: half, warning, and danger.