Promela/SPIN

Acknowledgements: Thesenotesusedsomeof thematerialpresentedby Flavio Lerda aspartofEd Clarke’smodel-checking course

SPIN ‡ Forcheckingcorrectnessofprocessinteractions » Specifiedusingbufferedchannels,sharedvariablesorcombination » Focus:asynchronouscontrolinsoftwaresystems » Promela – program-likenotationforspecifyingdesignchoices ‹ Modelsareboundedandhavecountably manydistinctbehaviors ‡ GenerateaCprogramthatperformsanefficient onlineverificationofthesystem’scorrectness properties ‡ Typesofproperties: » ,violatedassertions,unreachablecode » Systeminvariants,generalLTLproperties ‡ Randomsimulationsofthesystem’sexecution ‡ “Proofapproximation” •2

1 ExplicitStateModelChecker ‡ Representsthesystemasafinitestatemachine ‡ Visitseachreachablestate(statespace)explicitly (usingNestedDFS) ‡ Performson-the-flycomputation ‡ Usespartialorderreduction ‡ Efficientmemoryusage » Statecompression » Bit-statehashing ‡ Version4: » Uninterpreted CcodecanbeusedaspartofPromela model

•3

HighLevelOrganization

LTLformula Promela Model

LTLTranslator Buchi Automaton Buchi Translator

Promela Parser TheBuchi automatonis turnedintoaPromela AbstractSyntaxTree processandcomposed Automata Automata withtherestofthesystem. Generator Thegeneratedverifieris CGeneratospr ecifictothemodeland propertywestartedwith. CCode

C PanVerifier

VerificationResult •4

2 Promela (ProcessMetaLanguage) ‡ Asynchronouscompositionofindependent processes ‡ Communicationusingchannelsandglobal variables ‡ Non-deterministicchoicesandinterleavings ‡ BasedonDijkstra’s guardedcommandlanguage » Everystatementguardedbyaconditionandblocksuntilcondition becomestrue Example: while(a==b) skip/*waitfora==b*/ vs (a==b) •5

ProcessTypes ‡ Stateofvariableormessagechannelcanonlybe changedorinspectedbyprocesses(defined usingproctype) ‡ ;and->arestatementseparatorswithsame semantics. » ->usedinformallytoindicatecausalrelationbetweenstatements Example: bytestate=2; proctype A() { (state==1)->state=3 } proctype B() { state=state-1 } ‡ state hereisaglobalvariable •6

3 ProcessInstantiation ‡ Needtoexecuteprocesses » proctype onlydefinesthem ‡ Howtodoit? » Bydefault,processoftypeinit alwaysexecutes » runstartsprocesses » Alternatively,definethemasactive(seelater) ‡ Processescanreceiveparameters » allbasicdatatypesandmessagechannels. » Dataarraysandprocesstypesarenotallowed. Example: proctype A(bytestate;shortfoo) { (state==1)->state=foo } init { runA(1,3) } •7

Example ‡ Asmentionedearlier,nodistinctionbetweena statementandcondition.

bool a,b; proctype p1() { a=true; a&b; Thesestatementsareenabled onlyifbotha andb aretrue. a=false; } Inthiscaseb isalwaysfalse proctype p2() andthereforethereisa { deadlock. b=false; a&b; b=true; } init{a=false;b=false;runp1();runp2();} •8

4 AnExample mtype ={NONCRITICAL,TRYING,CRITICAL}; Atmostonemtype canbe mtype state[2]; declared proctype process(int id){ beginning: noncritical: state[id]=NONCRITICAL; if ::goto noncritical; NC ::true; fi; trying: state[id]=TRYING; if T ::goto trying; ::true; fi; critical: C state[id]=CRITICAL; if ::goto critical; ::true; fi; goto beginning;} init{runprocess(0);runprocess(1)} •9

Otherconstructs ‡ Doloops

do ::count=count +1; ::count=count - 1; ::(count==0)->break od

•10

5 Otherconstructs ‡ Doloops ‡ Communicationoverchannels

proctype sender(chan out) { int x;

if ::x=0; ::x=1; fi

out!x; }

•11

Otherconstructs ‡ Doloops ‡ Communicationoverchannels ‡ Assertions

proctype receiver(chan in) { int value; out?value; assert(value ==0||value==1) }

•12

6 Otherconstructs ‡ Doloops ‡ Communicationoverchannels ‡ Assertions ‡ AtomicSteps

int value; proctype increment() { atomic { x=value; x=x+1; value=x; } }

•13

MessagePassing chan qname =[16]of{short} qname!expr – writing(appending)tochannel qname?expr – reading(fromhead)ofthechannel qname??expr – “peaking”(withoutremovingcontent) qname!!expr – checkingifthereisroomtowrite candeclarechannelforexclusivereadorwrite: chan in,out;xr in;xs out; qname!exp1,exp2,exp3 – writingseveralvars qname!expr1(expr2,expr3) – typeandparams qname?vari(var2,var3) qname?cons1,var2,cons2 – cansendconstants » Lessparameterssentthanreceived– othersareundefined » Moreparameterssent– remainingvaluesarelost » Constantssentmustmatchwithconstantsreceived •14

7 MessagePassingExample proctype A(chan q1) { chan q2; q1?q2; q2!123 } proctype B(chan qforb) { int x; qforb?x; print(“x=%d\n”,x) } init { chan qname =[1]of{chan }; chan qforb =[1]of{int }; runA(gname); runB(qforb); qname!qforb } Prints: 123

•15

Randez-vous Communications ‡ Bufferofsize0– canpassbutnotstore messages » Messageinteractionsbydefinitionsynchronous Example: #definemsgtype 33 chan name=[0]of{byte,byte}; proctype A() { name!msgtype(123); name!msgtype(121);/*non-executable*/ } proctype B() { bytestate; name?msgtype(state) } init { atomic{ runA();runB()} } •16

8 Randez-Vous Communications(Cont’d) ‡ Ifchannelname haszerobuffercapacity: » Handshakeonmessagemsgtype andtransferofvalue123to variablestate. » Thesecondstatementwillnotbeexecutablesincenomatching receiveoperationinB ‡ Ifchannelnamehassize1: » ProcessAcancompleteitsfirstsendbutblocksonthesecond sincechannelisfilled. » Bcanretrievethismessageandcomplete. » ThenAcompletes,leavingthelastmessageinthechannel ‡ Ifchannelnamehassize2ormore: » AcanfinishitsexecutionbeforeBevenstarts

•17

Example– protocol ‡ ChannelsAin andBin » tobefilledwithtokenmessagesoftypenextandarbitraryvalues (ASCIIchars)… » byunspecifiedbackgroundprocesses:theusersofthetransfer service ‡ Theseuserscanalsoreadreceiveddatafromthe channelsAout andBout ‡ Thechannelsareinitializedinasingleatomic statement… » Andstartedwiththedummyerr message.

•18

9 ExampleCont’d mtype ={ack,nak,err,next,accept}; proctype transfer(chan in,out,chin,chout) { byteo,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(Cont’d) init { chan AtoB =[1]if{mtype,byte}; chan BtoA =[1]of{mtype,byte};

chan Ain =[2]of{mtype,byte}; chan Bin=[2]of{mtype,byte};

chan Aout =[2]of{mtype,byte}; chan Bout=[2]of{mtype,byte};

atomic{ runtransfer(Ain,Aout,AtoB,BtoA); runtransfer(Bin,Bout,BtoA,AtoB); } AtoB!err(0) } •20

10 MutualExclusion ‡ Peterson’ssolutiontothemutualexclusion problem

flag0=1

turn=0 flag0=0

flag1 ==0||turn==1

flag1 !=0&&turn!=1

Critical Section

•21

MutualExclusioninSPIN

bool turn; bool flag[2]; proctype mutex0(){ again: flag[0]=1; flag0=1 turn=0; (flag[1]==0||turn==0); turn=0 flag =0 /*criticalsection*/ 0 flag ==0||turn==1 flag[0]=0; 1

goto again; flag1 !=0&&turn!=1 } •22

11 MutualExclusioninSPIN

_pid: bool turn,flag[2]; Identifieroftheprocess active[2]proctype user() assert: { Checksthatthereareonly atmosttwoinstanceswith assert(_pid ==0||__pid ==1); identifiers0and1 again: flag[_pid]=1; turn=_pid; (flag[1- _pid]==0||turn==1- _pid);

/*criticalsection*/

flag[_pid]=0; goto again; } •23

MutualExclusioninSPIN bool turn,flag[2]; bytencrit; ncrit: Countsthenumberof active[2]proctype user() processesinthecriticalsection { assert(_pid ==0||__pid ==1); again: flag[_pid]=1; turn=_pid; (flag[1- _pid]==0||turn==1- _pid);

ncrit++; assert(ncrit ==1);/*criticalsection*/ assert: ncrit--; Checksthatthereisalways atmostoneprocessinthe flag[_pid]=0; criticalsection goto again; •24 }

12 Verification ‡ Generate,compileandruntheverifier » tocheckforandothermajorproblems:

$spin–amutex $cc–Opanpan.c $pan fullstatespacesearchfor: assertionviolationsandinvalidendstates vector20bytes,depthreached19,errors:0 79states,stored 0states,linked 38states,matched total:117 hashconflicts:4(resolved) (sizes^18states,stackframes:3/0) unreached code_init(proc0); reachedall3states unreached codeP(proc1): reachedall12states •25

MutualExclusion ‡ Verifier:Assertioncanbeviolated » Canuse-t-ptofindoutthetrace ‹ OruseXSpin ‡ Anotherwayofcatchingtheerror » Haveanothermonitorprocessraninparallel » Allowsallpossiblerelativetimingsoftheprocesses » Elegantwaytocheckvalidityofsysteminvariant

•26

13 MutualExclusioninSPIN bool turn,flag[2]; bytencrit;

active[2]proctype user() { assert(_pid ==0||__pid ==1); again: flag[_pid]=1; turn=_pid; (flag[1- _pid]==0||turn==1- _pid);

ncrit++; /*criticalsection*/ ncrit--;

flag[_pid]=0; goto again; }

activeproctype monitor() { assert(ncrit ==0||ncrit ==1)} •27

Finally, ‡ CanspecifyanLTLformulaandrunthemodel- checker Example: #definepcount<=1 » LTLclaim:[]p ‡ Note:allvariablesinLTLclaimshavetobeglobal! ‡ LTLclaimgetstranslatedintoNEVERclaimand storedeitherin.ltl fileorattheendofmodelfile » OnlyoneLTLpropertycanbeverifiedatatime ‡ ParameterscanbesetusingXSpin » Depthofsearch,availablememory,etc.

•28

14 MutualExclusioninSPIN bool turn,flag[2]; bool critical[2]; LTLProperties: active[2]proctype user() [](critial[0]||critical[1]) { assert(_pid ==0||__pid ==1); []<>(critical[0]) again: []<>(critical[1]) flag[_pid]=1; turn=_pid; [](critical[0]-> (flag[1- _pid]==0|| (critial[0]U (!critical[0]&& turn==1- _pid); ((!critical[0]&& !critical[1])Ucritical[1])))) critical[_pid]=1; /*criticalsection*/ [](critical[1]-> critical[_pid]=0; (critial[1]U (!critical[1]&& flag[_pid]=0; ((!critical[1]&& goto again; !critical[0])Ucritical[0])))) } Note:critical[]isaglobalvar! •29

Alternatively, #definepncrit <=1 #defineqncrit =0 LTLProperties: bool turn,flag[2]; bytencrit; [](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++; /*criticalsection*/ ncrit--;

flag[_pid]=0; goto again; •30 }

15 CommandLineTools ‡ Spin » GeneratesthePromela codefortheLTLformula $spin–f“[]<>p” ‹ Thepropositionintheformulamustcorrespondto#defines » GeneratestheCsourcecode $spin–asource.pro ‹ Thepropertymustbeincludedinthesource ‡ Pan » Performstheverification ‹ Hasmanycompiletimeoptionstoenabledifferentfeatures ‹ Optimizedforperformance

•31

Xspin

‡ GUIforSpin

•32

16 Simulator ‡ Spincanalsobeusedasasimulator » SimulatedthePromela program ‡ Itisusedasasimulatorwhenacounterexampleis generated » Stepsthroughthetrace » Thetraceitselfisnot“readable” ‡ Canbeusedforrandomandmanuallyguided simulationaswell

•33

Afewexamples

‡AlternatingBitProtocol ‡LeaderElection

17 AlternatingBitProtocol ‡ Twoprocesseswanttocommunicate ‡ Theywantacknowledgementofreceived messages ‡ Sendingwindowofonemessage ‡ Eachmessageisidentifiedbyonebit ‡ Alternatingvaluesoftheidentifier

•35

AlternatingBitProtocol

Sender Receiver

msg0

ack0

msg1

ack1

msg0

ack0

msg1

•36

18 AlternatingBitProtocol

Sender Receiver

msg0

ack1

msg0

ack0

•37

AlternatingBitProtocol

Sender Receiver

msg0

msg0

ack0

msg1

ack1

•38

19 SenderProcess activeproctype Sender() { :: do if :: ::receiver?msg1; if ::skip ::receiver?msg0; fi; ::skip do fi; ::sender?ack1->break do ::sender?ack0 ::sender?ack0->break ::timeout-> ::sender?ack1 if ::timeout-> ::receiver!msg1; if ::skip ::receiver!msg0; fi; ::skip od; fi; od; od; }

•39

ReceiverProcess activeproctype Receiver() mtype ={msg0,msg1,ack0,ack1} { chan sender=[1]of{mtype }; do chan receiver=[1]of{mtype }; :: do ::receiver?msg0-> sender!ack0;break; ::receiver?msg1-> server!ack1 od

do ::receiver?msg1-> sender!ack1;break; ::receiver?msg0-> server!ack0 od od } •40

20 LeaderElection ‡ Electleaderinunidirectionalring. » Allprocessesparticipateinelection » Cannotjoinaftertheexecutionstarted ‡ Globalproperty: » Itshouldnotbepossibleformorethanoneprocesstodeclaretobe theleaderofthering LTL:[](nr_leaders <=1) Useassertion(line57) assert(nr_leaders ==1) thisismuchmoreefficient! » Eventuallyaleaderiselected ‹ <>[](nr_leaders ==1)

•41

VerificationofLeaderElection 1#defineN5/*nrofprocesses*/ 2#defineI3/*nodegiventhesmallestnumber*/ 3#defineL10/*sizeofbuffer(>=2*N)*/ 4 5mtype ={one,two,winner};/*symb.messagenames*/ 6chan q[N]=[L]of{mtype,byte}/*asynch channel*/ 7 8bytenr_leaders =0;/*countthenumberofprocesses 9 thatthinktheyareleaderofthering*/ 10proctype node(chan in,out;bytemynumber) 11{bitActive=1,know_winner =0; 12 bytenr,maximum=mynumber,neighbourR; 13 14 xr in;/*claimexclusiverecv accesstoin*/ 15 xs out;/*claimsexclusivesendaccesstoout*/ 16 17 printf (“MSC:%d\n”,mynumber); 18 out!one(mynumber)/*sendmsg oftypeone*/ 19 one:do 20 ::in?one(nr)->/*receivemsg oftypeone*/ •42

21 VerificationofLeaderElection 21if 22::Active-> 23 if 24 ::nr!=maximum-> 25 out!two(nr); 26 neighbourR =nr; 27 ::else-> 28 /*maxisthegreatestnumber*/ 29 assert(nr==N); 30 know_winner =1; 31 out!winner(nr); 32 fi 33 ::else-> 34 out!one(nr) 35 fi 36 37 ::in?two(nr)-> 38 if 39 ::Active-> 40 if •43

VerificationofLeaderElection 41 ::neighbourR >nr&&neighbourR >maximum 42 maximum=neighbourR; 43 out!one(neighbourR) 44 ::else-> 45 Active=0 46 fi 47 ::else-> 48 out!two(nr) 49 fi 50 ::in?winner(nr)-> 51 if 52 ::nr!=mynumber ->printf (“LOST\n”); 53 ::else-> 54 printf (“Leader\n”); 55 nr_leaders++; 56 assert(nr_leaders ==1); 57 fi 58 if 59 ::know_winner 60 ::else-> 61 out!winner(nr) •44

22 VerificationofLeaderElection 62fi; 63break 64od 65} 66 67init{ 68byteproc; 69 atomic{/*activateNcopiesofproctemplate*/ 70 proc=1; 71 do 72 ::proc<=N-> 73 runnode(q[proc-1],q[proc%N], 74 (N+I-proc)%N+1); 75 proc++ 76 ::proc>N->break 77od 78} 79}

•45

Summary ‡ Distinctionbetweenbehaviorandrequirementson behavior » Whicharecheckedfortheirinternalandmutualconsistency ‡ Afterverification,canrefinedecisionstowardsa fullsystemimplementation » Promela isnotafullprogramminglanguage ‡ Cansimulatethedesignbeforeverificationstarts

•46

23 Comments ‡ DFSdoesnotnecessarilyfindtheshortest counterexample » Theremightbeaveryshortcounterexamplebuttheverification mightgooutofmemory » Ifwedon’tfinish,wemightstillhavesomesortofaresult (coveragemetrics)

•47

On-The-Fly ‡ Systemistheasynchronouscompositionof processes ‡ Theglobaltransitionrelationisneverbuild ‡ Foreachstatethesuccessorstatesare enumeratedusingthetransitionrelationofeach process

•48

24 VisitedSet ‡ Hashtable » Efficientfortestingevenifthenumberofelementsinitisverybig (≥106) ‡ Reducememoryusage » Compresseachstate ‡ Reducethenumberofstates » PartialOrderReduction Whenatransitionisexecutedonlya limitedpartofthestateismodified

•49

SPINandBit-stateHashing ‡ Commandline: » cc–DBITSTATE–orunpan.c ‡ Canspecifyamountofavailable(non-virtual) memorydirectly… » using–wN option,e.g.,-w7 means128Mbofmemory $run assertionviolated… panaborted … hashfactor:67650.064516 (size2^22states,stackframes:0/5) ‡ Hashfactor: » maxnumberofstates/actualnumber » Maximumnumberis222orabout32million » Hashfactor>100– coveragearound100% » Hashfactor=1– coverageapproaches0% •50

25 StateRepresentation ‡ Globalvariables ‡ Processesandlocalvariables ‡ Queues

GlobalVariables Processes Queues

•51

Compression ‡ Eachtransitionchangesonlyasmallpartofthe state ‡ Assignacodetoeachelementdynamically ‡ Encodedstates+basicelementsuseconsiderably lessspacesthantheuncompressedstates

•52

26 Compression

P0 P0 Q0 P0 P1 i=0j=0 x=0 x=1 {1} x=0 y=0 0 0 1 0 0 2

3 3 3

P1 2 2 2 y=0

P0 1 1 1 x=1

P0 Q0 0 i=0j=0 0 0 x=0 {1} •53

Compression

P0 P0 Q0 P0 P1 i=0j=0 x=0 x=1 {{1}} x=01 y=0 0 0 1 01 01 2 q?x

3 3 3

P1 2 2 2 y=0

P0 Q0 1 1 1 x=1 {}

P0 Q0 0 i=0j=0 0 0 x=0 {1} •54

27 HashCompaction ‡ Usesahashingfunctiontostoreeachstateusing only2bits ‡ Thereisanon-zeroprobabilitythattwostatesare mappedintothesamebits ‡ Ifthenumberofstatesismuchsmallerthanthe numberofbitsavailablethereisaprettygood chanceofnothavingconflicts ‡ Theresultisnot(always)100%correct!

•55

MinimizedAutomataReduction ‡ Turnsthestateintoasequenceofintegers ‡ Constructsanautomatonwhichacceptsthestates inthevisitedset ‡ WorkslikeaBDDbutonnon-binaryvariables (MDD) » Thevariablesarethecomponentsofthestate » Theautomatonisminimal » Theautomatonisupdatedefficiently

•56

28 PartialOrderReduction ‡ Optimalpartialorderreductionisasdifficultas modelchecking! ‡ Computeanapproximationbasedonsyntactical information Accesstolocalvariables » Independent Receiveonexclusivereceive-accessqueues » Invisible Sendonexclusivesend-accessqueues » Check(atrun-time)foractionspostponedatinfinitum

Notmentionedintheproperty

Socalledstackproviso

•57

References ‡ http://spinroot.com/ ‡ DesignandValidationofComputerProtocols byGerard Holzmann ‡ TheSpinModelChecker byGerardHolzmann ‡ Anautomata-theoreticapproachtoautomaticprogram verification,byMosheY.Vardi,andPierreWolper ‡ Ananalysisofbitstate hashing,byG.J.Holzmann ‡ AnImprovementinFormalVerification,byG.J.Holzmann and D.Peled ‡ Simpleon-the-flyautomaticverificationoflineartemporallogic, byRobGerth,Doron Peled,MosheVardi,andPierre Wolper ‡ AMinimizedautomatonrepresentationofreachablestates,by A.Puri andG.J.Holzmann

•58

29