Simulation under Arbitrary Temporal Logic Constraints

12/23/2019 ∙ by Julien Brunel, et al. ∙ 0

Most model checkers provide a useful simulation mode, that allows users to explore the set of possible behaviours by interactively picking at each state which event to execute next. Traditionally this simulation mode cannot take into consideration additional temporal logic constraints, such as arbitrary fairness restrictions, substantially reducing its usability for debugging the modelled system behaviour. Similarly, when a specification is false, even if all its counter-examples combined also form a set of behaviours, most model checkers only present one of them to the user, providing little or no mechanism to explore alternatives. In this paper, we present a simple on-the-fly verification technique to allow the user to explore the behaviours that satisfy an arbitrary temporal logic specification, with an interactive process akin to simulation. This technique enables a unified interface for simulating the modelled system and exploring its counter-examples. The technique is formalised in the framework of state/event linear temporal logic and a proof of concept was implemented in an event-based variant of the Electrum framework.



There are no comments yet.


page 1

page 2

page 3

page 4

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

Model checking is one of the most successful techniques for analysing systems, largely due to the ability to automatically verify whether a temporal logic specification holds in a model of a system. Model validation and debugging is essential when analysing a system, and most model checkers provide a simulation mode where the user can explore alternative system traces by choosing how to proceed with the exploration. With most tools, it is possible to choose one of the possible successor states randomly. Additionally, in order to provide a finer control and speed up the debugging process, many tools also allow the user to interactively pick which event to execute next (if the modelling language has some notion of event/action) and/or one of the next possible states (to support the exploration of non-deterministic events, both features must be provided). These simulation modes are quite intuitive and can even be used by problem domain experts unfamiliar with model checking to help validate the model.

Unfortunately this simulation mode only takes into account the system model, traditionally specified by some sort of transition system or a set of events. However, in some situations it would be extremely helpful to perform such simulation under additional constraints, for example to assess the impact of imposing arbitrary fairness constraints. Such constraints reduce the set of valid behaviours and simulation could help the user validate and better understand their impact (which is not always trivial to infer). Similarly, when model checking a given temporal logic property it could be very useful to explore the set of behaviours that falsify it (its set of counter-examples) with a similar simulation technique. Currently most model checkers display a single counter-example when a property is false. As a consequence, the user often inspects the (lone) counter-example to locate the possible source of the problem, changes the model (or specification) to address it, only for the model checker to reveal a different counter-example to the same property. The ability to explore distinct counter-examples at once could allow the user to identify a more general fix, thus tightening the check / analyse / fix loop and making the overall model checking process more efficient.

In this paper we propose a simulation technique that explores the set of the behaviours that satisfy (or falsify) an arbitrary temporal logic specification. At any point the user can focus on a particular state of a trace, see which alternative events enable the same trace prefix to be extended into a complete valid behaviour (another infinite trace satisfying the property), and follow any of those to proceed with the exploration. While traditional simulation is rather easy to implement efficiently for any model resembling a transition system, it is unclear how to do so when additional constraints are imposed. This paper explores the viability of a rather naïve on-the-fly technique: when a state is focused, multiple queries to the model checker are run in the background to determine which events can be further explored, while still preserving the same trace prefix. To tame the complexity in models with many events (or parametrised ones), type categorisation is supported: the user first focuses on a specific type and only then iterates over the different events of that type.

This paper is structured as follows. In the next section we very briefly discuss some alternative techniques to explore the set of behaviours that satisfy (or falsify) a given property. In Section 3 we formalise our proposal in the general setting of event/state linear temporal logic. Section 4 presents a prototype implementation of the proposed technique in the Electrum Analyzer [electrumanalyzer], the model checker for the Electrum language [electrum], an extension of Alloy [alloy] with linear time temporal logic. The goal of this prototype is mainly to show the viability of the approach, namely in terms of user-experience and efficiency. Section 5 wraps-up the paper and presents some ideas for future work.

2 Related work

Some techniques have been proposed to explore of the set of behaviours that satisfy (or falsify) a given property. The simplest ones just provide iteration over such set, by independently displaying one trace at a time. This can be achieved by changing an explicit model checking engine to resume search after finding one counter-example trace, or, in the case of a SAT-based symbolic bounded model checker, by incrementally adding new clauses that exclude exactly the previous trace, as implemented in the Electrum Analyzer [electrumanalyzer] developed by the authors. The problem is that this frequently keeps yielding traces that are just slight variations of each other and, since the full set of behaviours is usually too big to be enumerated, finding interesting variations may prove infeasible. To alleviate this problem, for specific modelling languages it is possible to define reasonable equivalence classes on traces (e.g., traces that follow the same control-flow path are deemed equivalent), and implement iteration by restarting the model checker with a modified property that conjoins the original one with a formula excluding all traces in the class of the previous counter-example [efsm, simulink].

Problem domain expertise, namely some kind of user input, could lead to more effective exploration. While in the above techniques user interaction is limited to just asking for the next trace, in [marsha], by running multiple queries to the model checker, a proof tree of a CTL property is inferred to “explain” a counter-example trace, with which the user can interact to ask for new counter-examples. Possible interactions include asking for alternative proofs (e.g., in a disjunction node), or guiding the search to explore different parts of the model (e.g., in nodes, by choosing the next -satisfying state). However, this approach requires substantial knowledge of the underlying proof system for CTL and it is not clear how it can be generalised to support LTL and fairness constraints.

3 Formalisation

Most systems incorporate both the notion of states and events. State/event linear temporal logic (SE-LTL) was proposed to allow a more concise and intuitive specification in these cases [stateevent]. The semantics of a formula in this logic is defined over a labelled Kripke structure (LKS), a tuple where is a finite set of states, the set of initial states, a finite set of atomic propositions, a state labelling function, a transition relation, a finite set of events, and a transition labelling function. The transition relation is assumed to be total, so every state has at least one successor. To enable a more efficient exploration, events are categorized with a function that assigns a type to each event. This categorization is natural in many models, namely those with parametrised events. A path of such a typed LKS is an alternating infinite sequence of states and events where and .

Given a typed LKS, SE-LTL formulas are defined by the following grammar, where ranges over , over , and over :

Given a path , the semantics of a formula is the standard one of LTL with the addition that iff is the first event of and iff is the first event of and . means that holds in the typed LKS , that is, for every path of we have . Given a formula the goal of a model checker is to find a path such that . We will denote the first such counter-example, if it exists, by . Given a path , is a formula that exactly characterises the prefix of up to , defined as , where is a nesting of “next” operators and is a formula that fixes the values of the propositions of state , defined as the conjunction of all propositions appearing in and all negated propositions in .

Following [scenarioexploration], our interactive exploration technique is specified by a set of scenario exploration operations. The state of the exploration is a tuple where is the formula being model checked111To simplify, in the remaining of the paper we will present the technique in the context of counter-example exploration in model checking, but it can obviously be also used for exploring the valid behaviours of a system with additional arbitrary constraints specified over it, by just running the model checker on the negation of their conjunction and interpreting the resulting set of counter-examples as witnesses of the system’s behaviour., the current counter-example on display, the state the user is focused in, and a function mapping each path index to a formula that characterises the set of states and transitions the model checker is allowed to explore at that point. Notation will denote an update on this last function, that maps every index between and to , keeping all other indexes intact. When updating a single index , the notation will be simplified to .

When first checking a property this state is initialised as . Basic navigation operations can then be used to inspect the counter-example, namely and (for ). At any point it is possible to ask for a new counter-example that differs only in the outcome of the previous event, a useful operation to explore non-determinism. This operation is defined as , where is . By repeatedly applying all possible outcomes of the previous action will eventually be enumerated (or possible initial states when ). Notice how is used to trim a branch of the behaviour tree when this operation is selected, but maintains memory of previously trimmed branches while inspecting a trace with and .

Similarly, it is possible to ask for a new counter-example that picks a different next event of the same type. This operation is defined as , where is . Notice how keeps track that the branch starting in and labeled with has already been explored. To ask for a new counter-example with a specific type for the next event, operation can be used, where is defined as .

4 Implementation

Electrum is an extension of the popular Alloy formal specification language, developed for the analysis of dynamic systems. An Alloy model consists of a set of static signatures and relations (of arbitrary arity). Properties can be specified in an extension of first-order logic: apart from the standard connectives and quantifiers, Alloy supports closures and some derived relational logic connectives, such as composition (.) or Cartesian product (->). To make the verification decidable, the user must specify a scope setting the maximum size of all signatures. Counter-examples are depicted graphically with user-customisable themes. In Electrum, signatures and relations can be declared mutable (with keyword var) and properties can be specified using linear temporal logic connectives (including past ones) and primed expressions (denoting their value in the next state) in addition to Alloy connectives.

[numbers = none, xleftmargin=0pt, xrightmargin=0pt] open util/ordering[Key] sig Key sig Room keys: set Key, var current: one keys sig Guest var gkeys: set Key one sig Desk var lastKey: Room -> lone Key, var occupant: Room -> Guest

(*event*) In[g: Guest, r: Room, k: Key] (*modifies*) gkeys, occupant, lastKey no r.(Desk.occupant) and k = nextKey[r.(Desk.lastKey), r.keys] gkeys’ = gkeys + g->k Desk.occupant’ = Desk.occupant + r->g Desk.lastKey’ = Desk.lastKey ++ r->k (*event*) Out[g: Guest] (*modifies*) occupant … (*event*) Entry[g: Guest, r: Room, k: Key] (*modifies*) current … (*event*) Reentry[g: Guest, r: Room, k: Key] …

fun nextKey[k: Key, ks: set Key] : set Key min[nexts[k] & ks]

fact Init keys in Room lone -> Key and no Guest.gkeys and …

assert BadSafety always all r: Room, g: Guest, k: Key | (Entry[g,r,k] or Reentry[g,r,k]) and some r.(Desk.occupant) => g in r.(Desk.occupant) check BadSafety for 3 Key, 1 Room, 2 Guest, 10 Time

Figure 1: Hotel example in Electrum with events.

Recently, we added the notion of event to Electrum [electrumactions]. Figure 1 presents an example of an Electrum model with events based on a classic Alloy example that specifies a protocol for disposable room key-cards in a hotel. There are 4 events in this model (check-In, check-Out, Entry, and Reentry), each specified declaratively with relational logic and primed expressions. The keyword modifies is used to fix the frame. The desired safety property is that only guests registered as occupants of a room can indeed enter that room. Unfortunately, that is not the case and the check BadSafety command yields a counter-example trace where a guest checks in, enters the room after checking out, a second guest checks in, and the first guest reenters the room afterwards. This is possible because the door lock has not yet been recoded with the new key issued by the front desk. The previous version of the Electrum Analyzer [electrumanalyzer] already allowed the user to ask for full alternative counter-example traces, but each one could only be inspected independently (by navigating backward and forward in the states), making it difficult to understand the relationship between the different counter-examples.

Figure 2: Exploration interface.

The new prototype interface for simulation and counter-example exploration is depicted in Fig. 2, which illustrates precisely the exploration of the above counter-example at . As in the previous version, the user can focus on a particular state of a trace by navigating backward () and forward (), using the left- and right-arrows in the bottom toolbar. However, two states are now shown side-by-side, allowing the user to better understand what is the effect of an event. In the top toolbar we also depict the trace and which transition is being inspected, and the bottom toolbar in the middle shows the event that triggers the current transition. Following the formalisation in the previous section, the user can choose a different pre- or post-state (the small “reload” buttons under the left- and right-panes, corresponding to operation ), an event of the same type with different parameters (the “reload” button next to the event name, corresponding to the operation), or a different event type to execute (the selection button in the bottom toolbar, implementing the operation). When the user focuses on a state, operation is dry run on-the-fly to determine which event types are enabled, so that when the event selection button is pressed only the enabled events can be selected (shown with a green background, as opposed to red for the disabled ones). In Fig. 2 we can see that after check-in the only options are for the first guest to check out or enter the room. Unlike in the previous version of the Analyzer, it is now easy to understand that, for the given scope, the check-in of the second guest must necessarily be followed by an entry or reentry of the first guest, and there are no other possibilities to breach safety.

To assess the efficiency of the proposed technique, we measured the required time to determine which operations are enabled in the different states of the first counter-example returned by the Analyzer. Table 1 shows the results of this preliminary evaluation for different scopes. The first column () shows the configuration (number of guests and a list with the number of keys per room), the second the time (in seconds) to compute the first counter-example (), and then, for each state , the total time (in seconds) to compute which event types are enabled (), and the set of enabled events (), with the subscript of each event type identifying the guest involved, and also highlighting the event chosen to be executed in bold. The evaluation was performed with the bounded model checking engine of Electrum (with the Glucose SAT solver), with maximum trace length of 10, in a commodity laptop with a 2.3 GHz Intel Core i5 and 16 GB of RAM. As can be seen, only for in the last configuration did the solving of all events take more than 2s, and in most cases it is in the order of a few hundred ms. Since a user typically needs some time to understand a state after focusing, this delay is almost always unnoticed. Also, times tend to decrease as the user advances in the trace: this is to be expected, since a bigger prefix of the trace is fixed, resulting in a smaller search space for the verification engine.

2[3] 0.07 0.33 0.20 E 0.18 E 0.22 0.09 OE 0.09 OE
2[1,3] 0.06 0.49 0.30 O 0.27 R 0.23 R 0.26 0.11 OE
3[2,3] 0.11 0.75 0.34 IE 0.39 E 0.35 I 0.06 IOE 0.07 IOE
3[1,1,4] 0.58 1.24 0.77 E 0.62 E 0.53 O 0.23 OE 0.20 OE
4[1,1,6] 1.74 2.30 1.41 E 1.10 E 0.94 O 0.39 OE 0.33 OE
Table 1: Performance of the event type enumeration (times in seconds).

5 Conclusion

This paper presented a simple technique that allows the user to explore the behaviours that satisfy (or falsify) an arbitrary temporal logic specification, with an interactive process akin to simulation. A prototype was implemented in the Electrum Analyzer, and a preliminary evaluation showed its viability in terms of efficiency. In the future we intend to further improve efficiency by checking which events are enabled in parallel. To show the generality of the technique we intend to apply it to other model checkers, namely develop a counter-example exploration tool for SMV. Finally, we also plan to conduct a more detailed evaluation, focusing not only on efficiency, but also on its effectiveness, namely in helping the user identify truly different counter-examples.


This work is financed by the ERDF - European Regional Development Fund - through the Operational Programme for Competitiveness and Internationalisation - COMPETE 2020 - and by National Funds through the Portuguese funding agency, FCT - Fundação para a Ciência e a Tecnologia, within project POCI-01-0145-FEDER-016826, and the French Research Agency project FORMEDICIS ANR-16-CE25-0007. The third author was also supported by the FCT sabbatical grant with reference SFRH/BSAB/143106/2018.