Model Checking with
SPIN
Concurrent and Distributed Programming
http://fmt.cs.utwente.nl/courses/cdp/
HC 3 - Tuesday, 29 November 2011
CDP #3
Marieke Huisman, Jaco van de Pol
http://fmt.cs.utwente.nl/~vdpol/
Jaco van de Pol Lecture 3: Model Checking with SPIN
Overview of Lecture 3
Ch. 4 - Verification of Concurrent Programs
linear temporal logic (LTL)
deductive proof of Dekker’s algorithm with LTL
model checking with SPIN
2
Jaco van de Pol Lecture 3: Model Checking with SPIN
Linear Temporal Logic (LTL)
LTL
= propositional logic + temporal operators
Syntax of LTL:
3 Φ := p atomic proposition | ¬Φ | Φ ∨ Φ | Φ ∧ Φ | Φ Φ | !Φ neXt | ΦUΦ Until | "Φ eventually (Finally) | #Φ always (Globally) wantp = true turn = 2 pcp = p1 an atomic proposition p iseither true or false in a state
temporal operators # (turn≤2) " (x≥10) # (x≥0 ∧ x<10) x=10 !(x≥10 U x=0) "# (x=0 U y=0) Some examples Boolean connectives
Jaco van de Pol Lecture 3: Model Checking with SPIN
First attempt
(revisited)
Idea: each process gets its
turn
to enter the critical section.
4 Alg. 3.2 (p. 48) integer turn integer turn ← 1
p
q
loop forever p1: non-critical section p2: await turn = 1 p3: critical section p4: turn ← 2 loop forever q1: non-critical section q2: await turn = 2 q3: critical section q4: turn ← 1await p = statement that waits until the condition p becomes true
We know from lecture 2 that this attempt is deadlock free (?), does ensure mutual exclusion, but is not free from starvation.
Jaco van de Pol Lecture 3: Model Checking with SPIN
Idea: the right to insist on entering is passed between the processes.
Dekker’s algorithm
(revisited)
5Alg. 3.10 (p. 60)
boolean wantp ← false, wantq integer turn ← 1
← false, wantq ← false 1 p q loop forever p1: non-critical section p2: wantp ← true p3: while wantq p4: if turn = 2 p5: wantp ← false p6: await turn = 1 p7: wantp ← true p8: critical section p9: turn ← 2 p10: wantp ← false loop forever q1: non-critical section q2: wantq ← true q3: while wantp q4: if turn = 1 q5: wantq ← false q6: await turn = 2 q7: wantq ← true q8: critical section q9: turn ← 1 q10: wantq ← false
Jaco van de Pol Lecture 3: Model Checking with SPIN
Dekker’s algorithm - progress
(1)
We want to
prove
progress
of Dekker’s
algorithm.
Property to prove ‘if p enters the preprotocol, it eventually will enter the critical section’. In LTL: #(p2 !p8)
The proof needs some invariants:
Invp: wantp p3..5,8..10 Invq: wantq q3..5,8..10 Invt: #(turn=1 ∨turn=2)
6 Alg. 3.10 (p. 60)
boolean wantp ← false boolean wantq ← false integer turn ← 1 p loop forever p1: non-critical section p2: wantp ← true p3: while wantq p4: if turn = 2 p5: wantp ← false p6: await turn = 1 p7: wantp ← true p8: critical section p9: turn ← 2 p10: wantp ← false
Dekker’s algorithm - progress
(2)
Case 1: q stays in its non-critical section forever: !"q1
7 boolean wantp ← false boolean wantq ← false integer turn ← 1 p loop forever p1: non-critical section p2: wantp ← true p3: while wantq p4: if turn = 2 p5: wantp ← false p6: await turn = 1 p7: wantp ← true p8: critical section p9: turn ← 2 p10: wantp ← false #(p2 !p8)
1. "q1 "¬wantq invariant Invq
2. "(p2 !p3) progress at p2: assignment
3. "( p3 ∧"¬wantq !p8) progress at p3: skip while
So: "(p2 ∧"q1) !p8 from 1, 2 and 3
Two cases: either q eventually stays in its non-critical section, or it will always leave it: !"q1 ∨ "!¬q1
Proof by contradiction: Assume p2 and ¬!p8. (p will never enter its critical section)
Then: "(p2..7). (*)
Dekker’s algorithm - progress
(3)
Case 2: q leaves its non-critical section: "!¬q1
8 p loop forever p1: non-critical section p2: wantp ← true p3: while wantq p4: if turn = 2 p5: wantp ← false p6: await turn = 1 p7: wantp ← true p8: critical section p9: turn ← 2 p10: wantp ← false #(p2 !p8)
Step 2.1: first we will prove: !"turn=1
Step 2.1: first we will prove: !"turn=1
Step 2.1: first we will prove: !"turn=1
1 Assume: "turn=2 towards contradiction 2 Then: !"p6 progress p, using (1), (*) 3 Then: !"¬wantp by invariant Invp 4 Then: !q9 progress q 5 Then: !turn=1 assignment q9 Contradiction, so ¬"turn=2, so !turn=1 (we use Invt)
Since "(p2..7), we obtain !"turn=1 (p9 never reached)
q loop forever q1: non-critical section q2: wantq ← true q3: while wantp q4: ... q8: critical section q9: turn ← 1
Jaco van de Pol Lecture 3: Model Checking with SPIN
Dekker’s algorithm - progress
(4)
9#(p2 !p8)
1. ""turn=1 turn=1 !!""(p3 (p3 ∨∨ p4) p4) see p and ass. (2)
2. HenceHence!!""(wantp)(wantp) from Invariant Invp
3. HenceHence!!""q6q6, so also , so also !!""(¬wantq)(¬wantq) see q, ass (3), and Invq
4. Hence!p8 progress p at line p3 progress p at line p3 Step 2.2: we now prove contradiction with ¬!p8. Recall the following assumptions/conclusions:
1: "!¬q1 2: "(p2..7) 3: !"(turn=1) Proof Contradiction! p loop forever p1: non-critical section p2: wantp ← true p3: while wantq p4: if turn = 2 p5: wantp ← false p6: await turn = 1 p7: wantp ← true p8: critical section p9: turn ← 2 p10: wantp ← false q loop forever q1: non-critical section q2: wantq ← true q3: while wantp q4: if turn = 1 q5: wantq ← false q6: await turn = 2 q7: wantq ← true q8: critical section q9: turn ← 1 q10: wantq ← false
Jaco van de Pol Lecture 3: Model Checking with SPIN
Proof techniques
Proof techniques so far:
1. Use the state diagram to check the property. 2. Inductive proof of invariant.
3. Deductive proof using LTL.
Drawbacks
of these proof techniques
labor intensive error prone
10
Jaco van de Pol Lecture 3: Model Checking with SPIN
Verification of correctness
11concurrent
program requirementsbehaviour,
physical world mathematical world structure properties confidence by validation proof by verification model, state diagram modelling formal properties temporal logic formalising
Jaco van de Pol Lecture 3: Model Checking with SPIN
Turing Award 2007
12“For their groundbreaking work on Model Checking,
Edmund M. Clarke, E. Allen Emerson, and Joseph Sifakis
are the recipients of the 2007 A.M. Turing Award for their work on an automated method for finding design errors in computer hardware and software. The method, called
Model Checking, is the most widely used technique for detecting and diagnosing errors in complex hardware and software design. It has helped to improve the reliability of
complex computer chips, systems and networks.”
February 4, 2008
CDP - 3
13
SPIN
14Model Checking
15M
|
=
φ
State space explosion: the state space grows exponentially in the number of parallel components.
Model Checker
yes! no!+
byte n; proctype Foo() { do :: n = (n+1) % 10; od } modelM
[] (n < 10) propertyφ
A model checker simply generates the complete state diagram of the
model (and its property).
SPIN - History
Major versions:
16
Some success factors of SPIN ‘push-the-button’ verification style very efficient implementation (using C) nice graphical user interface (Xspin) not just a research tool, but well supported
contains more than two decades of research on advanced computer aided verification (many optimization algorithms)
in 2001
other winners: 1983 UNIX 1986 TeX 1995 www 1997 Tcl/Tk 2001 SPIN 2002 Java 2003 Make 2006 Eiffel 2007 Statemate 1.0 Jan 1991 initial version (1st SPIN book)2.0 Jan 1995 partial order reduction
3.0 Apr 1997 minimised automaton representation 4.0 Jan 2003 embedded C code; BFS; abstraction 5.0 Nov 2007 multi-core verification
Jaco van de Pol Lecture 3: Model Checking with SPIN
SPIN - resources
Documentation
on SPIN can be found on spinroot.
Basic SPIN manual Tutorials
Concise Promela reference (by Rob Gerth) Proceedings of all 17 SPIN Workshops
Installation
Source code for SPIN is available from spinroot.
C compiler suite (preferably gcc) is not only needed to compile
SPIN, but also to generate verifiers.
Tcl/Tk is needed to run Xspin.
17 http://spinroot.com/
Download and install SPIN as soon as possible! SPIN will be used in the 2nd and 3rd practical exercise.
This lecture only introduces SPIN. You are expected to consult the documentation to learn more about SPIN.
http://www.utwente.nl/spin2010/
Jaco van de Pol Lecture 3: Model Checking with SPIN
Literature on SPIN
(and MC)
18The SPIN Model Checker (Primer and Reference Manual). Gerard J. Holzmann.
Addison-Wesley, 2004. Principles of SPIN.
Mordechai (Moti) Ben-Ari. Springer-Verlag, 2008.
Principles of Model Checking.
Christal Baier and Joost-Pieter Katoen. MIT Press, 2008.
The reference on SPIN!
Gentle introduction to SPIN.
Full, theoretical treatment of model checking.
Jaco van de Pol Lecture 3: Model Checking with SPIN
Promela
Promela
(= Protocol/Process Meta Language)
specification language to model finite-state systems
loosely based on CSP
dynamic creation of concurrent processes communication via message channels can be
synchronous (i.e. rendez-vous), or asynchronous (i.e. buffered)
features from Dijkstra’s guarded command language features from the programming language C
19
Promela is a modelling language, not a programming language!
= SPIN’s modelling language
Jaco van de Pol Lecture 3: Model Checking with SPIN
Promela model
A Promela model defines a finite set of processes, which together constitute the behaviour of the system.
A process
executes concurrently with all other processes, independent of speed or behaviour (i.e. arbritrary interleaving)
communicates with other processes using global (shared) variables using communication channels is defined by a proctype definition
Apart from the proctype definitions, a Promela model consists of declarations, which glue the processes together (e.g., types, variables, messages, channels).
Jaco van de Pol Lecture 3: Model Checking with SPIN
21
Promela statements
The body of a Promela proctype consists of a sequence of
statements
. Based on the current
state
— the values of all
the variables — a
statement
is either
executable: the statement can be executed immediately
blocked: the statement cannot be executed
assignment always executable wantp = true; assertion always executable assert(mutex<2); printf always executable printf(“Hello”); expression executable if expression is non-zero turn==1;
Jaco van de Pol Lecture 3: Model Checking with SPIN
Promela by example
22 byte turn = 1; active proctype P() { do :: /* non-critical section */ turn == 1; /* critical section */ turn = 2; od } active proctype Q() { do :: /* non-critical section */ turn == 2; /* critical section */ turn = 1; od } integer turn ← 1 p loop forever p1: non-critical section p2: await turn = 1 p3: critical section p4: turn ← 2 q loop forever q1: non-critical section q2: await turn = 2 q3: critical section q4: turn ← 1Semantics of Promela is the same as of Ben-Ari’s process language:
•arbitrary interleaving of statements of processes •individual statements are atomic
active processes run at the start of the system
expressions are blocked if they evaluate to zero global variable, accessible to all processes
assignments are always executable
endless loop (no break)
expressions model the ‘await’
Ben-Ari’s first attempt to mutex.
Promela by example
23boolean wantp ← false boolean wantq ← false integer turn ← 1 p loop forever p1: non-critical section p2: wantp ← true p3: while wantq p4: if turn = 2 p5: wantp ← false p6: await turn = 1 p7: wantp ← true p8: critical section p9: turn ← 2 p10: wantp ← false q ...
bool wantp = false; bool wantq = false; byte turn = 1; active proctype P() { do :: /* non-critical section */ wantp = true; do :: wantq -> if :: turn == 2 -> wantp = false; turn == 1; wantp = true; :: else fi :: else -> break od;
printf("P is in the critical section\n"); turn = 2;
wantp = false; od
} ...
breaks out of the inner do-loop one of the executable guards is selected
else becomes executable if none of the other guards are executable
-> is the same as ;
the arrow is typically used for guards
Dekker’s algorithm
SPIN
SPIN = Simple Promela Interpreter Three main components:
simulator for Promela models
random, interactive, guided simulation
generator of verifiers for Promela models (+ property)
the verifier is a C program
translator of LTL properties to Promela never claims
Xspin is GUI on top of SPIN
jSpin is an alternative GUI written in Java
http://stwww.weizmann.ac.il/g-cs/benari/jspin/
SpinJa is a reimplementation in Java (Ruys/de Jonge/FMT)
http://fmt.cs.utwente.nl/gitweb/?p=spinja.git
Jaco van de Pol Lecture 3: Model Checking with SPIN
Verification with SPIN
Safety
properties
deadlocks (invalid endstates)
A valid endstate is either the proctype’s closing } or a state which starts with end
assertions
A predicate which is assumed to be always true (cf. invariant).
Liveness
properties
LTL propertiesprogress or accept cycles support for weak fairness
25
Jaco van de Pol Lecture 3: Model Checking with SPIN
DEMOs
mutex-2.prom
use assert to show that mutual exclusion is not ensured
mutex-3.prom
let SPIN find the deadlock (= invalid endstate)
mutex-dekker.prom
use LTL property to show that mutual exclusion is ensured
use LTL property to show that progress is ensured
only when weak fairness is enabled
26 27 spin.exe
M
|
=
φ
correct error (+ counter example) pan.c ANSI C gcc verifiersimulator verifier generator LTL translator
Architecture of (X)spin
M
model propertyφ
•random •interactive •guided • deadlocks • assertions • LTL properties • liveness propertiesJaco van de Pol Lecture 3: Model Checking with SPIN
28
Semantics of a proctype
Every Promela
proctypedefines a
finite state automaton
(S, s0, L, T, F)
where
S! is a set of statess0! is the initial state s0 ∈ S
L! is the finite set of labels
T! is a set of transitions, T ⊆ S " L " S
F! is a set of final states, F ⊆ S A label l ∈ L is one of the six basic Promela statements:
•assignment • assert • printf •expression •send (!) •receive (?)
Other Promela statements (e.g. do, if) serve to specify
CDP - 3 29 17 12 wantp=1 8 wantq 15 else 4 turn==2 else 16 printf turn=2 5 wantp=0 6 turn==1 wantp=1 active proctype P() { do :: /* non-critical section */ wantp = true; do :: wantq -> if :: turn == 2 -> wantp = false; turn == 1; wantp = true; :: else fi :: else -> break od; printf("..."); turn = 2; od }
to let SPIN generate the automaton:
spin -a -o3 dekker.prom gcc -o pan pan.c ./pan -d P R O C E S S A U T O M A T O N
Jaco van de Pol Lecture 3: Model Checking with SPIN
Most Promela constructs
30assignment always executable
assert always executable
printf always executable
expression executable if non zero (i.e. true)
send (ch!) executable if channel is not full
receive (ch?) executable if channel is not empty
skip == true == 1 always executable
timeout variable, true if no other statement is executable
else variable, true if none of the guards are executable
if executable if at least one guard is executable
do executable if at least one guard is executable
atomic { ... } executable if first statement is executable
d_step { ... } executable if first statement is executable
goto always executable (jump to label)
break always executable (exit enclosing do-loop)
six basic statements expression statements compound statements control-flow specifiers
Glue
Basic types
bit, bool, byte, short, int
Records
user defined, C-style typedefs
Arrays
one-dimensional from basic or typedefs
Variables
global or local
basic type, typedef, array
31 bit turn=1; [0..1] bool flag; [0..1] byte counter; [0..255] short s; [-2^15..2^15 –1] int msg; [-2^31..2^31 –1] typedef Foo { short f1; byte f2; }; byte a[27]; bit flags[4]; Foo f[2]; f[0].f1 = -11; f[0].f2 = 255;
Branching
If there is at least one guard executable, the if-statement is executable and SPIN
non-deterministically chooses one of the executable guards.
If none of the guards is executable the
if-statement is blocked.
There is a special guard named ‘else’. This variable becomes true if all other guards are blocked.
32
if
:: guard1 -> stat12; stat13; ...
:: guard2 -> stat22; stat23; ...
:: guard3 -> stat32; stat33; ...
:: ...
:: guardn -> statn2; statn3; ...
fi; if fi g1 g2 g3 .. gn if :: (n % 2 != 0) -> n=1 :: (n >= 0) -> n=n-2 :: (n % 3 == 0) -> n=3 :: else -> skip fi;
What is the highest value of n for which the else guard becomes executable?
Jaco van de Pol Lecture 3: Model Checking with SPIN
Looping
With respect to the (selection of the) guards, a do-statement behaves in the
same way as an if-statement. However, instead of ending the statement at the end of the chosen sequence of statements, a do -statement starts again. The (always executable) break
statement exits a do-loop statement and transfers control to the end of the do-loop (i.e. after the od).
33
do
:: guard1 -> stat12; stat13; ...
:: guard2 -> stat22; stat23; ...
:: guard3 -> stat32; stat33; ...
:: ...
:: guardn -> statn2; statn3; ...
od; do g1 g2 g3 .. gn byte n=0; do :: n<=10 -> break; :: n<10 -> n=n+1; od;
What is the value of n after this loop?
Jaco van de Pol Lecture 3: Model Checking with SPIN
Pros and Cons of Model Checking
34Pros
potential “push-button” technology
widely applicable (hardware, software, protocols, etc.)
allows for partial verification (only the most relevant properties) rapidly increasing industrial interest
in case of property violation, a
counter-example is provided sound and interesting mathematical foundations
not biased to the most possible
scenario (such as testing)
Cons
mainly focused on control-intensive applications (less data-oriented)
any validation using model checking is only as ‘good’ as the system model
no guarantee about
completeness of results
impossible to check
generalisations (in general)
Model checking can provide a
significant increase in the level of
confidence of a system design.
Jaco van de Pol Lecture 3: Model Checking with SPIN
Verification vs. Debugging
There are roughly
two approaches
with respect to the
application of model checkers.
The verification approach tries to ascertain the correctness of a detailed model M of the system under verification.
The debugging approach tries to find errors in a model M.
Model checking is
most effective
as a design
debugging
approach.
35
Automatic verification is not just good for proving correctness. It also excels at finding bugs very early in the design of a new system.