Вы находитесь на странице: 1из 66

Promela

Spin

.. , ..
-

2009


...................................................................................................................................................................4
1.

PROMELA......................................................................................................7
1.1.

XSpinHelloworld.............................................................................7

1.2.

Promela..............................................................................................................10

....................................................................................................................................................................10
.........................................................................................................................................................................12
..................................................................................................................................................................................14
....................................................................................................................................................16
......................................................................................................................................................17
...........................................................................................................................................................................18

1.3 ...............................................................................................................................20
atomic........................................................................................................................................................................20
...............................................................................................................................................................21
......................................................................................................................................................................................22

1.4 ...................................................................................................................................23
2

PROMELASPIN.......................................................................25
2.1 assert......................................................................................................................................26
2.2 (end).............................................................................................26
2.3 (progress).............................................................................................27
2.4 (accept)..........................................................................................28
2.5 never...............................................................................................................................28

SPIN..............................................................................................................33
3.1 .........................................................................33
............................................................................................................................................................33
Promela................................................................................................................34
Promela......................................................................................................35
.....................................................................................................................36
...........................................................................................................................................38
LTL..........................................................................................................................................................38

3.2 ,,.................................................................................................43
..................................................................................................................................................................43
,Promela...............................................................................................43
Spin............................................................................................................................44

3.3 ................................................................................47
............................................................................................................................................................47
Promela..................................................................................................................................48
Promela.......................................................................................................51
........................................................................................................................................54

3.4 .............................................................................................................55
............................................................................................................................................................55

Promela..................................................................................................................................56
.....................................................................................................................58

3.5 ...................................................................................................................................................59
Promela..................................................................................................................................60
Spin............................................................................................................................62

1..........................................................................................................................63
2............................................................................................65
....................................................................................................................................................................66



.

, , .

Spin. Spin :

(, ,
)

(
)

( push button technique )



.

Spin ,
Bell Labs (Jerard
Holzmann), ,

. ,
Spin
. ACM (Association for Computing
Machinery) Spin ACM Software System
Award 2001 . 1983 UNIX, 1997 . Tcl/Tk,
2002 . Java.
Spin .
http://spinroot.com/.
, .
Spin Gerard J. Holzmann. The Spin Model checker.
Spin .
Spin ,
, .
Spin , .
(
) - Spin,
Promela (Protocol Meta Language).
Promela .
Promela , ,
()
,
..
Spin
Promela.

Simple

Promela

Interpreter

Spin .
Spin
-
(Message Sequence Diagrams),
.
XSpin .
4

, ,
.
Spin. , ,
, .

, .
Spin
. , Spin .
Promela ,
, , Java C.
Promela ,
, .
.
,
,
.
,
. ,
,
.
Promela
. , ,
Promela,
.
, , Spin,
.
( ).
, , :
, ,
,
...
Promela.
, ,
. .
Promela,
, , .
, ,
(, ),
, Rockwell Collins, - MDD
(Model Driven Development).
:
,
,
,
.

.
Promela.
. , :
5

, , ,
-.
, .. , Spin ,
.
, ,
,
.. ,
. , (..
) 10 .
,
Spin .
. , Spin
. Spin
.
, . Spin,
, . ,
,
, .


,
552822
, ( SPB/R&D/139/ 2006 16.11.2006
.).

1. Promela
Promela - .
, (
,
)
,
(
). , Promela (
), .
Promela
. Promela
, , , .
.
, Promela , ,
.
.
,
, , , ,
, . .
( Spin);
(
); .
Promela, ,
, , , . ""
Promela
,
.


, .
,
,
model checking
. Spin
. , , ,
Spin Deep
Space 1, ,
.

1.1.

XSpin Hello world

Spin ,
. XSpin.
XSpin ( XSpin 1
Spin c GUI XSpin).

XSpin . Edit
: Copy, Cut, Paste. View
.
(command-log).
.
Promela.

, hello world .
(1978),
. .
Promela:
active proctype example()
{
printf("MSC: hello world\n")
}

Promela
, .. .
Spin . C,
main. proctype
example. active ,
example .
, .
, proctype,
.

XSpin. hello
File. ,
ReOpen File XSpin.
Promela,
Run Run Syntax Check. hello ,
no syntax errors.
8

Spin
Spin ( (Re)Run Simulation Run).
( Set Simulation
Parameters Run).

(Display Mode) ,
MSC
Panel, Time Sequence Panel,
Data Values Panel
Execution Bar Panel ( . 1).
,
printf
printf("MSC: ")

MSC Panel.
Simulation Style . :
Random ,
Guided, Interactive
.
Random simulation. , Start.

Spin .
(Simulation Output) ,
. Run, .
1 printf.

, ,
.
.

, , Sequence Chart,
.
example 0 hello world.

1.2.

Promela

, Promela, :
(processes), (message channels) (data objects).
, ,
.

proctype.
Promela
- .
.
.
2 you_run active:
active [2] proctype you_run(){
printf("MSC: my pid is: %d\n", _pid)
}

,
.
_pid.
10

,
.
. (
,
). , Promela
.
Promela : ->
;. .
-
: ,
(, , ).

,
you_run.

1 0 printf,
1 printf, .
, ,
printf .
(Sequence Chart) .
, run.
proctype you_run(byte x)
{
printf("MSC: x is %d\n", x);
printf("MSC: my pid is = %d\n", _pid)
}
init {
run you_run(0);
run you_run(1)
}

11

init you_run
. . init
Promela, .
init . ,
0.

, (
init), . ,
.
run ,
, .. init.
,
, -. ,
Spin 255.

Promela C (. . 1) .
. 1. 32 .

bit
bool
byte
chan
mtype
pid
short
int
unsigned

0,1
false,true
0..255
1..255
1..255
0..255
215 .. 215 1
231 .. 231 1
0 .. 232 1

Promela : . ,
, .
,
, , ,
. , ,
12

, .
, (..
).
( false).
bool flag;
int state;
byte msg;

/* */

: /* */.
Promela ,
byte state[N]

state N ,

state[0] = state[3] + 5 * state[3*2/n]

n .
, .
0.. N-1 ; ,
(runtime error).
typedef (.
- .3.3).
mtype (mnemonic type, )
,
. ,
. , mtype,
, .
mtype 255 :
mtype = { apple, pear, orange, banana };
mtype = { fruit, vegetables, cardboard };
init {

mtype n = pear;
printf("MSC: %e
n = fruit;
printf("MSC: is

/* n pear */
", n);
/* n fruit */
%e\n ", n)

printf

C.
: .
: d
, i
, , e
mtype.
Spin printf
MSC: .

13



. chan:
chan qname = [16] of { short }

qname 16, .. 16
short, .. 16 .
.
! :
qname ! expr

expr qname,
. ,
, .
FIFO: .
?:
qname ? msg

msg.
, .
, .. , ,
, :
chan pname = [16] of { byte, int, chan }

pname ,
( byte, ), 32-
( int) . ()
( )
(. .3.1). ,
.

pname ! expr1,expr2,expr3

,
:
pname ? var1, var2, var3

(,
).
mtype:

14

/* : */
mtype = { ack, nak, err, next, accept }
/* : */
mtype msgtype1, msgtype2;

mtype
,
. :
chan tname = [4] of { mtype, int, bit };

qname , :
mtype, , .

tname ! msgtype (data, b)

:
tname ! msgtype, data, b

,
:
tname ! ack, var, 0

/* tname
(ack mtype 0)
var */

tname ? ack (data,1) /* qname ,


ack
mtype, int,
data,
1
*/

,

. . ,
,
<ack,15,0 >.
, , ,
, . ,
- , .
(Bartlett, Scantlebury
Wilkinson [1]):
mtype = { msg, ack };
chan
chan

/* */

to_sndr = [2] of { mtype, bit };


to_rcvr = [2] of { mtype, bit };

active proctype Sender(){


again: to_rcvr!msg,1;
to_sndr?ack,1;

/* */
/* */

/* */
/* , 1 */
/* , 1 */

15

/* , 0 */
/* , 0 */

to_rcvr!msg,0;
to_sndr?ack,0;
goto again
}
active proctype Receiver(){
again: to_rcvr?msg,1;
to_sndr!ack,1;
to_rcvr?msg,0;
to_sndr!ack,0;
goto again
}

/* */
/* , 1 */
/* , 1 */
/* , 0 */
/* , 0 */

-
, 1, 0, .
- , 1, 0,
- .
, .
goto again
.
Promela (len, empty, nempty, full,
nfull). , len(qname)
, qname . len
, , ,
.. ,
, .
, msgtype ,
qname :
(len(qname) < MAX) -> qname ! msgtype

qname
,
.
, ,
qname ( MAX)
, , .


,
chan qname = [N] of { byte }

N ,
. , 0:
chan port = [0] of { byte }

- (
). , ,
16

. -
. .
#define msgtype 1
chan name = [0] of { byte, byte };
proctype A()
{
name ! msgtype(4);
name ! msgtype(1)
}
proctype B()
{
byte state;
name ? msgtype(state)
}
init
{
atomic { run A(); run B() }
}

name -.
: ()
msgtype 4 state.
A ,
B.
name ,
. , 2, A
, . ,
1, . A
, ,
. B . A
, .
: , ,
.
- .1.3.

Promela ,
. ,
Spin , .
Promela: printf, ,
/ ( ) -.
, ,
. ,
, , ,
.
, Promela .
, , :
while (a != b) ->skip
/* , a==b */

skip () , Promela :

17

(a == b)

,
( - b).
,
state.
byte state = 1;
active proctype A(){
byte tmp;
(state==1) -> tmp = state; tmp = tmp+1; state = tmp
}
active proctype B(){
byte tmp;
(state==1) -> tmp = state; tmp = tmp-1; state = tmp
}

(state == 1).
, state, state = tmp,
, state
.
state : 0, 1 2.
state ,
.

Promela ,
. 2. ,

.
Promela , .. . ,
(true),
.
. 2. Promela
( ).

() []
! ++ -* / %
+ << >>
< <= > >=
== !=
&
^
|
&&

,
, 1, 1

,
,

,




18

||
-> :
=


variable = expression

, , .
. Promela
, ( ,
,
. 2). , ,
, variable,
variable .
Promela :
(.. a++, ++)
, .
/
, , ,
(. .1.2, ).
, . / ,
,
. ,
/ ,
, :
qname ? [ack, var, 0]

,
qname , ack,
var 0. ,
, .
C-
(qname ? var == 0)

/* */

(a > b && qname ! 123)

/* */

Promela ,
( / , ,
0 ).
, .
printf.
printf skip.
, .
printf Spin,
.
19

1.3

1.2 , Promela.
atomic,

, .
atomic
, ,
atomic,, ,
, . atomic
. atomic
:
, , ,
atomic.
- atomic ,
.
state.
byte state = 1;
active proctype A(){
atomic {
(state==1) -> state = state+1
}
}
active proctype B(){
atomic {
(state==1) -> state = state-1
}
}

atomic
.
, ,
atomic. , ,
, , , (state
== 1). , , ,
.
state 0, 2, ,
.
tomic
Spin
: atomic ().
, ,
,
,
atomic,
.

20


if
.
a b :
if
:: (a != b) -> option1
:: (a == b) -> option2
fi

if ,
.
(). ,
. (guard) .
,
- . ,
. , ,
. ,
, .
.
#define a 1
#define b 2
chan ch = [1] of { byte };
proctype A(){
ch ! a
}
proctype B(){
ch ! b
}
proctype C(){
if

:: ch ? a -> option1
:: ch ? b -> option2

fi
}
init{
atomic { run A(); run B(); run C() }
}

ch.
C , - a (a
1). ,
b (b ). ,
, .
,
count:
21

byte count;
proctype counter(){
if
:: count = count + 1
:: count = count 1
fi
}

,
, count.

().
,
, ,
:
byte count;
active proctype counter(){
do
:: count = count + 1
:: count = count - 1
:: (count == 0) -> break
od
}

if, do
. , ,
: .
break. break
, , ,
, od. ,
count .
,
count, 0.
,
, .
active proctype counter(){
do
:: (count != 0) ->
if
:: count = count + 1
:: count = count - 1
fi
:: (count == 0) -> break
od
}

else.
else ,
.
:
active proctype counter(){
do
:: (count != 0) ->
if
:: count = count + 1

22

:: count = count - 1
fi
:: else -> break
od
}

else , !(count != 0) ,
(count == 0), .

goto. goto , ,
.
:
proctype Euclid(int x,
do
:: (x > y)
:: (x < y)
:: (x == y)
od;
done: skip
}

y){
-> x = x - y
-> y = y - x
-> goto done

goto done.
.
. skip :
-, ,
.

1.4

, Promela.
, ch
large small . N
128 size 16 :
#define N
128
#define size 16
chan ch
= [size] of { short };
chan large = [size] of { short };
chan small = [size] of { short };
proctype split(){
short data;
do
:: ch ? data ->
if
:: (data >= N) ->
:: (data < N) ->
fi
od
}

large ! data
small ! data

init{
run split()
}

, , .. split
ch, !
23

. ,
, ch :
proctype merge(){
short data;
do
::
if

:: large ? data
:: small ? data

fi;
ch ! data
od
}

init :
init{

ch ! 345; ch ! 12;
ch ! 6777; ch!32; ch ! 0;
run split();
run merge()

. ,
init ch. merge split
. ,
, .
.
.
.
proctype fact(int n; chan p) {
chan child = [1] of { int };
int result;
if

fi

:: (n <= 1) -> p ! 1
:: (n >= 2) -> run fact(n-1, child);
child ? result;
p ! n*result

}
init{
chan child = [1] of { int };
int result;
run fact(7, child);
child ? result;
printf("MSC: result: %d\n", result)
}

fact(n,p) n,
p.

24

2 Promela SPIN
model checking ,
,
.
, ,
, .
:

c (reachability), ,
;
c (safety), , , ,
;
c (liveness), ,
;
c (fairness), ,
.


:
. LTL
EF.
,
( , ).
G.
, (),
.
: ,
(,
, ,
, ,
).
, , :
, . ,

, .
. ,
, CTL AF,
,
LTL GF.
,
, ,
, :
fairness

.
, ,
,

. ,
.
25

. , ,
, ,
(), -
. .

: ,
,
,
.
, ,
,
, ,
. SPIN ,
SPIN :

2.1


o ,
assert;
o , ..
;

o , ,
progress;
o ,
accept.

assert

assert, , .. ,

assert( Promela)

, assert,, assert
. , SPIN
Error: assertion violated.
assert . SPIN
, assert.
, SPIN,
.

2.2

(end)

Promela ,
Spin, ,
. , ,
, ,
() .
,
, .
, .

26

, ,
,
.
,
, , end
#define p
#define v

0
1

chan sema = [0] of { bit };


proctype dijkstra(){
byte count = 1;
endpoint: do
:: (count == 1) ->
sema ! p; count = 0
:: (count == 0) ->
sema ? v; count = 1
od
}
active[3] proctype user(){
if
:: sema ? p;
/* */
sema ! v;
/* */
fi
}

Spin, ( ),
dijkstra
, - .
dijkstra() . ,
. dijkstra
, ,
.
dijkstra ,
v ,
.
.

2.3

(progress)

, ,
progress. ,
, .
SPIN ,
progress, ,
(liveness). ,
, SPIN , ,
. dijkstra,
sema. V
, sema ? p sema ! v:

27

proctype dijkstra()
{
byte count = 1;
endpoint :
do
:: (count == 1) ->
progress: sema ! p; count = 0
:: (count == 0) ->
sema ? v; count = 1
od
}

,
progress,
SPIN ,
.
.

2.4

(accept)

never (. 2.5),
PROMELA .
, accept:
accept[a-zA-Z0-9_]*:


, , accept, acceptance, accepting.
, ,
() , ,
.
,
. ,
, , accept,
.

2.5

never

assert,
proctype. ,
, : " , p ,
, q". ,

.
, ..
( ) .
never . never
, ,
. never ,
.
. ,
. never.
never .
(..
28

, ,
).
never p
:
never {

do

:: !p -> break
:: else

od

never .
, never ,
. never
. p , never
, , .

never. monitor:
active proctype monitor(){
atomic { !p -> assert(false) }
}

monitor
, atomic, .
, (
) , monitor
assert, .. monitor
never. , never
.
, :
, p , - q,
, q .

(LTL): G(p (p U q)) (, ).

. LTL G(p (p U q)).


never.
,
, , ,
.
29

!G(p (p U q)).
, .. ,
p , q , p
, q .
, , q ,
. Promela ,
.
assert
(, assert ).
never .
never { /*
S0:
do
od;
accept:
do

!G (p (p U q))
*/
:: p && !q -> break
:: true
:: p && !q
:: !(p || q) -> break

od
}

( )
never.
never S0, .
true. ,
.
never . ,
S0, .. true . true
, .
do , p ,
q . :
p, q .
. , q ,
, , q.
(.. , , q
) accept.
, , .
, q .
, G (p (p U q)).
.
accept.
accept.
, p , q
. never.
never , ,
,
.

30

, p q, , ,
, , never .
never , ! never
, accept, ..
.
, S0 , (guard)
. .
never true else,
p,
q.
G (p (p U q)).
, never ,
, , assert.
, accept, , accept1,
accepting .., never, accept.

accept_init,

, never
. Spin
, F, G U,
( ),
Promela, &&, || ! (. ).
X LTL
Spin (
:
). , Spin G
[], F <>.
->. LTL
G (p (p U q)) Spin, [](p -> (p U q)).

accept
p

true

accept1
!(p||q)

true

. !G(p (p U q)),
() accept, ,
( true s0) ,
p, , ,
, , q.
,
, Spin ! (, ),
! B!,
. , B! Spin never,
31


, .

32

3 Spin
,
Promela Spin. ,
XSpin.
,
Spin.

3.1


(
, , (Dolev, Klawe, Rodeh) (Peterson) 1982
) [2, 3]. ,
, O(N2), N
.
2Nlog2N+O(N). .
N .
, .
. .
,
(, ).

,


.
, , ,
. ,
. ,
.
,
,
. , ,
.
, , :
maximum ,
neighbourR.
.
,
.
.
, .
: A1 one,
A2 two.
.
.
:
A0. maximum := . one(maximum) .
33

A1. one(q), :
1. q != maximum, neighbourR q
two(neighbourR).
2. , maximum . .
A2. two(q), :
1. neighbourR q, maximum, maximum
neighbourR one(maximum).
2. .
1, 2, 1, 2 .., .
, , ,
,
.
:
, , ,
,
.
( ), Spin.
Promela
p. N .
in,
, out,
.
p , Active true. p
.
,
,
one. neighbourR,
, p
. , neighbourR ,
maximum, , ,
two. p two(neighbourR),
.
, neighbourR = maximum: ,
winer(nr).
Promela :

, , , 10,
.. 10 , ,
, ;

5, .. Promela
- , ;

, , ..
.

34

Promela
1 #define N 5
2 #define I 3
3 #define L 10
4
5 mtype = {one, two, winner};
6 chan q[N] = [L] of {mtype, byte};
8 byte nr_leaders = 0;

/* */
/* ,
*/
/* (>= 2*N) */
/* 3 */
/*
L */
/* , ,
*/

9
10 proctype node (chan in, out; byte mynumber) /* */
11 { bit Active = 1,
/* 1 Active ,
*/
know_winner = 0;
/* know_winner ,
, */
12
byte nr, neighbourR, maximum = mynumber;
/*
byte,
mynumber */
13
14
xr in;
/*
in */
15
xs out;
/*
out */
/* Promela, (
),
( ), . */
16
17
printf(MSC: %d\n, mynumber);
/* */
18
out ! one(mynumber);
/* one
mynumber */
19
end: do
/* end , ,
*/
20
:: in?one(nr)->
/* one ,
nr : */
21
if
22
:: Active ->
/* , : */
23
if
24
:: nr != maximum ->
/* */
25
out ! two(nr);
/* two
*/
26
neighbourR = nr
27
:: else ->
28
/* (..
, 1 )*/
29
assert(nr == N);/* ,
*/
30
know_winner = 1; /* , */
31
out ! winner,nr; /* winner
, */
32
fi
33
:: else ->
/* */
34
out ! one(nr)
/* */
35
fi
36
37
:: in?two(nr) ->
/* two,

35

nr */
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

if
:: Active ->

if
:: neighbourR > nr && neighbourR > maximum -> /*
*/
maximum = neighbourR; /*
*/
out ! one(neighbourR) /* */
:: else ->
Active = 0
/* */
fi
:: else ->
/* */
out ! two(nr)
/* */
fi
:: in ? winner,nr ->
/* ,
, : */
if
:: nr != mynumber ->
/* */
printf(MSC: LOST\n);
:: else ->
/* , ,
*/
printf(MSC: LEADER\n);
nr_leaders++;
/* */
assert(nrleaders == 1) /* , 1*/
fi;
if
:: know_winner
/* , ,
. ,
*/
:: else -> out!winner,nr
/* */
fi;
break
od

61
62
63
64
65 }
66
67 init {
68
byte proc;
69
atomic {
70
71
72
73
74
75
76
77
78
79 }

/* ,

*/

/* */
/* N
node*/

proc = 1;
do
:: proc <= N ->
run node (q[proc-1], q[proc%N], (N+I-proc)%N+1);
/* 2
2 in out */
proc++
:: proc > N ->
break
od


5 [28 -> 34].
,
[30 -> 38; 35 -> 54; 40 -> 49; 42 -> 66].
36

, 4- (3-) [30 -> 38],


5- ( ) [28 -> 34]. ..
one (4-),
two [47 -> 65].

[48 -> 76; 61 > 80; 60 -> 105; 81 -> 82], ..

.

two 1
[81 -> 82],

(5, 28 -> 34)
(4, ..
) .
,
=>
=>

[104 ->
106].
3,
two 5 [47 -> 65],

(4)
(3)
. ,
=>
3

[104 -> 106] ->
[113 -> 115].

2 [48 -> 76],
1 [61 -> 80], ,
, 5 [60 > 105].
,
one 5
[134 -> 135]
4, .
,
, [142 -> 143].
Simulation Output Spin.
,
Promela .
log ( ) :
37

.starting simulation.
spin -X -p -v -g -l -s -r -n1 -j0 pan_in
.at end of run.

, Xspin,
.
Cancel Simulation Output.

, Run Set Verification
Parameters. leader ,
Verification Output errors: 0. .
, 22 assert(false).
:
:: Active -> assert(false);

. SPIN ,
, Run Guided Simulation (
).

Setup Guided Simulation,


XSpin , ,
. XSpin Simulation style Guided Simulation Random
Simulation.

Run
Guided
Simulation, Run
Simulation Output, XSpin
,
.

,
assert,

.

,
Cancel Simulation Output Panel. assert (..
22 :: Active ->).
LTL
SPIN,
LTL . LTL (LTL
Property Manager Run):
38

<>q
[]q
w U q

Fq
Gq
w U q

q
q
w q

q .
XSpin .ltl, ,
Promela, .
leader.ltl.

1. , 1, ..
.
39

Formula:
[] noMore

, , noMore,
. ,
: Property holds for All
Executions, - No Executions. ,
Property holds for All Executions.
, noMore, Symbol definition box.
#define noMore (nr_leaders <= 1)

Generate. Never Claim LTL


never, .
/*
* Formula As Typed: [] notMore
* The Never Claim Below Corresponds
* To The Negated Formula !([] notMore)
* (formalizing violations of the original)
*/
never {
/* !([] notMore) */
T0_init:
if
:: (! ((notMore))) -> goto accept_all
:: (1) -> goto T0_init
fi;
accept_all:
skip
}

, ,
:

40

Full statespace search for:


never claim
+
assertion violations + (if within scope of claim)
acceptance
cycles + (fairness disabled)
invalid end states
- (disabled by never claim)
State-vector 200 byte, depth reached 205, errors: 0
97 states, stored
1 states, matched
98 transitions (= stored+matched)
12 atomic steps
hash conflicts: 0 (resolved)
unreached in proctype node
line 53, "pan.___", state 28, "out!two,nr"
(1 of 49 states)
unreached in proctype :init:
(0 of 11 states)
unreached in proctype :never:
line 104, "pan.___", state 8, "-end-"
(1 of 8 states)

SPIN ( ,
, ..),
.
, , 1.
assert (
):
57 assert(nrleaders == 1)

, ,
Spin , .
2. , , , LTL
<>

[]

oneLeader,

:
#define oneLeader

(nr_leaders == 1).

, - ,
1, .. . .
3. , (..
).
assert(nr == N)
, , (. 29 ), nr
, , N .
.
, .
: election_started = 0 first_message = 1.
,
Active = 0
41

( 18- ). , ,
, election_started = 1( 19 20- ):
:: atomic {
(!election_started && !Active) ->
/* msg */
/* */
election_started = 1;
out ! one(mynumber);
first_message = 0;
Active = 1}
}

, , first_message=1,
, first_message=0 (
20 21 37 38 ):
if
:: (first_message && !Active) ->
if
:: Active = 1; /* */
out ! one(mynumber)
:: skip
/* */
fi
:: else
fi;
first_message = 0;

,
:
pan: assertion violated (nr==5) (at depth 45)
pan: wrote pan_in.trail
(Spin Version 4.2.7 -- 23 June 2006)
Warning: Search not completed
+ Partial Order Reduction
Full statespace search for:
never claim
- (not selected)
assertion violations +
cycle checks
- (disabled by -DSAFETY)
invalid end states
- (disabled by -E flag)
State-vector 196 byte, depth reached 45, errors: 1
33 states, stored
0 states, matched
33 transitions (= stored+matched)
13 atomic steps
hash conflicts: 0 (resolved)

, ,
assert(nr == N) (assertion violated). ?
,
, .. ,
.

42

, ,
.

3.2

, ,


, :
, , .
, .
( , , ). .
, , ,
, .
, ?
, Spin
: ,
. Spin
<--->,
.
.
, Promela
river.
, ,
(f, w, g, c). , 0,
, 1 ,
.
, .
,
. , , , ,
, . , ,
,
.
, :
(f==1) && (f == w) && (f ==g) && (f == c)

, 1 (.. , ,
, ).
.
Promela:
/* (f), (w), (g) (c) */
/* , LTL */
bool all_right_side, g_and_w, g_and_c;
active proctype river()
{
/* , , */
bit
f = 0,
/* */
w = 0,
/* */
g = 0,
/* */
c = 0;
/* */

43

all_right_side
g_and_w
g_and_c

= false;
= false;
= false;

printf("MSC: f %c w %c g %c c %c \n",

f, w, g, c);

do
:: (f==1) && (f == w) && (f ==g) && (f == c) ->
all_right_side = true; /* */
break;
/* */
:: else ->
/* */
if
:: (f == w) ->
/* */
f = 1 - f; /* */
w = 1 - w;
:: (f == c) ->
/* */
f = 1- f; /* */
c = 1- c;
/* */
:: (f == g) ->
f = 1-f; /* */
g = 1-g;
:: (true) ->
/* */
f = 1 - f; /* */
fi;
printf("MSC: f %c w %c g %c c %c \n",

od;
}

f, w, g, c);

if
/* */
/* ? */
::(f != g && g == c ) ->
g_and_c = true;
/* ? */
::(f != g && g == w ) ->
g_and_w = true;
::else ->
skip
fi
printf("MSC: OK!\n")

Spin
, ,
, , "" .
,
. .
, : ,
0, 1, .

44

.
!

.
!

Spin .
: ,
(, ) .
LTL :
<>

fin && [] ( wg

&& gc )

(all_right_side, g_and_w, g_and_c


, ):
#define fin
#define wg
#define gc

(all_right_side == true)
(g_and_w
== false)
(g_and_c
== false)

, ( No Executions
Property holds for LTL ),
: "- ,
, , ".
Spin , ,
river, .
State-vector 20 byte, depth reached 73, errors: 1
56 states, stored (57 visited)
8 states, matched
65 transitions (= visited+matched)
0 atomic steps
hash conflicts: 0 (resolved)

Spin (Run guided simulation):

45


:
1.

f = 0 w = 0 g = 0 c = 0

2. ,
,
f = 1 w = 0 g = 1 c = 0

3. ,
f = 0 w = 0 g = 1 c = 0

4.

f = 1 w = 1 g = 1 c = 0

5. ,
f = 0 w = 1 g = 0 c = 0

6. , ,
f = 1 w = 1 g = 0 c = 1

7. .
, Spin ,
,
.

46

3.3



A B, ,
, Kerberos. , 1978 (Needham)
(Schroeder), .
. , ,
( ), .
, , ,
. ,
, , ,
.
- ,
.
, ,
.
. , , nonce
,
. A ,
. .
.
,
,
. ,
. -
:
1. 1,
nonceA.
B.
2. , 1, ,

. ,
2, : nonceA nonceB.
3. , 2, ,
nonceA, , ,
1. ,
, nonceB
3. , 3, , -, , , .
20 , 1995 (Lowe)
CSP FDR [4].
(intruder),
.
:
1. , ,
2. ; ,
, , , ,
47

3. ,
4. .
,
-.
Promela
- Promela ,
, Spin.
Alice ( ), Bob ( ) Intruder
(), .
, ,
.
-: fakedA fakedB (), intercepted ().
intercepted , Alice Bob ,
. fakedA, Alice
, ( Bob). Intruder
intercepted, fakedA
fakedB , .
msg.
/* faked , */
chan fakedA = [0] of {mtype, mesCrypt};
chan fakedB = [0] of {mtype, mesCrypt};
/* intercepted , */
chan intercepted = [0] of {mtype, mesCrypt};

,
:
typedef mesCrypt {
/* */
mtype s,
/* */
r,
/* */
nummsg,
/* */
key,
/* , */
/* */
d1,
/* nonce */
d2
};

, ,
, .
mtype

{msg,
alice, bob, intruder,
pkA, pkB, pkI,
nonceA, nonceB, nonceI,
ok, err};

/*
/*
/*
/*

*/
*/
*/
*/


:
48

Alice,

Intruder Alice Bob,

Intruder ,

, Intruder (
) ,

Alice Bob ,
( ),
.

, Alice Bob data


mesCrypt. ,
. , Bob
if

:: (data.r == bob) &&


/* Bob ? */
(data.key == pkB) &&
/* */
(data.s == data.d1) &&
/* ? */
(data.nummsg == 1)->
/* ? */
partnerB = data.s;
pnonce = data.d2;
:: else -> goto stopB;

fi;

, , (
), , .
, Bob . Bob ,

. ,
, . ,
Alice
Bob, . , , :
. , ,
,
, , , .
Intruder mesCrypt data
, fake

. ,
: , (data.key
== pkI),
( nonceA nonceB). Intruder
, .
active proctype Intruder() {
/* */
end: do

/* ,

intercepted */
:: intercepted ? msg(data) ->
if
/* data */
:: (data.key == pkI) -> /* ,

49

true;

*/
if
:: (data.d1 == nonceA || data.d2 == nonceA) -> knowNA =
/* nonceA, , knowNA=1 */
/* nonceB */
/* */
fi;
:: else -> skip;
/* : */
fi;
/* fake */
if
/* */
:: fake.s = alice ->
/* Alice */
fake.r = bob; fake.key = pkB;
/* Bob */
/* Bob */
fi;
/*
d1
*/
if
:: fake.d1 = alice;
:: fake.d1 = bob;
:: fake.d1 = intruder;
:: fake.d1 = nonceI;
:: (knowNA) -> fake.d1 = nonceA;
:: (knowNB) -> fake.d1 = nonceB;
fi;
/* d2 */
/* */
/*
*/
if
:: (data.key != pkI) ->
fake.key = data.key;
fake.d1 = data.d1;
fake.d2 = data.d2;
:: else -> skip;
fi;
/* */
/* */
/* ,
, Alice, Bob */
if
:: (data.r == alice) ->
fakedA ! msg(data); /* Alice*/
:: (data.r == bob) ->
fakedB ! msg(data); /* Bob */
/* */
/* */
fi;

50

od;
}

- Promela
/* - */
/* : Alice, Bob, Intruder,

*/
mtype = {msg, alice, bob, intruder, pkA, pkB, pkI,
nonceA, nonceB, nonceI, ok, err};
/*
( , , , ( ID) )
*/
/* */
typedef mesCrypt {
mtype s, r, nummsg,
/* */
/* */
key, d1, d2;
};
/* faked , */
chan fakedA = [0] of {mtype, mesCrypt};
chan fakedB = [0] of {mtype, mesCrypt};
/* intercepted , */
chan intercepted = [0] of {mtype, mesCrypt};
/* , LTL */
mtype partnerA, partnerB;
mtype statusA, statusB;
/* */
bool knowNA, knowNB;
/* */
active proctype Alice() {
mtype pkey, pnonce;
mesCrypt data;
statusA = err;
if /* */
:: partnerA = bob; pkey = pkB;
:: partnerA = intruder; pkey = pkI;
fi;
/* 1 */
d_step {
data.s = alice;
data.r = partnerA;
data.nummsg = 1;
data.key = pkey;
data.d1 = alice;
data.d2 = nonceA;
}
intercepted ! msg(data);
/* 2 */
fakedA ? msg(data);

51

end_errA:
/* ,
,
. */
if
:: (data.key == pkA) && (data.d1 == nonceA) &&
(data.s == partnerA) && (data.r == alice) &&
(data.nummsg == 2)->
pnonce = data.d2;
:: else -> goto stopA;
fi;
/* 3 */
d_step {
data.s = alice;
data.r = partnerA;
data.nummsg = 3;
data.key = pkey;
data.d1 = pnonce;
data.d2 = 0;
}
intercepted ! msg(data);
statusA = ok;
stopA:
printf("MSC: Process A finished \n");
} /* proctype Alice() */
/* */
active proctype Bob() {
mtype pkey, pnonce, receiver, partner;
mesCrypt data;
statusB = err;
/* msg1, */
fakedB ? msg(data);
/* ,
- , */
end_errB1:
if
:: (data.r == bob) && (data.key == pkB) && (data.s == data.d1) &&
(data.nummsg == 1)->
partnerB = data.s;
pnonce = data.d2;
:: else -> goto stopB;
fi;
/* */
if
:: (partnerB == alice) -> pkey = pkA;
:: (partnerB == intruder) -> pkey = pkI;
:: else -> goto stopB;
fi;
/* 2 */
d_step {
data.s = bob;
data.r = partnerB;
data.nummsg = 2;

52

data.key = pkey;
data.d1 = pnonce;
data.d2 = nonceB;
}
intercepted ! msg(data);
/* 3, ,
ok */
fakedB ? msg(data);
end_errB2:
if
:: (data.r == bob) && (data.s == partnerB) && (data.key == pkB) &&
(data.d1 == nonceB) && (data.nummsg == 3)->
statusB = ok;
:: else -> goto stopB;
fi;
stopB:
printf("MSC: Process B finished \n");
}
/* */
active proctype Intruder() {
mesCrypt data, fake;
knowNA = false;
knowNB = false;
end: do
:: intercepted ? msg(data) ->
if
:: (data.key == pkI) ->
if
:: (data.d1 == nonceA || data.d2 == nonceA) -> knowNA = true;
:: (data.d1 == nonceB || data.d2 == nonceB) -> knowNB = true;
fi;
:: else -> skip;
fi;
/* */
if
:: fake.s = alice ->
fake.r = bob; fake.key = pkB;
:: fake.s = bob;
fake.r = alice; fake.key = pkA;
:: fake.s = intruder;
if
:: fake.r = bob; fake.key = pkB;
:: fake.r = alice; fake.key = pkA;
fi;
fi;
/* */
if
:: fake.d1 = alice;
:: fake.d1 = bob;
:: fake.d1 = intruder;
:: fake.d1 = nonceI;
:: (knowNA) -> fake.d1 = nonceA;
:: (knowNB) -> fake.d1 = nonceB;
fi;

53

if
:: fake.d2 = alice;
:: fake.d2 = bob;
:: fake.d2 = intruder;
:: fake.d1 = nonceI;
:: (knowNA) -> fake.d2 = nonceA;
:: (knowNB) -> fake.d2 = nonceB;
fi;
/*
*/
if
:: (data.key != pkI) ->
fake.key = data.key;
fake.d1 = data.d1;
fake.d2 = data.d2;
:: else -> skip;
fi;
/* */
if
:: fake.nummsg = 1;
:: fake.nummsg = 2;
:: fake.nummsg = 3;
fi;

od;

if
:: (data.r ==
fakedA !
:: (data.r ==
fakedB !
:: (fake.r ==
fakedA !
:: (fake.r ==
fakedB !
fi;

alice) ->
msg(data);
bob) ->
msg(data);
alice)
msg(fake);
bob)
msg(fake);

/* */
/* */
/* */
/* */


,
, A ,
. LTL : "
, - ,
, , ,
nonceA nonceB"
<> ( agentB_finished && bobtrustsA && intrknowNA && intrknowNB )

( statusB, partnerB, knowNA,


knowNB )
#define
#define
#define
#define

agentB_finished (statusB == ok)


bobtrustsA
(partnerB == alice)
intrknowNA
(knowNA == true)
intrknowNB
(knowNB == true)

No Executions , Spin. Spin


, 1995 .
54

1. Alice, Intruder , 1
,
Intruder [16 -> 17]. Intruder nonceA.
2. Intruder 1 Bob,
Alice, ,
Bob [39-40].
3. Bob Intruder
2, , Alice.
,
Intruder,
Alice [54-55].
nonceB
Bob,
.

4.
2 Alice [73-74].

Bob,

,

.
5. Alice,

Intruder,
2,
nonceB, Intruder 3,
nonceB,
Intruder
[82-83].
6. Intruder
3, nonceB, 3
Bob.
Bob, [105-106].

3.4


, ,
, ,
.
,
, , .
, . ,
,
. , , ,
, ,
, .. ,
.

55

,
, ,
.
, ,
,
, .
, . ,
, ,
(, ),
.
. :
S0. . ,
S1.
S1. , .
, . , S1
. , S2.
S2. . ,
. ,
S3 ,
.
S3. . , , ,
S4.
S4.
( S0).
:
F0. . ,
( ). , F1,
, F2.
F1. ( F0).
F2. ( F0).
, .. -
?

SPIN.
Promela
N . 2N : N
N .
cur_state.
() -
. 2N .
chan l_fork[N] = [0] of {bit}; /* */
chan r_fork[N] = [0] of {bit}; /* */

,
. -
56

:
, ;
, .

:
#define msgtype 1

/* */


.
proctype phil (chan left, right; byte mn)
{
byte cur_state = 0;
printf("MSC: phil # %d \n", mn);
do
::

::

(cur_state == 1)
left ! msgtype
cur_state = 2;

->
->

(cur_state == 2) ->
right ! msgtype;
cur_state = 3;

::(cur_state == 3) ->
cur_state = 4;
:: (cur_state == 4) ->
right ! msgtype ->
cur_state = 5;
:: (cur_state == 5) ->
left ! msgtype ->
cur_state = 0;
::(cur_state == 0) ->
cur_state = 1;
}

/* */

/* */
/* */
/* */
/* */

/* */
/* */
/* */

od

- cur_state_fork.
-
( , ).
( ), ,
. ,
.
proctype fork(chan left_phil, right_phil)
{
byte cur_state_fork = 0;
/* F0. */
end:

do
::( cur_state_fork == 0) ->
if
::right_phil ? msgtype ->
cur_state_fork = 2;
::left_phil ? msgtype ->
cur_state_fork = 1;

/* */
/* */
/* F2. */
/* */
/* F1. */

57

::skip;
fi
::( cur_state_fork == 1) ->
left_phil ? msgtype ->
cur_state_fork = 0;
::( cur_state_fork == 2) ->
right_phil ? msgtype ->
cur_state_fork = 0;
od

/* */
/* F0. */
/* */
/* F0. */

- - init.
. N - 1 N
( ), N ( )
0 N-1.

- proc.

l_fork proc
proc-1.

r_fork proc
proc.

, , proc.


: r_fork proc
l_fork proc .
1.
init {
byte

proc;

proc = 1;
get_in_stuck = 0;
do
:: proc <= N

->

/* - proc (proc-1) proc */


run phil (l_fork[proc-1], r_fork[proc%N], proc);
/* - proc proc
proc */
run fork (r_fork[proc%N], l_fork[proc%N], proc);
proc++;

:: proc > N ->


break
od


, ,
- ,
. (system deadlock)
58

Spin
. , sic
Verification Options Invalid Endstates.
, :
Full statespace search for:
never claim
assertion violations
cycle checks
invalid end states

- (not selected)
- (disabled by -A flag)
- (disabled by -DSAFETY)
+

, , ,
, ,
.

3.5

,

1960.
(),
. .
.
, , :
, - .
59

Promela
Promela,
.
N,
0 N-1. N: up[i]
, i-, down[i] ,
i-. NOTHING , .
Tup Tdown.

: up[0]=NOTHING, up[1]=2,
down[0]=2, down[1]=NOTHING, down[2]=2.
:

up[2]=0,

a) i, (
up[i]==NOTHING), (up[down[i]] = NOTHING);

b) (down[i]=NOTHING),
j, (up[j]==NOTHING),
i (up[j]=i; down[i] = j). j i (ji),.
, ..
up[] Tup[], down[] Tdown[].
, ,
() .
#define N 3
#define NOTHING 255
#define N-1 2
/* */
byte up
[N];
byte down[N];
/* */
byte Tup
[N];
byte Tdown[N];
byte i, j, k;
bool equal = false,
findi = true,
findj = false,

/* */

/* i */
/* i */
/* i */
/* i */
/* */
/* i */
/* j, i */

60

checkconf = false;

/* */

active proctype cube_world(){


/* */
up[0] = NOTHING;
up[1] = 2;
up[2] = 0;
down[0] = 2;
down[1] = NOTHING;
down[2] = 1;
/* */
Tup[0] = 1;
Tup[1] = 2;
Tup[2] = NOTHING;
Tdown[0] = NOTHING;
Tdown[1] = 0;
Tdown[2] = 1;
i = 0;
j = 0;
/* */
do
:: findi ->
/* i */
if :: (up[i] == NOTHING) -> findj = true; findi = false;
if :: ( down[i] != NOTHING ) ->
up[ down[i] ] = NOTHING;
/* i- */
:: else -> skip;
fi;
:: (i < N-1) -> i ++
:: (i > 0)
-> i -fi
:: findj && ( down[i] != NOTHING) -> /* */
down[i] = NOTHING;
/* i- */
printf("MSC: [%d] to table \n", i);
findj = false;
checkconf = true;
:: findj -> /* j i- j- */
if :: ( i != j ) && ( up[j] == NOTHING ) ->
up[j] = i; down[i] = j;
/* i- j- */
printf("MSC: [%d] to [%d] \n", i, j);
findj = false;
checkconf = true;
:: (j < N-1) -> j ++
:: (j > 0)
-> j -fi
:: checkconf -> /* , */
equal = true; k = 0;
do :: ( k < N ) ->
equal=equal && (up[k]==Tup[k]) && (down[k]==Tdown[k]);
k++
:: ( !equal ) -> break
:: ( k == N ) -> break
od;
if :: (equal) -> break /* */
:: else -> checkconf = false; findi = true
fi
od;

61

printf("MSC: movement finished \n")

Spin
, (
) . Spin:
, LTL-: FG (equal == true), ..
,
.
Spin , .
, Spin
.
, ,
.

62

1.
Run Set Simulation Parameters. Simulation
Options.

Display Mode ,
.

MSC Panel . ,
.
o Step Number Labels .
o Source Text Labels .Ghj

Time Sequence Panel. ,


.
o Interleaved Steps
, , ,
.
o One Window per Process ,
Promela.
, .
o One Trace per Process .
,
.

Data Values Panel .


o Track Buffered Channels .
o Track Global Variables .
o Track Local Variables .
o Display vars marked show in MSC
MSC .
63

show (,
show byte cnt byte cnt).

Execution Bar Panel


.

Simulation Style . 3
:
o Random
.

o Guided .
,
.
o Steps Skipped , .
o Interactive
.

64

2.
Set Verification Parameters Run. sic
Verification Options.

Correctness Properties ,
:

Safety
o Assertions ,
assert (. 2.1);
o Invalid Endstates , ..
(. 2.2);

Liveness
o Non-Progress Cycles ,
, progress (. 2.3);

o Acceptance Cycles ,
accept (. 2.4).

Apply Never Claim never,


(. 2.5).

Report Unreachable Code .

Check xr/xs Assertions (channel assertions) , ,


xr,
. , , xs
, .

65


1. Holzmann G. "Spin Model Checker. The Primer and Reference Manual" Addison Wesley,
2003, 608 .
2. Peterson G. "An O(n log n) Unidirectional Algorithmfor the Circular Extrema Problem"
ACM Transactions on Programming Languages and Systems (TOPLAS), v. 4 , i. 4, p. 758
762, 1982
3. Dolev D., Klawe M., Rodeh M. "An O(n log n) Unidirectional Distributed Algorithm for
Extrema Finding in a Circle" Journal of Algorithms, 3, . 245-260, 1982
4. Lowe G. " Breaking and Fixing the Needham-Schroeder Public-Key Protocol using FDR"
Lecture Notes In Computer Science; v. 1055, Proceedings of the Second International
Workshop on Tools and Algorithms for Construction and Analysis of Systems table of
contents, . 147 166, 1996
5. ... Model checking.
. // -, 2009, 520 .

66