+ All Categories
Home > Documents > Lecture 3 (on Promela and SPIN)

Lecture 3 (on Promela and SPIN)

Date post: 09-Feb-2022
Category:
Upload: others
View: 4 times
Download: 0 times
Share this document with a friend
42
Lecture 3 Lecture 3 SPIN and Promela 1
Transcript
Page 1: Lecture 3 (on Promela and SPIN)

Lecture 3Lecture 3SPIN and Promela

1

Page 2: Lecture 3 (on Promela and SPIN)

What is SPIN(Simple Promela Interpreter)

A tool for analyzing models of reactive systemsM d l d ib d i P lModels described in Promela• Language with concurrent processes,

C i i i h l• Communication via channels,Analysis by• Simulation• Model checking• Several optimizations implemented• ”most efficient tool for explicit-state model checking”

2

Page 3: Lecture 3 (on Promela and SPIN)

Material About SPIN

SPIN Home page http://spinroot.com/spin/

C t i l f t i l d t t i lContains manuals, reference material, and tutorialBooks about SPIN

G J H l SPIN MODEL CHECKER P i d• G.J. Holzmann SPIN MODEL CHECKER Primer and Reference Manual, G J Hol mann Design and Validation of Comp te• G.J. Holzmann Design and Validation of Computer Protocols,, Prentice Hall 1991, older book, available on the Interneton the Internet

3

Page 4: Lecture 3 (on Promela and SPIN)

Elements of Promela

• Language for defining finite-state transition systemsD t t ith i l d fi d fi it d i• Data types with precisely defined finite domains– Bits, integers, arrays, messages

• Processes which can be dynamically created• Processes, which can be dynamically created• Communication via global variables or communication

channelschannels• Simple control constructs

4

Page 5: Lecture 3 (on Promela and SPIN)

Typical Structure of Promela Model

Promela model consists oft d l ti

mtype = {msg, ack};

chan toS = ...• type declarations• channel declarations

i bl d l i

chan toR = ...

bool flag;

• variable declarations• process declarations

proctype Sender () {

...• init process }

proctype Receiver () {

...

}

init {

...

}

5

}

Page 6: Lecture 3 (on Promela and SPIN)

Basic Variables and Types

Basic types bit [0 .. 1]bool [0 .. 1]byte [0 .. 255]short [-215 .. 215 -1]int [-231 .. 231 -1]

Array declarationArray access

byte anarray[24];

anarray[v] = anarray[3]; y

Records type definition

y y

typedef Msg{

byte a[3], b;

Record declaration

y [ ], ;

chan p

}

Msg astructRecord access

Enumeration type f messages

Msg astruct

astruct.a[1]

mtype = {ack, nak, err, next}

6

Enumeration type f. messages mtype = {ack, nak, err, next}

Page 7: Lecture 3 (on Promela and SPIN)

Expressions

Operators + - * / % ^

> >= < <= == !=

! && ||

& | -

>> << ++ --

Conditional expression

(v >= 0 -> v : -v)expression

Operations on len(qid)Operations on channel identifers

(q )

empty(qid) nempty(qid)

full(qid) nfull(qid)

7

Page 8: Lecture 3 (on Promela and SPIN)

Basic Statements

Expressions (y == false || x > 9)

Assignments y = 34 % 3

anarray[0] = anarray[3] * anarray[(v+2)/4]

No-Op

Goto

skip

goto labelGoto

Print (only in simulation)

g

printf

simulation)

• All basic statements are either executable (enabled) or blocked(disabled) (of course, depending on values of variables, etc.)( ) ( , p g , )

• Expressions are also statements– Blocked if evaluated to 0, otherwise executable

hi i / b d d8

– In this way, expressions/statements can be used as guards

Page 9: Lecture 3 (on Promela and SPIN)

Compound Statements

Sequential composition

test == 1 ; state = state + 1

test == 1 -> state = state + 1 equivalentcomposition

Selectionif

:: (a == b) -> state = state + 1

:: (a != b) -> state = state – 1:: (a != b) -> state = state – 1

fi

if

:: (a == b) -> state = state + 1

:: else -> state = state – 1

fi

Selection can be nonderministic

if

:: input ? offhook

:: (a == b) -> b = 3 ; goto onhook:: (a == b) > b = 3 ; goto onhook

:: output ! wakeup

:: b = 3 /*any statement can be guard*/

fi

9

Page 10: Lecture 3 (on Promela and SPIN)

Compound Statements (ctd.)

Repetition do

:: (m > n) -> m = m - n

:: (m < n) -> n = n – m

:: (m == n) -> break

od ;

printf (”GCD = %d\n”, m)

10

Page 11: Lecture 3 (on Promela and SPIN)

Processes and process typesName Local variable

proctype Sender(chan in; chan out) {

bit sndB, rcvB; formal parameters

declarations do

:: out ! data(sndB) ->

in ? ack(rcvB);

if

:: sndB == rcvB –> sndB = 1-sndB

:: else -> skipp

fi

od

}}

Processes defined by proctype definitionsA process type may be instantiated several times p yp yEach process has its local state (pc, local variables)Processes execute concurrently, by interleaving

11

Page 12: Lecture 3 (on Promela and SPIN)

Process instantiationsProcesses are created by run

statement/expressionproctype Foo(byte x) {

...

run returns process id

Processes execute their first

}

init {Processes execute their first

statement some time after creation

int pid = run Foo(2);

run Foo(27)

}

Processes can be statically created at initialization time

}

active[3] proctype Bar(){

...created at initialization time (no formal parameters allowed)

}

12

Page 13: Lecture 3 (on Promela and SPIN)

Communication Channels

Channels used for passing messages• Asynchronous (buffered default is FIFO)• Asynchronous (buffered, default is FIFO)• Synchronously (rendez-vous)

chan qid = [4] of {mtype, int, byte}chan qid [4] of {mtype, int, byte}

chan synch[3] = [0] of {mtype, int}

name capacity types of messages

qid ! var1, const, var

qid ! err(const, var)

Sending

assigned

matched

qid ? err(const, var)

qid ? [err , const, var]

Receiving

Non-modifying receive

assigned

qid !! err(const, var)

qid ?? err(const, var)

Non modifying receive

Sorted send/receive(inserts lexicographically

13

(inserts lexicographically,receives any element)

Page 14: Lecture 3 (on Promela and SPIN)

Communication Channels (ctd.)

Declaring synchronous (rendez-vous) channel w. capacity 0

chan synch[3] = [0] of {mtype, int}

14

Page 15: Lecture 3 (on Promela and SPIN)

Peterson-Fischer Mutual Exclusion#define true 1

#define false 0

#d fi 1 f l

proctype P2() {

m1: y2 = true;

2 1#define turn1 false

#define turn2 true

bool y1, y2, t;

m2: t = turn1;

m3: (y1 == false || t == turn2) ;

m4: /* critical section */

atomic{ y2 = false ; goto m1 }bool y1, y2, t;

byte mutex = 0;

proctype P1() {

atomic{ y2 = false ; goto m1 }

}

l1: y1 = true;

l2: t = turn2;

l3: (y2 == false || t == turn1) ;

l4 /* iti l ti */

init {

atomic { run P1() ; run P2() }

}l4: /* critical section */

atomic{ y1 = false ; goto l1 }

}

}

15

Page 16: Lecture 3 (on Promela and SPIN)

Peterson-Fischer Mutual Exclusion#define true 1

#define false 0

#d fi 1 f l

proctype P2() {

m1: y2 = true;

2 1#define turn1 false

#define turn2 true

bool y1, y2, t;

m2: t = turn1;

m3: (y1 == false || t == turn2) ;

mutex++ ;

assert (mutex <= 1) ;bool y1, y2, t;

byte mutex = 0;

proctype P1() {

assert (mutex <= 1) ;

m4: /* critical section */

mutex-- ;

atomic{ y2 = false ; goto m1 }

l1: y1 = true;

l2: t = turn2;

l3: (y2 == false || t == turn1) ;

t

}

mutex++ ;

assert (mutex <= 1) ;

l4: /* critical section */

mutex -- ;

init {

atomic { run P1() ; run P2() }

}mutex ;

atomic{ y1 = false ; goto l1 }

}

}

16

Page 17: Lecture 3 (on Promela and SPIN)

Problem with Atomicity

byte state = 1;Only basic statements are atomic

proctype A() {

state == 1 -> state++

}

Q: What is the final value of state ?

proctype B() {

state == 1 -> state--

}

init {{

run A() ; run B()

}

17

Page 18: Lecture 3 (on Promela and SPIN)

Solution: atomic-construct

byte state = 1;A process whose control is inside

{ } proctype A() {

atomic {

state == 1 -> state++

atomic{ }

executes without being interrupted by other processes }

}

processes

NOTE: Make sure that such a sequence cannot be blocked

proctype B() {

atomic {

state == 1 -> state--

sequence cannot be blocked inside (after the first statement).

}

}In that case, Promela will

suspend the process, and you get unintended

init {

atomic {run A() ; run B()}

}

y gsemantics.

18

}

Page 19: Lecture 3 (on Promela and SPIN)

Other use of atomic{ }

atomic {

cnt = 0 ;

d

To group complex manipulation into i l t iti do

:: (cnt < Max) -> z[cnt] = 3; cnt++

:: (cnt >= Max) -> break

od

single transition

od

}

d_step {If the manipulation is d d cnt = 0 ;

do

:: (cnt < Max) -> z[cnt] = 3; cnt++

( t M ) b k

deterministic and always exits at the end d step { :: (cnt >= Max) -> break

od

}

d_step {

is more efficient

19

Page 20: Lecture 3 (on Promela and SPIN)

Else and Timeout

do

:: (m > n) -> m = m - n

else is enabled if no other statement in the same

i bl d :: (m < n) -> n = n – m

:: else -> break

od ;

process is enabled

printf (”GCD = %d\n”, m)

dotimeout is enabled if no other h :: input ? offhook

:: input ? ringing

:: timeout -> output ! wakeup

statement in the entire Promela model is enabled

p p

Od

doskip is best to use if we want t b t l th

:: input ? offhook

:: input ? ringing

:: skip -> output ! wakeup

to be sure to analyze the effect of possibly premature timeout.

20

:: skip > output ! wakeup

od

Page 21: Lecture 3 (on Promela and SPIN)

Useful Macros

#define IF if ::

#define FI :: else fi

IF without else branch

IF b -> x++ FIAllows to write

#define FOR(i,l,h) i = l ; do :: i < h ->

#define ROF(i,l,h) ;i++ :: i >= h -> break od

FOR loop

FOR(i,0,N) run proc(i) ROF(i,0,N)Allows to write

i = 0 ;

do

:: i < N -> run proc(i)

which means

p ( )

:: i >= N -> break

od

21

Page 22: Lecture 3 (on Promela and SPIN)

Message Transmission Protocolmtype = { m0, m1, ack} proctype Receiver{

Rec0: do

:: StoR?any -> skip /* loss */

proctype Sender{

Send0: do

:: StoR?any > skip / loss /

:: StoR?m0 -> RtoS!ack;

goto Rec1

od

Rec1: doSend0: do

:: skip -> /* timeout */

StoR!m0

:: RtoS?ack -> /* rec ack */

SoR!m1;

Rec1: do

:: StoR?any -> skip /* loss */

:: StoR?m1 -> RtoS!ack;

goto Rec0

odSoR!m1;

goto Send1

od;

Send1: do

ki /* ti t */

od

}

init {

h St R [1] f { t }:: skip -> /* timeout */

StoR!m1

:: RtoS?ack -> /* rec ack */

StoR!m0;

d0

chan StoR = [1] of { mtype };

chan RtoS = [1] of { mtype };

atomic {

StoR!m0; /* start */

dgoto Send0

od

}

run Sender;

run Receiver

}

}

22

Page 23: Lecture 3 (on Promela and SPIN)

Alternating Bit Protocol (version 1)mtype = { msg, ack };

chan s r = [2] of {mtype , byte, bit};

active proctype Receiver() {

byte recd ;

bit rbit, seqno = 0;chan s_r [2] of {mtype , byte, bit};

chan r_s = [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

bit rbit, seqno 0;

do

:: s_r ? msg (recd, seqno) ->

r_s ! ack(seqno);

ifbyte data = 0;

bit sbit, seqno = 0;

do

:: s_r ! msg(data, sbit) ->

r s ? ack(seqno);

if

:: seqno == rbit ->

rbit = 1 – rbit

:: else

fir_s ? ack(seqno);

if

:: seqno == sbit ->

sbit = 1 – sbit;

d t

fi

od

}

data++

:: else

fi

od

}}

23

Page 24: Lecture 3 (on Promela and SPIN)

Alternating Bit Protocol (version 1 altern)mtype = { msg, ack };

chan s r = [2] of {mtype , byte, bit};

proctype Receiver() {

byte recd ;

bit rbit, seqno = 0;chan s_r [2] of {mtype , byte, bit};

chan r_s = [2] of {mtype , bit };

proctype Sender() {

byte data = 0;

bit rbit, seqno 0;

do

:: s_r ? msg (recd, seqno) ->

r_s ! ack(seqno);

ifbyte data = 0;

bit sbit, seqno = 0;

do

:: s_r ! msg(data, sbit) ->

r s ? ack(seqno);

if

:: seqno == rbit ->

rbit = 1 – rbit

:: else

fir_s ? ack(seqno);

if

:: seqno == sbit ->

sbit = 1 – sbit;

d t

fi

od

}

i it {data++

:: else

fi

od

}

init {

atomic {

run Sender();

run Receiver()

}} }

}

24

Page 25: Lecture 3 (on Promela and SPIN)

AB Protocol (version 2, with losses )mtype = { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

chan r s = [2] of {mtype , bit };

active proctype Receiver() {

byte recd ;

bit rbit, seqno = 0;chan r_s [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

bit sbit seqno = 0;

bit rbit, seqno 0;

do

:: s_r ? msg (recd, seqno) ->

if

:: r s ! ack(seqno)bit sbit, seqno = 0;

do

:: s_r ! msg(data, sbit) ->

r_s ? ack(seqno);

if

:: r_s ! ack(seqno)

:: skip

fi;

if

:: seqno == rbit >if

:: seqno == sbit ->

sbit = 1 - sbit ;

data++

l

:: seqno == rbit ->

rbit = 1 - rbit

:: else

fi

d:: else

fi

:: (1) -> skip

od

}

od

}

}

25

Page 26: Lecture 3 (on Promela and SPIN)

AB Protocol (version 3, w. retransmission)mtype = { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

chan r s = [2] of {mtype , bit };

active proctype Receiver() {

byte recd, expected = 0;

bit rbit = 1, seqno;chan r_s [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

bit sbit seqno = 0;

bit rbit 1, seqno;

do

:: s_r ? msg (recd, seqno) ->

if

:: seqno != rbit ->bit sbit, seqno = 0;

do

:: s_r ! msg(data, sbit)

:: (1) -> skip

:: r s ? ack(seqno);

:: seqno != rbit ->

rbit = 1 - rbit ;

assert(recd == expected) ;

expected++:: r_s ? ack(seqno);

if

:: seqno == sbit ->

sbit = 1 - sbit ;

d t

expected++

:: else

fi

:: r_s ! ack (rbit)

:: (1) -> skipdata++

:: else

fi

od

}

:: (1) -> skip

od

}

}

26

Page 27: Lecture 3 (on Promela and SPIN)

AB Protocol (version 4, w. checks)mtype = { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

chan r s = [2] of {mtype , bit };

active proctype Receiver() {

byte recd, expected = 0;

bit rbit = 1, seqno;chan r_s [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

bit sbit seqno = 0;

bit rbit 1, seqno;

do

:: s_r ? msg (recd, seqno) ->

if

:: seqno != rbit ->bit sbit, seqno = 0;

do

:: data < 10 -> s_r ! msg(data, sbit)

:: (1) -> skip

:: seqno != rbit ->

rbit = 1 - rbit ;

assert(recd == expected);

expected++

:: else:: (1) > skip

:: r_s ? ack(seqno);

if

:: seqno == sbit ->

sbit = 1 - sbit ;

:: else

fi

:: r_s ! ack (rbit)

:: (1) -> skip

dsbit = 1 - sbit ;

data++

:: else

fi

od

od

}

od

}

27

Page 28: Lecture 3 (on Promela and SPIN)

AB Protocol (version 5, limiting checks)mtype = { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

chan r s = [2] of {mtype , bit };

active proctype Receiver() {

byte recd, expected = 0;

bit rbit = 1, seqno;chan r_s [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

bit sbit seqno = 0;

bit rbit 1, seqno;

do

:: s_r ? msg (recd, seqno) ->

if

:: seqno != rbit ->bit sbit, seqno = 0;

do

:: data < 10 -> s_r ! msg(data, sbit)

:: (1) -> skip

:: seqno != rbit ->

rbit = 1 - rbit ;

progress: assert(recd == expected) ;

expected++

:: else:: (1) > skip

:: r_s ? ack(seqno);

if

:: seqno == sbit ->

sbit = 1 - sbit ;

:: else

fi

:: r_s ! ack (rbit)

:: (1) -> skip

dsbit = 1 - sbit ;

data++

:: else

fi

od

od

}

od

}

28

Page 29: Lecture 3 (on Promela and SPIN)

AB Protocol (version 6, w progress)mtype = { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

chan r s = [2] of {mtype , bit };

active proctype Receiver() {

byte recd, expected = 0;

bit rbit = 1, seqno;chan r_s [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

bit sbit seqno = 0;

bit rbit 1, seqno;

do

:: s_r ? msg (recd, seqno) ->

if

:: seqno != rbit ->bit sbit, seqno = 0;

do

:: data < 10 -> s_r ! msg(data, sbit)

:: (1) -> progress1: skip

:: seqno != rbit ->

rbit = 1 - rbit ;

progress: assert(recd == expected) ;

expected++

:: else:: (1) > progress1: skip

:: r_s ? ack(seqno);

if

:: seqno == sbit ->

sbit = 1 - sbit ;

:: else

fi

:: r_s ! ack (rbit)

:: (1) -> progress2: skip

dsbit = 1 - sbit ;

data++

:: else

fi

od

od

}

od

}

29

Page 30: Lecture 3 (on Promela and SPIN)

AB Protocol (version 7, w progress)# define MAXMSG 4

mtype = { msg, ack };

active proctype Receiver() {

byte recd = 0;

bit rbit = 1, seqno;mtype { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

chan r_s = [2] of {mtype , bit };

chan source = [0] of {byte};

bit rbit 1, seqno;

do

:: s_r ? msg (recd, seqno) ->

if

:: seqno != rbit ->[ ] { y };

chan sink = [0] of {byte};

active proctype Sender() {

byte data = 0;

:: seqno != rbit ->

sink!recd;

progress: rbit = 1 - rbit

:: else

fibyte data = 0;

bit sbit, seqno = 0;

source?data;

do

:: s r ! msg(data sbit)

fi

:: r_s ! ack (rbit)

:: (1) -> progress2: skip

od

}:: s_r ! msg(data, sbit)

:: (1) -> progress1: skip

:: r_s ? ack(seqno);

if

:: seqno sbit >

}

:: seqno == sbit ->

sbit = 1 - sbit ;

source?data

:: else

fi

30

fi

od

}

Page 31: Lecture 3 (on Promela and SPIN)

AB Protocol (version 7, w harness)# define MAXMSG 4

chan source = [0] of {byte};

active proctype Checker() {

byte expected, inmsg= 0;

dochan source [0] of {byte};

chan sink = [0] of {byte};

do

:: sink?inmsg ->

assert(inmsg == expected);

expected = (expected+1)%MAXMSG

od

active proctype Generator() {

byte seed = 0;

do

od

}

do

:: source!seed -> seed = (seed+1)%MAXMSG

od

}}

31

Page 32: Lecture 3 (on Promela and SPIN)

AB Protocol (version 8, new harness)# define white 0

# define red 1

# define blue 2

active proctype Checker() {

byte inmsg;

do# define blue 2

chan source = [0] of {byte};

chan sink = [0] of {byte};

do

:: sink?inmsg ->

if

:: (inmsg == red) -> break

:: else assert(inmsg == white)

active proctype Generator() {

do

:: source!white

:: else assert(inmsg == white)

fi

od;

do

:: sink?inmsg >:: source!white

:: source!red -> break

od;

do

! hit

:: sink?inmsg ->

if

:: (inmsg == blue) -> break

:: else assert(inmsg == white)

fi:: source!white

:: source!blue -> break

od;

end: do

hi

fi

od;

end1: do

:: sink?inmsg ->

(i hi ):: source!white

od

}

assert(inmsg == white)

od

}

32

Page 33: Lecture 3 (on Promela and SPIN)

AB Protocol (version 9, w acceptance)#define p Sender@Slabel

#define q Receiver@Rlabel

#define r Receiver@Rsuccess

active proctype Receiver() {

byte recd = 0;

bit rbit = 1, seqno;#define r Receiver@Rsuccess

mtype = { msg, ack };

chan s_r = [2] of {mtype , byte, bit};

bit rbit 1, seqno;

do

:: s_r ? msg (recd, seqno) ->

if

:: seqno != rbit ->};

chan r_s = [2] of {mtype , bit };

active proctype Sender() {

byte data = 0;

:: seqno != rbit ->

Rsuccess: sink!recd;

rbit = 1 - rbit

:: else

fibyte data = 0;

bit sbit, seqno = 0;

source?data;

do

:: s r ! msg(data sbit) ->

fi

:: r_s ! ack (rbit) -> Rlabel: skip

:: (1) -> skip

od

}:: s_r ! msg(data, sbit) -> Slabel: skip

:: (1) -> skip

:: r_s ? ack(seqno);

if

}

if

:: seqno == sbit ->

sbit = 1 - sbit ;

source?data

:: else

33

:: else

fi

od

}

Page 34: Lecture 3 (on Promela and SPIN)

AB Protocol (version 9, the never claim)#define p Sender@Slabel

#define q Receiver@Rlabel

#define r Receiver@Rsuccess

T0_init:

if

:: (! ((r)) && (p) && (q)) -> goto#define r Receiver@Rsuccess

/*

* Formula As Typed: ([] <> p && [] <> q) -> [] <> r

:: (! ((r)) && (p) && (q)) > goto accept_S485

:: (! ((r)) && (p)) -> goto T2_S485

:: (! ((r))) -> goto T0_S485

:: (1) -> goto T0 init[] q) []

* The Never Claim Below Corresponds

* To The Negated Formula !(([] <> p && [] <> q) -> [] <> r)

( ) g _

fi;

accept_S485:

if

:: (! ((r))) -> goto T0 S485* (formalizing violations of the

original)

*/

:: (! ((r))) > goto T0_S485

fi;

T2_S485:

if

:: (! ((r)) && (q)) -> gotonever { /* !(([] <> p && [] <>

q) -> [] <> r) */

:: (! ((r)) && (q)) -> goto accept_S485

:: (! ((r))) -> goto T2_S485

fi;

T0 S485:T0_S485:

if

:: (! ((r)) && (p) && (q)) -> goto accept_S485

:: (! ((r)) && (p)) -> goto T2 S485

34

:: (! ((r)) && (p)) > goto T2_S485

:: (! ((r))) -> goto T0_S485

fi;

}

Page 35: Lecture 3 (on Promela and SPIN)

Specifying invariant properties

assert (v <= 2)Always executableIf v <= 2 is false,

SPIN exits with errorUsed to check invariants

35

Page 36: Lecture 3 (on Promela and SPIN)

Checking by monitor#define true 1

#define false 0

#d fi 1 f l

proctype P2() {

m1: y2 = true;

2 1#define turn1 false

#define turn2 true

bool y1, y2, t;

m2: t = turn1;

m3: (y1 == false || t == turn2) ;

mutex++ ;

m4: /* critical section */bool y1, y2, t;

byte mutex = 0;

proctype P1() {

m4: / critical section /

mutex-- ;

atomic{ y2 = false ; goto m1 }

}

l1: y1 = true;

l2: t = turn2;

l3: (y2 == false || t == turn1) ;

t

active proctype monitor() {

assert (mutex <= 1)

}mutex++ ;

l4: /* critical section */

mutex -- ;

atomic{ y1 = false ; goto l1 }

}

init {

atomic { run P1() ; run P2() }atomic{ y1 false ; goto l1 }

}

atomic { run P1() ; run P2() }

}

36

Page 37: Lecture 3 (on Promela and SPIN)

Checking deadlocks#define true 1

#define false 0

#d fi 1 f l

proctype P2() {

m1: y2 = true;

2 ki#define turn1 false

#define turn2 true

bool y1, y2, t;

m2: skip ;

m3: (y1 == false) ;

mutex++ ;

m4: /* critical section */bool y1, y2, t;

byte mutex = 0;

proctype P1() {

m4: / critical section /

mutex-- ;

atomic{ y2 = false ; goto m1 }

}

l1: y1 = true;

l2: skip ;

l3: (y2 == false) ;

t

active proctype monitor() {

assert (mutex <= 1)

}mutex++ ;

l4: /* critical section */

mutex -- ;

atomic{ y1 = false ; goto l1 }

}

init {

atomic { run P1() ; run P2() }atomic{ y1 false ; goto l1 }

}

atomic { run P1() ; run P2() }

}

37

Page 38: Lecture 3 (on Promela and SPIN)

Checking progress by progress-labels#define MAX 5

mtype = { mesg, ack, nak, err };

proctype receiver(chan in, out) {

byte i; /* actual input */

byte s; /* actual seqno */

proctype sender(chan in, out)

{ byte o, s, r;

o=MAX-1;

do

byte es; /* expected seqno */

byte ei; /* expected input */

do

:: in?mesg(i, s) ->

ifdo

:: o = (o+1)%MAX; /* next msg */

again: if

:: out!mesg(o,s) /* send */

:: (1) -> progress1: out!err(0,0) /* distort */

:: (s == es) ->

assert(i == ei);

progress: es = 1 - es;

ei = (ei + 1)%MAX;

ifdistort */

:: (1) -> progress2: skip /* or lose */

fi;

if

timeout > goto again

if

/* send, */ :: out!ack(s,0)

/* distort */ :: (1) -> out!err(0,0)

:: (1) -> skip

fi:: timeout -> goto again

:: in?err(0,0) -> goto again

:: in?nak(r,0) -> goto again

:: in?ack(r,0) ->

if

:: (s != es) ->

if

/* send, */ :: out!nak(s,0)

/* distort */ :: (1) -> out!err(0,0)

:: (1) -> skip:: (r == s) -> goto progress

:: (r != s) -> goto again

fi

fi;

progress: s = 1-s /* toggle seqno */

fi

fi

:: in?err(0,0) -> out!nak(s,0)

od

}

38

p g / gg q /

od

}

}

Page 39: Lecture 3 (on Promela and SPIN)

Checking progress (ctd.)init {

chan s_r = [1] of { mtype,byte,byte };

chan r s = [1] of { mtype,byte,byte };chan r_s [1] of { mtype,byte,byte };

atomic {

run sender(r_s, s_r);

run receiver(s_r, r_s)

}}

}

39

Page 40: Lecture 3 (on Promela and SPIN)

Progress labels: improved version#define MAX 5

mtype = { mesg, ack, nak, err };

proctype receiver(chan in, out) {

byte i; /* actual input */

byte s; /* actual seqno */

proctype sender(chan in, out)

{ byte o, s, r;

o=MAX-1;

do

byte es; /* expected seqno */

byte ei; /* expected input */

do

:: in?mesg(i, s) ->

ifdo

:: o = (o+1)%MAX; /* next msg */

again: if

:: out!mesg(o,s) /* send */

:: (1) -> progress1: out!err(0,0) /* distort */

:: (s == es) ->

assert(i == ei);

progress: es = 1 - es;

ei = (ei + 1)%MAX;

ifdistort */

:: (1) -> progress2: skip /* or lose */

fi;

if

timeout > goto again

if

/* send, */ :: out!ack(s,0)

/* distort */ :: (1) -> progress1:out!err(0,0)

:: (1) -> progress2:skip:: timeout -> goto again

:: in?err(0,0) -> goto again

:: in?nak(r,0) -> goto again

:: in?ack(r,0) ->

if

skip

fi

:: (s != es) ->

if

/* send, */ :: out!nak(s,0)

/ i / ( ):: (r == s) -> goto progress

:: (r != s) -> goto again

fi

fi;

progress: s = 1-s /* toggle seqno */

/* distort */ :: (1) -> progress3:out!err(0,0)

:: (1) -> progress4:skip

fi

fi

40

p g / gg q /

od

}

init {

fi

:: in?err(0,0) -> out!nak(s,0)

od

}

Page 41: Lecture 3 (on Promela and SPIN)

Automata properties: never claims

{

Automata specifications can be given in Promela as Never claims, e.g.,

• ( > ) never {

do

:: skip

• □ ( p -> □p )

:: p -> break

od ;

doT p

T¬p

T

:: skip

:: !p -> break

od

}

Never claims execute in lock-step with the rest of the Promela modelAccept if they reach the end

41

Page 42: Lecture 3 (on Promela and SPIN)

Buchi Automata as never claims

{

Accepting states designated by labels acceptxxxxx

◊( /\ ) never {

do

:: skip

• ◊( p /\ □¬q)

T p /\¬q :: p && !q -> break

od ;

accept: do

¬qp /\¬q

:: !q

od

}

The never claim accepts if the Promela model has cycle with only !q

Then SPIN reports a violating cycle.

42


Recommended