Spin Tutorial
Spin Tutorial
Spin Tutorial
Theo C. Ruys
University of Twente Formal Methods & Tools group
http://www.cs.utwente.nl/~ruys
Credits should go to
Gerard Holzmann (Bell Laboratories)
Developer of SPIN, Basic SPIN Manual.
Advanced SPIN
intended audience: people at least at the level of Basic SPIN
Contents
Emphasis is on using SPIN not on technical details. In fact, we almost regard SPIN as a black box.
We just want to press-the-button.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 3
Overspecification
Dead code
Violations of constraints
Buffer overruns Array bounds violations
Designing concurrent (software) systems is so hard, that these flaws are mostly overlooked...
Fortunately, most of these design errors can be detected using model checking techniques!
Model checking is an automated technique that, given a finite-state model of a system and a logical property, systematically checks whether this property holds for (a given initial state in) that model. Model checking tools automatically verify whether M |= holds, where M is a (finite-state) model of a system and property is stated in some formal notation. Problem: state space explosion! SPIN [Holzmann 1991] is one of the most powerful model checkers.
Based on [Vardi & Wolper 1986].
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 5
System Development
System Engineering Analysis Design Code Testing
Maintenance
Thursday 11-Apr-2002
Model Checker
Thursday 11-Apr-2002
Model Checker
Abstraction is the key activity in both approaches. This talk deals with pure SPIN, i.e., the classic model checking approach.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial
Thursday 11-Apr-2002
Program suggestions
Some presentations at ETAPS/SPIN 2002 somehow related to this tutorial:
Dennis Dams Abstraction in Software Model Checking
Friday April 12th 10.45-13.00
John Hatcliff, Matthew Dwyer and Willem Visser Using the Bandera Tool Set and JPF (Tutorial 10)
Saturday April 13th (full day)
SPIN Applications
Saturday April 13th 11.00-12.30
Modern model checking approach.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 10
Basic SPIN
Gentle introduction to SPIN and Promela SPIN Background Promela processes Promela statements Promela communication primitives Architecture of (X)Spin Some demos: SPIN and Xspin hello world Windows 2000: OK, but mutual exclusion SPIN runs more smoothly alternating bit protocol under Unix/Linux. Cookie for the break
Thursday 11-Apr-2002
11
SPIN - Introduction
SPIN (= Simple Promela Interpreter)
(1)
= is a tool for analysing the logical conisistency of concurrent systems, specifically of data communication protocols. = state-of-the-art model checker, used by >2000 users Concurrent systems are described in the modelling language called Promela.
12
SPIN - Introduction
Major versions:
1.0 2.0 3.0 4.0 Jan 1991 Jan 1995 Apr 1997 late 2002
(2)
initial version [Holzmann 1991] partial order reduction minimised automaton representation Ax: automata extraction from C code
Documentation on SPIN
SPINs starting page: http://netlib.bell-labs.com/netlib/spin/whatispin.html
Basic SPIN manual Also part of SPINs Getting started with Xspin documentation distribution Getting started with SPIN (file: html.tar.gz) Examples and Exercises Concise Promela Reference (by Rob Gerth) Proceedings of all SPIN Workshops
Gerard Holzmanns website for papers on SPIN: http://cm.bell-labs.com/cm/cs/who/gerard/ SPIN version 1.0 is described in [Holzmann 1991].
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 14
Promela Model
Promela model consist of:
type declarations channel declarations variable declarations process declarations [init process]
mtype = {MSG, ACK}; chan toS = ... chan toR = ... bool flag; proctype Sender() { ... process body } proctype Receiver() { ... } init { ... }
A Promela model corresponds with a (usually very large, but) finite transition system, so
no unbounded data no unbounded channels no unbounded processes no unbounded process creation
Thursday 11-Apr-2002
creates processes
15
Processes
a name a list of formal parameters local variable declarations body name
(1)
formal parameters
proctype Sender(chan in; chan out) { bit sndB, rcvB; local variables do :: out ! MSG, sndB -> in ? ACK, rcvB; if body :: sndB == rcvB -> sndB = 1-sndB :: else -> skip fi The body consist of a od sequence of statements. }
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 16
Processes
A process
(2)
is defined by a proctype definition executes concurrently with all other processes, independent of speed of behaviour communicate with other processes using global (shared) variables using channels There may be several processes of the same type. Each process has its own local state: process counter (location within the proctype) contents of the local variables
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 17
Processes
Process are created using the run statement (which returns the process id). Processes can be created at any point in the execution (within any process). Processes start executing after the run statement. Processes can also be created by adding active in front of the proctype declaration.
Thursday 11-Apr-2002
(3)
proctype Foo(byte x) { ... } init { int pid2 = run Foo(2); run Foo(27); } number of procs. (opt.) active[3] proctype Bar() { ... } parameters will be initialised to 0
18
DEMO
Hello World!
/* A "Hello World" Promela model for SPIN. */ active proctype Hello() { printf("Hello process, my pid is: %d\n", _pid); } init { int lastpid; printf("init process, my pid is: %d\n", _pid); lastpid = run Hello(); printf("last pid was: %d\n", lastpid); } random seed $ spin -n2 hello.pr running SPIN in init process, my pid is: 1 random simulation mode last pid was: 2 Hello process, my pid is: 0 Hello process, my pid is: 2 3 processes created
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 19
(1)
Five different (integer) basic types. Arrays Records (structs) Type conflicts are detected at runtime.
[0..1] [0..1] [0..255] [-216-1.. 216 1] [-232-1.. 232 1] array indicing start at 0
{
Arrays
byte a[27]; bit flags[4];
Default initial value of basic Typedef (records) typedef Record variables (local and global) short f1; byte f2; is 0.
} Record rr; rr.f1 = ..
variable declaration
Thursday 11-Apr-2002
20
10
(2)
assignment =
typedef Foo { bit bb; int ii; }; Foo f; f.bb = 0; f.ii = -2;
declaration + initialisation
21
Statements
(1)
The body of a process consists of a sequence of statements. A statement is either executable/blocked depends on the global executable: the statement can state of the system. be executed immediately. blocked: the statement cannot be executed. An assignment is always executable. An expression is also a statement; it is executable if it evaluates to non-zero.
2 < 3 x < 27 3 + x
Thursday 11-Apr-2002
11
Statements
(2)
A run statement is only executable if a new process can be created (remember: the number of processes is bounded). A printf statement is always executable (but is not evaluated during verification, of course).
int x; proctype Aap() { int y=1; skip; run Noot(); x=2; x>2 && y==1; skip; }
Thursday 11-Apr-2002
Executable if Noot can be created Can only become executable if a some other process makes x greater than 2.
Theo C. Ruys - SPIN Beginners' Tutorial 23
Statements
assert(<expr>);
(3)
The assert-statement is always executable. If <expr> evaluates to zero, SPIN will exit with an error, as the <expr> has been violated. The assert-statement is often used within Promela models, to check whether certain properties are valid in a state.
proctype monitor() { assert(n <= 3); } proctype receiver() {
...
}
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 24
12
Interleaving Semantics
Promela processes execute concurrently. Non-deterministic scheduling of the processes. Processes are interleaved (statements of different processes do not occur at the same time).
exception: rendez-vous communication.
All statements are atomic; each statement is executed without interleaving with other processes. Each process may have several different possible actions enabled at each point of execution.
only one choice is made, non-deterministically.
= randomly
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 25
(X)SPIN Architecture
SPIN
M |=
random guided interactive
Promela model M
Xspin
pan.*
checker
pan.exe
|=
26
Thursday 11-Apr-2002
13
Xspin in a nutshell
Xspin allows the user to
edit Promela models (+ syntax check) simulate Promela models
random interactive guided
with dialog boxes to set various options and directives to tune the verification process
additional features
Xspin suggest abstractions to a Promela model (slicing) Xspin can draw automata for each process LTL property manager Help system (with verification/simulation guidelines)
Theo C. Ruys - SPIN Beginners' Tutorial 27
Thursday 11-Apr-2002
DEMO
Mutual Exclusion
WRONG!
(1)
proctype P(bit i) { flag != 1; models: flag = 1; while (flag == 1) /* wait */; mutex++; printf("MSC: P(%d) has entered section.\n", i); mutex--; flag = 0; Problem: assertion violation! } Both processes can pass the proctype monitor() { flag != 1 at the same time, assert(mutex != 2); i.e. before flag is set to 1. } init { atomic { run P(0); run P(1); run monitor(); } } starts two instances of process P
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 28
14
DEMO
Mutual Exclusion
WRONG!
(2)
*/ */
active proctype A() { x = 1; Process A waits for y == 0; process B to end. mutex++; mutex--; x = 0; }
active proctype monitor() { assert(mutex != 2); } Problem: invalid-end-state! Both processes can pass execute x = 1 and y = 1 at the same time, and will then be waiting for each other.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 29
DEMO
Mutual Exclusion
Dekker [1962]
(3)
*/ */ */
/* signal entering/leaving the section /* # of procs in the critical section. /* who's turn is it? active proctype B() { y = 1; turn = A_TURN; x == 0 || (turn == B_TURN); mutex++; mutex--; y = 0; }
active proctype A() { x = 1; turn = B_TURN; y == 0 || (turn == A_TURN); mutex++; mutex--; Can be generalised x = 0; to a single process. } active proctype monitor() { assert(mutex != 2); }
Thursday 11-Apr-2002
15
DEMO
Mutual Exclusion
Bakery
(4)
proctype P(bit i) { Problem (in Promela/SPIN): do turn[i] will overrun after 255. :: turn[i] = 1; turn[i] = turn[1-i] + 1; (turn[1-i] == 0) || (turn[i] < turn[1-i]); mutex++; mutex--; turn[i] = 0; More mutual exclusion algorithms od in (good-old) [Ben-Ari 1990]. } proctype monitor() { assert(mutex != 2); } init { atomic {run P(0); run P(1); run monitor()}}
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 31
if-statement
(1)
if :: choice1 -> stat1.1; stat1.2; stat1.3; :: choice2 -> stat2.1; stat2.2; stat2.3; :: :: choicen -> statn.1; statn.2; statn.3; fi;
If there is at least one choicei (guard) executable, the ifstatement is executable and SPIN non-deterministically chooses one of the executable choices. If no choicei is executable, the if-statement is blocked. The operator -> is equivalent to ;. By convention, it is used within if-statements to separate the guards from the statements that follow the guards.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 32
16
if-statement
if :: :: :: :: fi (n % 2 != 0) -> n=1 (n >= 0) -> n=n-2 (n % 3 == 0) -> n=3 else -> skip
(2)
The else guard becomes executable if none of the other guards is executable.
give n a random value if :: :: :: :: fi skip skip skip skip -> -> -> -> n=0 n=1 n=2 n=3
non-deterministic branching
do-statement
(1)
do :: choice1 -> stat1.1; stat1.2; stat1.3; :: choice2 -> stat2.1; stat2.2; stat2.3; :: :: choicen -> statn.1; statn.2; statn.3; od;
With respect to the choices, a do-statement behaves in the same way as an if-statement. However, instead of ending the statement at the end of the choosen list of statements, a do-statement repeats the choice selection. The (always executable) break statement exits a do-loop statement and transfers control to the end of the loop.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 34
17
do-statement
Example modelling a traffic light
(2)
if- and do-statements are ordinary Promela statements; so they can be nested.
active proctype TrafficLight() { byte state = GREEN; do :: (state == GREEN) -> state = YELLOW; :: (state == YELLOW) -> state = RED; :: (state == RED) -> state = GREEN; od; } Note: this do-loop does not contain
any non-deterministic choice.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 35
Communication
Sender s2r
(1)
Receiver
r2s
s2r!MSG
MSG
s2r?MSG
ACK
r2s!ACK
r2s?ACK
! is sending ? is receiving
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 36
18
Communication
(2)
Communication between processes is via channels: message passing rendez-vous synchronisation (handshake) Both are defined as channels:
name of the channel also called: queue or buffer
array of channels
37
Communication
channel = FIFO-buffer (for dim>0) !
(3)
The values of <expri> should correspond with the types of the channel declaration. A send-statement is executable if the channel is not full.
message passing If the channel is not empty, the message is fetched from the channel and the individual parts of the message are stored into the <vari>s. ch ? <const1>, <const2>, <constn>; message testing If the channel is not empty and the message at the front of the channel evaluates to the individual <consti>, the statement is executable and the message is removed from the channel.
Theo C. Ruys - SPIN Beginners' Tutorial 38
Thursday 11-Apr-2002
19
Communication
Rendez-vous communication
<dim> == 0
(4)
The number of elements in the channel is now zero. If send ch! is enabled and if there is a corresponding receive ch? that can be executed simultaneously and the constants match, then both statements are enabled. Both statements will handshake and together take the transition. Example:
chan ch = [0] of {bit, byte};
P wants to do ch ! 1, 3+7 Q wants to do ch ? 1, x Then after the communication, x will have the value 10.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 39
DEMO
(1)
Thursday 11-Apr-2002
40
20
DEMO
(2)
channel length of 2 chan toS = [2] of {mtype, bit}; chan toR = [2] of {mtype, bit}; mtype {MSG, ACK}; proctype Sender(chan in, out) { bit sendbit, recvbit; do :: out ! MSG, sendbit -> in ? ACK, recvbit; if :: recvbit == sendbit -> sendbit = 1-sendbit :: else fi od }
proctype Receiver(chan in, out) { bit recvbit; do :: in ? MSG(recvbit) -> out ! ACK(recvbit); od } init { run Sender(toS, toR); run Receiver(toR, toS); }
Thursday 11-Apr-2002
41
Germany
.. .. .. ..
<= 60 min?
holes
Holland
coffee shop
10
20
25 <= 2 pers
Thursday 11-Apr-2002
42
21
unsafe
<= 60 min?
safe
10 20 25
<= 2 pers
Thursday 11-Apr-2002
43
Advanced SPIN
Towards effective modelling in Promela Some left-over Promela statements Properties that can be verified with SPIN Introduction to SPIN validation algorithms SPINs reduction algorithms Extreme modelling: the art of modelling Beyond Xspin: managing the verification trajectory Concluding remarks Summary
Thursday 11-Apr-2002
44
22
Promela Model
A Promela model consist of:
type declarations channel declarations global variable declarations process declarations [init process]
mtype, typedefs, constants
Basic SPIN
chan ch = [dim] of {type, } asynchronous: dim > 0 rendez-vous: dim == 0 can be accessed by all processes
behaviour of the processes: local variables + statements initialises variables and starts processes
Thursday 11-Apr-2002
45
Promela statements
skip expression assignment if do break send (ch!) receive (ch?) always executable executable if not zero always executable
Basic SPIN
executable if at least one guard is executable executable if at least one guard is executable always executable (exits do-statement) executable if channel ch is not full executable if channel ch is not empty
Thursday 11-Apr-2002
46
23
atomic
atomic { stat1; stat2; ... statn }
can be used to group statements into an atomic sequence; all statements are executed in a single step (no interleaving with statements of other processes) no pure atomicity is executable if stat1 is executable if a stati (with i>1) is blocked, the atomicity token is (temporarily) lost and other processes may do a step
d_step
d_step { stat1; stat2; ... statn }
more efficient version of atomic: no intermediate states are generated and stored may only contain deterministic steps it is a run-time error if stati (i>1) blocks. d_step is especially useful to perform intermediate computations in a single transition
:: Rout?i(v) -> d_step { k++; e[k].ind = i; e[k].val = v; i=0; v=0 ; }
atomic and d_step can be used to lower the number of states of the model
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 48
24
proctype P1() { t1a; t1b; t1c } proctype P2() { t2a; t2b; t2c } init { run P1(); run P2() }
No atomicity
t1a (0,0) t2a
P1
0 t1a 1 t1b 2 t1c 3
P2
0 t2a 1 t2b 2 t2c 3
t1a (0,1) t2b t1c (2,0) t2a t1b (1,1) t2b t1a (0,2) (3,0) t2c t2a t1c (2,1) t2b t1b (1,2) t2c t1a (0,3) (3,1) t2b t1c (2,2) t2c t1b (1,3) (3,2) t2c t1c (2,3) (3,3)
proctype P1() { atomic {t1a; t1b; t1c} } proctype P2() { t2a; t2b; t2c } init { run P1(); run P2() } (0,0) (1,0) (2,0) (3,0) (3,1) (3,2) (3,3)
Thursday 11-Apr-2002
atomic
(2,1) (2,2)
(0,3) (1,3)
(2,3)
Although atomic clauses cannot be interleaved, the intermediate states are still constructed.
50
25
proctype P1() { d_step {t1a; t1b; t1c} } proctype P2() { t2a; t2b; t2c } init { run P1(); run P2() } (0,0) (1,0) (2,0) (3,0) (3,1) (3,2) (3,3)
Thursday 11-Apr-2002
d_step
(0,1) (1,1) (0,2) (1,2) (0,3) (1,3) (2,3) No intermediate states will be constructed.
Theo C. Ruys - SPIN Beginners' Tutorial 51
(2,1) (2,2)
bit aflag;
3. Check that aflag is always 0.
aflag=1;
[]!aflag
e.g.
aflag=0;
}
52
26
timeout
(1)
Promela does not have real-time features. In Promela we can only specify functional behaviour. Most protocols, however, use timers or a timeout mechanism to resend messages or acknowledgements.
timeout
SPINs timeout becomes executable if there is no other process in the system which is executable so, timeout models a global timeout timeout provides an escape from deadlock states beware of statements that are always executable
Thursday 11-Apr-2002
53
timeout
(2)
Premature timeouts can be modelled by replacing the timeout by skip (which is always executable).
One might want to limit the number of premature timeouts (see [Ruys & Langerak 1997]).
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 54
27
DEMO
(3)
abp-1.pr
perfect lines
abp-2.pr
stealing daemon (models lossy channels) how do we know that the protocol works correctly?
abp-3.pr
only three!
model different messages by a sequence number assert that the protocol works correctly how can we be sure that different messages are being transmitted?
Thursday 11-Apr-2002
55
goto
goto label transfers execution to label each Promela statement might be labelled quite useful in modelling communication protocols
wait_ack: Timeout modelled by a channel. if :: B?ACK -> ab=1-ab ; goto success :: ChunkTimeout?SHAKE -> if :: (rc < MAX) -> rc++; F!(i==1),(i==n),ab,d[i]; goto wait_ack :: (rc >= MAX) -> goto error fi fi ; Part of model of BRP
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 56
28
unless
{ <stats> } unless { guard; <stats> }
Statements in <stats> are executed until the first statement (guard) in the escape sequence becomes executable. resembles exception handling in languages like Java Example:
proctype MicroProcessor() { { ... /* execute normal instructions */ } unless { port ? INTERRUPT; ... } }
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 57
macros
#define RESET_ARRAY(a) \ d_step { a[0]=0; a[1]=0; a[2]=0; a[3]=0; }
29
error messages are more useful than when using #define cannot be used as expression all variables should be declared somewhere else
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 59
Properties
(1)
Model checking tools automatically verify whether M |= holds, where M is a (finite-state) model of a system and property is stated in some formal notation. With SPIN one may check the following type of properties: deadlocks (invalid endstates) assertions unreachable code LTL formulae liveness properties
non-progress cycles (livelocks) acceptance cycles
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 60
30
Properties
safety property
nothing bad ever happens invariant x is always less than 5 deadlock freedom the system never reaches a state where no actions are possible SPIN: find a trace leading to the bad thing. If there is not such a trace, the property is satisfied.
Thursday 11-Apr-2002
(2)
Historical Classification
liveness property
something good will eventually happen termination the system will eventually terminate response if action X occurs then eventually action Y will occur SPIN: find a (infinite) loop in which the good thing does not happen. If there is not such a loop, the property is satisfied.
61
Properties
(3)
LTL formulae are used to specify liveness properties. LTL propositional logic + temporal operators
[]P <>P P U Q always P eventually P P is true until Q becomes true
Xspin contains a special LTL Manager to edit, save and load LTL properties.
[] [] [] []
(p) ((p) -> (<> (q))) ((p) -> ((q) U (r))) ((p) -> <>((q) || (r)))
Theo C. Ruys - SPIN Beginners' Tutorial 62
31
Properties
[Brard et. al. 2001]
(4)
DEMO
(1)
chan germany_to_holland = [0] of {hippie, hippie} ; chan holland_to_germany = [0] of {hippie} ; chan stopwatch = [0] of {hippie} ; byte time ; A hippie is a byte. ... proctype Germany() Process Holland is { the dual of Germany. bit here[N] ; hippie h1, h2 ; here[0]=1; here[1]=1; here[2]=1; here[3]=1; do :: select_hippie(h1) ; select_hippie(h2) ; germany_to_holland ! h1, h2 ; IF all_gone -> break FI ; holland_to_germany ? h1 ; here[h1] = 1 ; stopwatch ! h1 ; od It can be modelled more effectively } See [Ruys 2001] for directions.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 64
32
(2)
proctype Timer() { end: do :: stopwatch ? 0 -> atomic { time=time+5 ; MSCTIME } :: stopwatch ? 1 -> atomic { time=time+10; MSCTIME } :: stopwatch ? 2 -> atomic { time=time+20; MSCTIME } :: stopwatch ? 3 -> atomic { time=time+25; MSCTIME } od } init { atomic { run Germany(); run Holland(); run Timer(); } }
Thursday 11-Apr-2002
65
while (!error & !allBlocked) { ActionList menu = getCurrentExecutableActions(); allBlocked = (menu.size() == 0); if (! allBlocked) { Action act = menu.chooseRandom(); error = act.execute(); interactive simulation: } act is chosen by the user }
act is executed and the system enters a new state Visit all processes and collect all executable actions .
s
Thursday 11-Apr-2002
act
t
66
33
Verification Algorithm
(1)
SPIN uses a depth first search algorithm (DFS) to generate and explore the complete state space.
procedure dfs(s: state) { if error(s) states are stored reportError(); in a hash table foreach (successor t of s) { if (t not in Statespace) Only works dfs(t); requires state matching for state properties. } the old states s are stored on a stack, which }
corresponds with a complete execution path
Note that the construction and error checking happens at the same time: SPIN is an on-the-fly model checker.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 67
Verification Algorithm
P1 P2
(2)
Pn
translation language intersection
interleaving product
Buchi Automaton
Buchi Automaton
accepts words
X should be empty. Search for an accepting state in the intersection, which is reachable from itself. In SPIN this Based on is implemented by two basic DFS procedures. [Vardi & Wolper 1986]. See [Holzmann 1996 et. al. DFS] for details.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 68
34
State vector
A state vector is the information to uniquely identify a system state; it contains: global variables contents of the channels for each process in the system:
local variables process counter of the process
s s hash(s)
all states are explicitly stored lookup is fast due to hash function memory needed: n*m bytes + hash table h-1 hash table
Thursday 11-Apr-2002
70
35
(Spin Version 3.4.12 -- 18 December 2001) + Partial Order Reduction the size of a single state Full statespace search for: never-claim assertion violations cycle checks invalid endstates
State-vector 96 byte, depth reached 18637, errors: 0 169208 states, stored 71378 states, matched 240586 transitions (= stored+matched) 31120 atomic steps hash conflicts: 150999 (resolved) total number (max size 2^19 states)
Stats on memory usage (in Megabytes): 17.598 equivalent memory usage for states (stored*(State-vector + overhead)) 11.634 actual memory usage for states (compression: 66.11%) State-vector as stored = 61 byte + 8 byte overhead 2.097 memory used for hash-table (-w19) 0.480 memory used for DFS stack (-m20000) 14.354 total actual memory usage
Reduction Algorithms
(1)
SPIN has several optimisation algorithms to make verification runs more effective:
partial order reduction bitstate hashing minimised automaton encoding of states (not in a hashtable) state vector compression dataflow analysis slicing algorithm
36
Reduction Algorithms
Partial Order Reduction
(2)
enabled by default
observation: the validity of a property is often insensitive to the order in which concurrent and independently executed events are interleaved idea: if in some global state, a process P can execute only local statements, then all other processes may be deferred until later local statements, e.g.:
statement accessing only local variables receiving from a queue, from which no other process receives sending to a queue, to which no other process sends
It is hard to determine exclusive access to channels: let user annotate exclusisve channels with xr or xs.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 73
Reduction Algorithms
Partial Order Reduction (cont.)
Suppose the statements of P1 and P2 are all local. t1a t1b (1,0) t1c (2,0) (3,0) t2a (3,1) t2b (3,2) t2c (3,3)
Thursday 11-Apr-2002
(3)
(2,1) (2,2)
74
37
Reduction Algorithms
Bit-state hashing
approximation
(3)
instead of storing each state explicitly, only one bit of memory are used to store a reachable state given a state, a hash function is used to compute the address of the bit in the hash table no collision detection hash factor = # available bits / # reached states
aim for hash factor > 100
Hash-compaction
large hash table: 2^64 store address in regular (smaller) hash table with collision detection
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 75
Reduction Algorithms
Bit-state hashing
(cont.)
0 0 1 0 1 1 0 0 0 0 1 0 0 1 0 h-1 1 hash table
Thursday 11-Apr-2002
(4)
hash(s)
If hash(s) = n and h[n] == 1, SPIN concludes that s has already been visited.
states are not stored explicitly lookup is fast due to hash function memory needed: hash table (only)
76
38
Reduction Algorithms
State compression
(5)
instead of storing a state explicitly, a compressed version of the state is stored in the state space
Minimised automaton
states are stored in a dynamically changing, minimised deterministic finite automaton (DFA) very memory inserting/deleting a state changes the DFA effective, but slow. close relationship with OBDDs
1980: pan 1987: bitstate hashing 1995: partial order reduction 1999: minimised automaton memory requirements to (fully) verify Tpc
7 days
Thursday 11-Apr-2002
7 secs
Theo C. Ruys - SPIN Beginners' Tutorial 78
39
Thursday 11-Apr-2002
80
40
Invariance
[]P where P is a state property
[]P
safety property invariance global universality or global absence [Dwyer et. al. 1999]:
25% of the properties that are being checked with model checkers are invariance properties BTW, 48% of the properties are response properties
examples:
[] !aflag [] mutex != 2
Thursday 11-Apr-2002
81
variant
(single assert)
[]P
proposed in SPIN's documentation add the following monitor process to the Promela model:
active proctype monitor() { assert(P); } 1 assert(P) 2 -end0
Two variations:
1. monitor process is created first 2. monitor process is created last
If the monitor process is created last, the endtransition will be executable after executing assert(P).
82
Thursday 11-Apr-2002
41
variant
[]P
Drawback of solution 1+2 monitor process is that the assert statement is enabled in every state.
active proctype monitor() { atomic { !P -> assert(P) ; } }
The atomic statement only becomes executable when P itself is not true.
We are searching for a state where P is not true. If it does not exist, []P is true.
Theo C. Ruys - SPIN Beginners' Tutorial
Thursday 11-Apr-2002
83
variant
4 - monitor process
(do assert)
[]P
From an operational viewpoint, the following monitor process seems less effective:
active proctype monitor() { do :: assert(P) od }
assert(P)
Thursday 11-Apr-2002
84
42
variant
5 - never claim
(do assert)
[]P
SPIN will synchronise the never claim automaton with the automaton of the system. SPIN uses never claims to verify LTL formulae.
Thursday 11-Apr-2002
85
variant
The logical way...
6 - LTL property
[]P
Thursday 11-Apr-2002
86
43
variant
[]P
Enclose the body of (at least) one of the processes into the following unless clause:
{ body } unless { atomic { !P -> assert(P) ; } }
Discussion
+ + no extra process is needed: saves 4 bytes in state vector local variables can be used in the property P definition of the process has to be changed the unless construct can reach inside atomic clauses partial order reduction may be invalid if rendez-vous communication is used within body This is quite the body is not allowed to end restrictive
Note: disabling partial reduction (-DNOREDUCE) may have severe negative consequences on the effectiveness of the verification run.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 87
[]P
60 50 40 30 20 10 0 brp
Thursday 11-Apr-2002
1. monitor first 2. monitor last 3. guarded monitor 4. monitor do assert 5. never do assert 6. LTL property 7. unless
philo
pftp
88
44
[]P
1. monitor first 2. monitor last 3. guarded monitor 4. monitor do assert 5. never do assert 6. LTL property 7. unless
Thursday 11-Apr-2002
[]P
seems attractive...
90
Thursday 11-Apr-2002
45
[]P
1. monitor first 2. monitor last 3. guarded monitor 4. monitor do assert 5. never do assert 6. LTL property
Thursday 11-Apr-2002
Invariance - Conclusions
The methods 1 and 2 monitor process with single assert performed worst on all experiments.
When checking invariance, these methods should be avoided.
[]P
Variant 4 monitor do assert seems attractive, after verifying the pftp model.
unfortunately, this method modifies the original pftp model! the pftp model contains a timeout statement because the do-assert loop is always executable, the timeout will never become executable never use variant 4 in the presence of timeouts
Variant 3 guarded monitor process is the most effective and reliable method for checking invariance.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 92
46
2. Partial check
Use SPINs bitstate hashing mode to quickly sweep over the state space. states are not stored; fast method
3. Exhaustive check
If this fails, SPIN supports several options to proceed: 1. Compression (of state vector) 2. Optimisations (SPIN-options or manually) 3. Abstractions (manually, guided by SPINs slicing algorithm) 4. Bitstate hashing
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 93
47
Beyond Xspin
retrieve
Promela model
shell script to automatically run spin, gcc & pan
runspin
ppr
LaTeX file .csv file
Thursday 11-Apr-2002
ppr
parse pan results: recognises 49 items in verification report Perl script (600 loc) output to LaTeX or CSV (general spreadsheet format)
Thursday 11-Apr-2002
96
48
Read SPIN (html) documentation thoroughly. Consult Proceedings of the SPIN Workshops:
papers on successful applications with SPIN papers on the inner workings of SPIN papers on extensions to SPIN
Further reading
[Holzmann 2000 Mdorf]
Thursday 11-Apr-2002
(1)
See Extended Abstract of this tutorial in the SPIN 2002 Proceedings for:
Techniques to reduce the complexity of a Promela model (borrowed from Xspins Help). Tips (one-liners) on effective Promela patterns.
See [Ruys 2001] for details.
49
(2)
Atomicity Enclose statements that do not have to be interleaved within an atomic / d_step clause Beware: the behaviour of the processes may change! Beware of infinite loops. Computations use d_step clauses to make the computation a single transition reset temporary variables to 0 at the end of a d_step Processes sometimes the behaviour of two processes can be combined into one; this is usually more effective.
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 99
Summary
Basic SPIN
Promela basics Overview of Xspin Several Xspin demos
Advanced SPIN
Some more Promela statements SPINs reduction algorithms Beyond Xspin: verification management Art of modelling
Final word of advice: get your own copy of SPIN and start playing around!
Thursday 11-Apr-2002 Theo C. Ruys - SPIN Beginners' Tutorial 100
50