2.2 Model checking
2.2.3 Model checking tools
The techniques presented in Section 2.2.2 have been implemented in a number of soft- ware tools, from the early 1990s. This section briefly summarises three mature tools and their programming and specification languages; other tools exist, and they are briefly summarised in Section 2.3. The tools reviewed below have been chosen because of their robustness, of their wide circulation and availability, and because of their relevance with material presented in later chapters.
2.2.3.1 SPIN
The model checker SPIN (Simple Promela INterpreter) is one of the most mature model checkers available: it was introduced in the 1980s at Bell Labs, it has been available to the general public since 1991, and it has been continually developed since then. A general introduction to the tool can be found in [Holzmann, 1997], while the theoretical foundations and a detailed user manual are presented in the book [Holzmann, 2003]. The main characteristics of SPIN are:
• It is a model checker for the temporal logic LTL.
• It is mainly aimed at verification of protocols and software. SPIN’s programming language PROMELA (PROcess MEta LAnguage) reflects this intended use (see below).
• It implements an automata-based algorithm for model checking and various optimi- sation strategies, including on-the-fly model checking and partial order reduction19.
• It provides a graphical user interface (Xspin) to the model checker and to an inter- active simulator.
19
This technique is based on the observation that execution traces arising from different orderings of interleaved concurrent processes are sometimes equivalent for the evaluation of a formula ϕ.
mtype = { . . . }; chan = { . . . }; <type> = { . . . }; proctype SampleProcess1(<args>) { . . . } proctype SampleProcess1(<args>) { . . . } init { main body }
Figure 2.12: Structure of a PROMELA program.
The structure of a PROMELA program is represented in Figure 2.12. A program includes a declaration section for message types (mtype), for channel types (chan), and for global variables of various types (indicated collectively with the string <type> in the figure). Various processes may be defined in a PROMELA program using the keyword proctype; each process is defined by a name and by a list of accepted arguments. The behaviour of each process is defined in its body (not shown in the figure), and each process may include a list of local variables. Processes communicate using global variables and channels. Processes are initially created in the init section of the program, they execute concurrently, and they can be created by other processes.
The Xspin graphical interface acts as a “control centre” for the components of SPIN archi- tecture (depicted in Figure 2.13). The user needs to provide a PROMELA program and an LTL formula ϕ; the LTL formula is then translated by the tool into an appropriate automaton. SPIN can be used as a simulator (to perform either random or interactive simulations), or as a model checker. In the latter case, a C program implementing the automata-based algorithm presented above is constructed and compiled, producing a bi- nary executable that provides an answer to the model checking question.
2.2.3.2 MOCHA
MOCHA [Alur et al., 1998] is a model checker for the logic ATL presented in Sec- tion 2.1.4.3. Two versions of MOCHA are available: cMocha and jMocha, but only the for- mer allows for model checking ATL formulae (the latter being more simulation-oriented).
LTL formula ϕ PROMELA code Verifier Interactive Random Simulator C code TRUE FALSE LTL translator
Figure 2.13: Structure of SPIN.
Model checking is performed in MOCHA by extending the labelling algorithm presented in Figure 2.4 for CTL to ATL formulae: indeed, it has been shown in [Alur et al., 1998, Alur et al., 2002] that ATL operators can be characterised using fix-points. Therefore, the techniques presented in Section 2.2.2.2 for the verification of CTL using obdds can be extended to the verification of ATL formulae. The details of this approach can be found in [Alur et al., 1998].
Systems are specified in MOCHA by using the dedicated language ReactiveModules. Each specification consists of one or more modules; each module is characterised by a set of input variables (called external variables), by a set of output variables (called in- terface variables), and by a set of local variables. In each module, the initial value and the evolution of variables is controlled by a set of constructs called atoms. Instances of modules are created at end of the file, and they are composed in parallel. Excerpts from a ReactiveModulesprogram are reported in Figure 2.14; the full syntax of the language is available from [Alur et al., 2006].
MOCHA provides a graphical user interface to input programs written in ReactiveMod- ule, and ATL formulae. Interactive simulations and model checking may be performed either using the interface, or using command line instructions.
2.2.3.3 SMV and NuSMV
SMV (Symbolic Model Verifier, [McMillan, 1992]) and NuSMV [Cimatti et al., 2002] are two of the most widely cited model checkers. The SMV system was developed at the beginning of the 1990s to implement the obdd-based symbolic model checking techniques
module SampleModule1 private v1: bool external v2: bool interface v3: bool
atom controls v1 reads v1 awaits v3 init [. . . ] update [. . . ] endatom [. . . ] endmodule module SampleModule2 [. . . ] endmodule
Main := [. . . ] ( SampleModule1 || SampleModule2 ) [. . . ]
Figure 2.14: Excerpts from a ReactiveModule program.
for CTL presented in Section 2.2.2.2 using obdds.
NuSMV is a re-implementation of the SMV system; the tool is implemented in C language and it is available freely under an “open” license. NuSMV implements symbolic model checking techniques for CTL and bounded model checking techniques for LTL. NuSMV can operate either in “batch” mode or interactively using a text shell; in this case, sim- ulations can be performed. NuSMV accepts parameters to optimise the size of obdds by means of various heuristic functions. obdds are manipulated using the CUDD library [Somenzi, 2005].
The input languages of SMV and NuSMV present minor differences. They both allow for a compact description of systems using modules, which may be composed to describe the evolution of states. The NuSMV program for a 3 bit counter is presented in Figure 2.15, as an example to introduce the syntax of the language. A NuSMV module is identified by a string (counter cell in the figure), it may accept input parameters (carry in), and it may include “local” variables (value). The initial value of the module and the evolution of the variables are defined in the section appearing under the ASSIGN keyword, using the constructs init and next. In particular, next(value) is read as “the next value of the variable value is obtained by taking the disjunction of the current value of it with the value of the variable carry in, modulo 2”. The keyword DEFINE is used to introduce a “derived” variable, i.e., a variable which is not part of the state space, but whose value may be derived from other variables. The behaviour of the system is described in the (mandatory) module main. In the example, three instances of the module counter cell are created, imposing the constraints that carry out of counter i is equal to carry in of
MODULE counter cell(carry in) VAR value: boolean;
ASSIGN
init(value) := 0 ;
next(value) := (value + carry in) mod 2; DEFINE
carry out := value & carry in; MODULE main
VAR
bit0 := counter cell(1);
bit1 := counter cell(bit0.carry out); bit2 := counter cell(bit1.carry out);
Figure 2.15: An SMV program for a 3 bit counter (from [Cimatti et al., 2002]).
counter i + 1.
A possible execution of NuSMV in interactive mode to verify the 3 bit counter presented above is shown in Figure 2.16. In this example, NuSMV is run interactively with the option -int, and the file counter.smv is processed. At the command line of NuSMV (identified by the prompt NuSMV >), the command go launches a number of preliminary operations on the input file, including parsing the input text file and generating the obdds for the temporal relation. The command check_spec -p "AX(bit0.value=0)" launches the obdd-based verification of the CTL formula AX(bit0.value=0). As the formula is false, NuSMV outputs a counter-example.