Spin Lecture
Spin Lecture
Acknowledgements: These notes used some of the material presented by Flavio Lerda as part of Ed Clarkes model-checking course
SPIN
Generate a C program that performs an efficient online verification of the systems correctness properties Types of properties:
Deadlock, violated assertions, unreachable code System invariants, general LTL properties
each reachable state (state space) explicitly (using Nested DFS) on-the-fly computation partial order reduction memory usage
Performs Uses
Efficient
State compression
Bit-state hashing
Version
4:
LTL Translator
Buchi Automaton Buchi Translator
Promela Parser The Buchi automaton is turned into a Promela Abstract Syntax Tree process and composed Automata Automata with the rest of the system. Generator The generated verifier is C Generator specific to the model and property we started with. C Code
C Compiler Pan Verifier
Verification Result
vs
(a == b)
Process Types
State of variable or message channel can only be changed or inspected by processes (defined using proctype)
; and -> are statement separators with same semantics.
-> used informally to indicate causal relation between statements Example:
byte state = 2; proctype A() { (state == 1) -> state = 3 } proctype B() { state = state -1 }
Process Instantiation
How to do it?
By default, process of type init always executes run starts processes Alternatively, define them as active (see later)
Example
These statements are enabled only if both a and b are true. In this case b is always false and therefore there is a deadlock.
An Example
mtype = { NONCRITICAL, TRYING, CRITICAL }; mtype state[2]; proctype process(int id) { beginning: noncritical: state[id] = NONCRITICAL; if :: goto noncritical; :: true; fi; trying: state[id] = TRYING; if :: goto trying; :: true; fi; critical: state[id] = CRITICAL; if :: goto critical; :: true; fi; goto beginning;} init { run process(0); run process(1) }
NC
Other constructs
Do loops
do :: count = count + 1; :: count = count - 1; :: (count == 0) -> break od
10
Other constructs
Do loops
Communication over channels
proctype sender(chan out) { int x; if ::x=0; ::x=1; fi out ! x; }
11
Other constructs
Do loops
Communication over channels Assertions
proctype receiver(chan in) { int value; out ? value; assert(value == 0 || value == 1) }
12
Other constructs
Do loops
Communication over channels Assertions
Atomic Steps
int value; proctype increment() { atomic { x = value; x = x + 1; value = x; } }
13
Message Passing
qname!expr writing (appending) to channel qname?expr reading (from head) of the channel qname??expr peaking (without removing content) qname!!expr checking if there is room to write can declare channel for exclusive read or write: chan in, out; xr in; xs out; qname!exp1, exp2, exp3 writing several vars qname!expr1(expr2, expr3) type and params qname?vari(var2, var3)
qname?cons1, var2, cons2 can send constants Less parameters sent than received others are undefined More parameters sent remaining values are lost Constants sent must match with constants received
14
Prints:
123 15
Randez-vous Communications
Example:
#define msgtype 33
chan name = [0] of { byte, byte }; proctype A() { } proctype B() { } init { } atomic { run A(); run B() } byte state; name?msgtype(state) name!msgtype(123); name!msgtype(121); /* non-executable */
16
17
Example protocol
These users can also read received data from the channels Aout and Bout
18
Example Contd
mtype = {ack, nak, err, next, accept}; proctype transfer (chan in, out, chin, chout) { byte o, I; in?next(o); do :: chin?nak(I) -> out!accept(I); chout!ack(o) :: chin?ack(I) -> out!accept(I); in?next(o); chout!ack(o) :: chin?err(I) -> chout!nak(o) od }
19
Example (Contd)
init {
chan AtoB chan BtoA chan Ain chan Bin chan Aout chan Bout = [1] if { mtype, byte }; = [1] of { mtype, byte }; = [2] of { mtype, byte }; = [2] of { mtype, byte }; = [2] of { mtype, byte }; = [2] of { mtype, byte };
atomic { run transfer (Ain, Aout, AtoB, BtoA); run transfer (Bin, Bout, BtoA, AtoB); } AtoB!err(0) }
20
Mutual Exclusion
Petersons
problem
flag0=1
flag0=0
21
turn = 0;
(flag[1] == 0 || turn == 0); /* critical section */ flag1 == 0 || turn == 1 flag[0] = 0; goto again; } Critical Section flag1 != 0 && turn != 1 turn=0 flag0=0
22
23
24
Verification
25
Mutual Exclusion
Verifier:
Another
Have another monitor process ran in parallel Allows all possible relative timings of the processes Elegant way to check validity of system invariant
26
active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid);
27
Finally,
Can
Example:
Note: LTL
claim gets translated into NEVER claim and stored either in .ltl file or at the end of model file
Only one LTL property can be verified at a time
Parameters
29
Alternatively,
#define p ncrit <= 1 #define q ncrit = 0 bool turn, flag[2]; byte ncrit; LTL Properties: [] (p) []<> (!q)
active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid);
ncrit++; /* critical section */ ncrit--; flag[_pid] = 0; goto again;
30
Spin
Generates the Promela code for the LTL formula
$ spin f []<>p The proposition in the formula must correspond to #defines
Pan
Performs the verification
Has many compile time options to enable different features Optimized for performance
31
Xspin
32
Simulator
Spin
Can
33
A few examples
Alternating Leader
Bit Protocol
Election
They
want acknowledgement of received messages window of one message values of the identifier message is identified by one bit
Sending Each
Alternating
35
ack0
msg1
36
37
38
Sender Process
active proctype Sender() { do :: if :: receiver!msg0; :: skip fi; do :: sender?ack0 -> break :: sender?ack1 :: timeout -> if :: receiver!msg0; :: skip fi; od;
::
if :: receiver!msg1; :: skip fi; do :: sender?ack1 -> break :: sender?ack0 :: timeout -> if :: receiver!msg1; :: skip fi; od; od; }
39
Receiver Process
active proctype Receiver() { do :: do :: receiver?msg0 -> sender!ack0; break; :: receiver?msg1 -> server!ack1 od do :: receiver?msg1 -> sender!ack1; break; :: receiver?msg0 -> server!ack0 od od } mtype = { msg0, msg1, ack0, ack1 } chan sender = [1] of { mtype }; chan receiver = [1] of { mtype };
40
Summary
46
Comments
DFS
If we dont finish, we might still have some sort of a result (coverage metrics)
47
On-The-Fly
System The For
48
Visited Set
Hash
table
Efficient for testing even if the number of elements in it is very big ( 106)
Reduce
49
Compression
P0 x=0 P0 x=1 Q0 {1} P0 x=0 P1 y=0
i=0 j=0
0 0 1 0 0 2
3
2 1 0 i=0 j=0
3
2 1 0 P1 y=0
3
2 1 0 Q0 {1}
P0 x=1
P0 x=0
53
References
http://spinroot.com/
Design and Validation of Computer Protocols by Gerard Holzmann The Spin Model Checker by Gerard Holzmann
An automata-theoretic approach to automatic program verification, by Moshe Y. Vardi, and Pierre Wolper
An analysis of bitstate hashing, by G.J. Holzmann An Improvement in Formal Verification, by G.J. Holzmann and D. Peled Simple on-the-fly automatic verification of linear temporal logic, by Rob Gerth, Doron Peled, Moshe Vardi, and Pierre Wolper A Minimized automaton representation of reachable states, by A. Puri and G.J. Holzmann 58