Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Model Checking and Verification of Concurrent Programs in Maude - Prof. Jose Meseguer, Study notes of Computer Science

The model checking and verification of concurrent imperative programs in maude, a language based on rewriting logic. It covers the verification of declarative deterministic programs, the reduction of the correctness of imperative programs to proving inductive properties satisfied by the initial model, and the use of temporal logic, model checking, or deductive proof to prove such properties. The document also presents the rewriting semantics of the parallel module and provides examples of model checking dekker's algorithm and the thread game.

Typology: Study notes

Pre 2010

Uploaded on 03/16/2009

koofers-user-1xi-1
koofers-user-1xi-1 🇺🇸

10 documents

1 / 43

Toggle sidebar

Related documents


Partial preview of the text

Download Model Checking and Verification of Concurrent Programs in Maude - Prof. Jose Meseguer and more Study notes Computer Science in PDF only on Docsity! Program Verification: Lecture 23 José Meseguer Computer Science Department University of Illinois at Urbana-Champaign 1 Model Checking TOK-RING Consider the following TOK-RING module, (fth NZNAT* is protecting NAT . op * : -> NzNat . endfth) (fmod NAT/(N :: NZNAT*) is sort Nat/(N) . op ‘[_‘] : Nat -> Nat/(N) . op _+_ : Nat/(N) Nat/(N) -> Nat/(N) . op _*_ : Nat/(N) Nat/(N) -> Nat/(N) . vars I J : Nat . ceq [I] = [I rem *] if I >= * . eq [I] + [J] = [I + J] . eq [I] * [J] = [I * J] . endfm) 2 Model Checking TOK-RING (III) (omod CHECK-TOK-RING(N :: NZNAT*) is inc TOK-RING(N) . inc MODEL-CHECKER . subsort Configuration < State . op inCrit : Nat/(N) -> Prop . op twoInCrit : -> Prop . var I : Nat . vars X Y : Nat/(N) . var C : Configuration . var F : Formula . eq < X : Proc | mode : critical > C |= inCrit(X) = true . eq < X : Proc | mode : critical > < Y : Proc | mode : critical > C |= twoInCrit = true . 5 op guaranteedReentrance : -> Formula . op allProcessesReenter : Nat -> Formula . op nextIter_ : Formula -> Formula . op nextIterAux : Nat Formula -> Formula . ceq guaranteedReentrance = allProcessesReenter(I) if s(I) := * . eq allProcessesReenter(s(I)) = (<> inCrit([s(I)])) /\ [] (inCrit([s(I)]) -> (nextIter inCrit([s(I)]))) /\ allProcessesReenter(I) . eq allProcessesReenter(0) = (<> inCrit([0])) /\ [] (inCrit([0]) -> (nextIter inCrit([0]))) . eq nextIter F = nextIterAux(2 * *, F) . eq nextIterAux(s I, F) = O nextIterAux(I, F) . eq nextIterAux(0, F) = F . endom) 6 Model Checking TOK-RING (IV) We cannot model check these properties directly in their parameterized form. However, for each nozero value n we can check the corresponding instance of these properties. For example, for n = 5 we define in Full Maude the view, (view 5 from NZNAT* to NAT is op * to term 5 . endv) Then we can model check the mutual exclusion property for 5 processes as follows: (red in CHECK-TOK-RING(5) : modelCheck(init,[] ~ twoInCrit) .) result Bool : true 7 Verification of Concurrent Imperative Programs (II) What should the analogous situation be in the case of concurrent imperative programs? We should of course specify the semantics of a concurrent imperative language L as a rewrite theory R(L) (in fact, a Maude system module). Then, the correctness of imperative programs in L can be reduced to proving inductive properties satisfied by the initial model TReach(R(L)). If such properties are specified in temporal logic, then we can use methods such as model checking or deductive proof. We can illustrate this general method by definig the rewriting logic semantics of a simple parallel language called PARALLEL. 10 The Rewriting Semantics of PARALLEL *** A simple parallel language and its rewriting logic semantics. *** Extends an even simpler language presented in ‘‘The Maude LTL *** Model Checker’’ by Eker, Meseguer, and Sridaranarayanan, *** in Proc. WRLA’02, ENTCS Vol. 71, Elsevier, 2002. fmod MEMORY is inc INT . inc QID . sorts Memory Bool? Int? . subsorts Bool < Bool? . subsorts Int < Int? . op null : -> Int? . op none : -> Memory . op __ : Memory Memory -> Memory [assoc comm id: none] . op [_,_] : Qid Int? -> Memory . op _in_ : Qid Memory -> Bool? . var Q : Qid . var M : Memory . var N? : Int? . eq null + N? = null . eq null * N? = null . eq Q in [Q,N?] M = true . endfm 11 ***(Equality test comparing the contents of a named memory location to an Int? value.) fmod TESTS is inc MEMORY . sort Test . op _=_ : Qid Int? -> Test . op eval : Test Memory -> Bool . var Q : Qid . var M : Memory . vars N? N’? : Int? . eq eval(Q = N?, [Q, N’?] M) = N? == N’? . ceq eval(Q = N?, M) = N? == null if Q in M =/= true . endfm ***(Syntax for arithmetic expressions, and their evaluation semantics. To avoid evaluation of expressions by themselves, which would happen even without a memory for integer subexpressions if we keep the usual syntax, the operators + and * are specified as constructors with syntax +’ and *’ ) 12 The Rewriting Semantics of PARALLEL (II) Using the above functional modules, we can then define our simple parallel language in a system module PARALLEL. The global state is a triple consisting of: 1. a “soup” (set) of processes; 2. the shared memory; and 3. a process identifier recording the last process that touched the memory or, in any event, performed some computation. Processes themselves are pairs having a process identifier and a program. 14 The Rewriting Semantics of PARALLEL (III) mod PARALLEL is inc SEQUENTIAL . inc TESTS . sorts Pid Process Soup MachineState . subsort Process < Soup . subsort Int < Pid . op [_,_] : Pid Program -> Process . op empty : -> Soup . op _|_ : Soup Soup -> Soup [prec 61 assoc comm id: empty] . op {_,_,_} : Soup Memory Pid -> MachineState . 15 vars P R : Program . var S : Soup . var U : UserStatement . var L : LoopingUserStatement . vars I J : Pid . var M : Memory . var Q : Qid . vars N? X? : Int? . var T : Test . var E : Expression . rl {[I, U ; R] | S, M, J} => {[I, R] | S, M, I} . rl {[I, L ; R] | S, M, J} => {[I, L ; R] | S, M, I} . rl {[I, (Q := E) ; R] | S, [Q, X?] M, J} => {[I, R] | S, [Q,eval(E,[Q, X?] M)] M, I} . crl {[I, (Q := E) ; R] | S, M, J} => {[I, R] | S, [Q,eval(E,M)] M, I} if Q in M =/= true . 16 Dekker’s Mutex Algorithm (II) The code of process 1 in PARALLEL is as follows, repeat c1 := 1 ; while c2 = 1 do if turn = 2 then c1 := 0 ; while turn = 2 do skip od ; c1 := 1 fi od ; crit ; turn := 2 ; c1 := 0 ; rem1 forever . 19 Dekker’s Mutex Algorithm (III) The code of process 2 is entirely symmetric: repeat c2 := 1 ; while c1 = 1 do if turn = 1 then c2 := 0 ; while turn = 1 do skip od ; c2 := 1 fi od ; crit ; turn := 1 ; c2 := 0 ; rem2 forever . 20 Dekker’s Mutex Algorithm (IV) We can then define the two processes for Dekker’s algorithm and the desired initial state in the following module extending PARALLEL. Note that we assume that crit does terminate, whereas rem may not. mod DEKKER is inc PARALLEL . subsort Int < Pid . op crit : -> UserStatement . op rem : -> LoopingUserStatement . ops p1 p2 : -> Program . op initialMem : -> Memory . op initial : -> MachineState . 21 Model Checking Dekker’s Algorithm We need to define three state predicates parameterized by the process id: enterCrit, when the process is about to enter its critical section, in-rem, when the process is executing its remaining code fragment, and exec, when the process has just executed. mod CHECK is inc DEKKER . inc MODEL-CHECKER . inc LTL-SIMPLIFIER . *** optional subsort MachineState < State . ops enterCrit in-rem exec : Pid -> Prop . var M : Memory . vars R : Program . var S : Soup . vars I J : Pid . eq {[I, crit ; R] | S, M, J} |= enterCrit(I) = true . eq {[I, rem ; R] | S, M, J} |= in-rem(I) = true . eq {S, M, J} |= exec(J) = true . endm 24 Model Checking Dekker’s Algorithm (II) The mutual exclusion property is satisfied: reduce in CHECK : modelCheck(initial,[]~ (enterCrit(1) /\ enterCrit(2))) . ModelChecker: Property automaton has 2 states. ModelCheckerSymbol: Examined 263 system states. rewrites: 1714 in 50ms cpu (50ms real) (34280 rewrites/second) result Bool: true 25 Model Checking Dekker’s Algorithm (III) But the strong liveness property that executing infinitely often implies entering one’s critical section infinitely often fails, as witnessed by the counterexample, reduce in CHECK : modelCheck(initial,[]<> exec(1) -> []<> enterCrit(1)) . ModelChecker: Property automaton has 3 states. ModelCheckerSymbol: Examined 16 system states. rewrites: 159 in 0ms cpu (0ms real) (~ rewrites/second) result ModelCheckResult: counterexample({{[1,repeat ’c1 := 1 ; while ’c2 = 1 do if ’turn = 2 then ’c1 := 0 ; while ’turn = 2 do skip od ; ’c1 := 1 fi od ; crit ; ’turn := 2 ; ’c1 := 0 ; rem forever] | [2,repeat ’c2 := 1 ; while ’c1 = 1 do if ’turn = 1 then ’c2 := 0 ; while ’turn = 1 do skip od ; ’c2 := 1 fi od ; crit ; ’turn := 1 ; ’c2 := 0 ; rem forever],[’c1,0] [’c2,0] [ ’turn,1],0},unlabeled} ... 26 The Thread Game A simple, yet interesting, program that we can also implement in PARALLEL is a “game,” suggested by J Moore, between two forever-looping processes accessing a shared variable ’c that initially holds the value 1. Each process loop reads twice the value of ’c in two different local variables, and then writes the sum of those two local variables back into ’c. There is no synchronization at all between the processes. Two interesting questions are: (1) which values can ’c hold, depending on the different strategies in this game? and (2) which values can ’c hold if only one of the processes is actually running? 29 The Thread Game (II) The code for these processes and the relevant initial states can be defined as follows, mod THREAD-GAME is inc PARALLEL . ops p1 p2 : -> Program . ops init init1 init2 : -> MachineState . eq p1 = repeat ’a1 := ’c ; ’b1 := ’c ; ’c := ’a1 +’ ’b1 forever . 30 eq p2 = repeat ’a2 := ’c ; ’b2 := ’c ; ’c := ’a2 +’ ’b2 forever . eq init = { [1, p1] | [2, p2], [’c, 1], 0 } . eq init1 = { [1, p1], [’c, 1], 0 } . eq init2 = { [2, p2], [’c, 1], 0 } . endm 31 S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] M:Memory --> [’a1,2] [’b1,3] [’a2,1] [’b2,2] J:Pid --> 1 Maude> search [1] init =>* { S:Soup, [’c, 6] M:Memory, J:Pid } . Solution 1 (state 243) states: 244 rewrites: 1278 in 20ms cpu (20ms real) (63900 rewrites/second) S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] M:Memory --> [’a1,2] [’b1,2] [’a2,2] [’b2,4] J:Pid --> 2 Maude> search [1] init =>* { S:Soup, [’c, 7] M:Memory, J:Pid } . Solution 1 (state 912) states: 913 rewrites: 4998 in 100ms cpu (100ms real) (49980 rewrites/second) S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] M:Memory --> [’a1,4] [’b1,3] [’a2,1] [’b2,2] J:Pid --> 1 34 Maude> search [1] init =>* { S:Soup, [’c, 8] M:Memory, J:Pid } . search [1] in THREAD-GAME : init =>* {S:Soup,M:Memory [’c,8],J:Pid} . states: 236 rewrites: 1234 in 30ms cpu (30ms real) (41133 rewrites/second) S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] M:Memory --> [’a1,4] [’b1,4] J:Pid --> 1 Maude> search [1] init =>* { S:Soup, [’c, 9] M:Memory, J:Pid } . Solution 1 (state 883) states: 884 rewrites: 4846 in 90ms cpu (90ms real) (53844 rewrites/second) S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] M:Memory --> [’a1,3] [’b1,3] [’a2,3] [’b2,6] J:Pid --> 2 Maude> search [1] init =>* { S:Soup, [’c, 10] M:Memory, J:Pid } . Solution 1 (state 829) states: 830 rewrites: 4511 in 90ms cpu (90ms real) (50122 rewrites/second) S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] 35 M:Memory --> [’a1,4] [’b1,6] [’a2,2] [’b2,4] J:Pid --> 1 ... Maude> search [1] init =>* { S:Soup, [’c, 99] M:Memory, J:Pid } . Solution 1 (state 68974) states: 68975 rewrites: 408394 in 8960ms cpu (9020ms real) (45579 rewrites/second) S:Soup --> [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever] | [2, repeat ’a2 := ’c ; ’b2 := ’c ; ’c := (’a2 +’ ’b2) forever] M:Memory --> [’a1,48] [’b1,51] [’a2,3] [’b2,48] J:Pid --> 1 36 ---> {empty | [1,(’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1)) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever ; skip],[’a1,2] [’c,4] [’b1,2],1} ---> {empty | [1,’b1 := ’c ; ’c := (’a1 +’ ’b1) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’c,4] [’b1,2]) [’a1,eval(’c, ([’c,4] [’b1,2]) [ ’a1,2])],1} ---> {empty | [1,’c := (’a1 +’ ’b1) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’a1,4] [’c,4]) [’b1,eval(’c, ([’a1,4] [’c,4]) [’b1,2])],1} ---> {empty | [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’a1,4] [’b1,4]) [’c,eval(’a1 +’ ’b1, ([’a1,4] [’b1,4]) [’c,4])],1} ---> {empty | [1,(’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1)) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever ; skip],[’a1,4] [’c,8] [’b1,4],1} 39 ---> {empty | [1,’b1 := ’c ; ’c := (’a1 +’ ’b1) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’c,8] [’b1,4]) [’a1,eval(’c, ([’c,8] [’b1,4]) [ ’a1,4])],1} ---> {empty | [1,’c := (’a1 +’ ’b1) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’a1,8] [’c,8]) [’b1,eval(’c, ([’a1,8] [’c,8]) [’b1,4])],1} ---> {empty | [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’a1,8] [’b1,8]) [’c,eval(’a1 +’ ’b1, ([’a1,8] [’b1,8]) [’c,8])],1} ---> {empty | [1,(’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1)) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever ; skip],[’a1,8] [’c,16] [’b1,8],1} ---> {empty | [1,’b1 := ’c ; ’c := (’a1 +’ ’b1) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’c,16] [’b1,8]) [’a1,eval(’c, ([’c,16] [’b1,8]) [’a1,8])],1} 40 ---> {empty | [1,’c := (’a1 +’ ’b1) ; repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’a1,16] [’c,16]) [’b1,eval(’c, ([’a1,16] [’c,16]) [’b1, 8])],1} ---> {empty | [1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],([’a1, 16] [’b1,16]) [’c,eval(’a1 +’ ’b1, ([’a1,16] [’b1,16]) [’c,16])],1} result MachineState: {[1,repeat ’a1 := ’c ; ’b1 := ’c ; ’c := (’a1 +’ ’b1) forever],[’a1,16] [’c,32] [’b1,16],1} Maude> 41
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved