• No results found

Analyzing Counterexample Traces

8.2 Solving the Symmetric Protocol Completion Problem

8.2.2 Analyzing Counterexample Traces

We now describe in detail how we perform the analysis of counterexamples returned by the model checker. Our implementation first composes the ESM sketches to form aproductesm-sk

Π. It then compiles down this productesm-skΠinto guarded commands. These guarded commands operate over a set of variables which include the state variables of everyesmand

esm-skin the protocol, as well as a distinguished variable that tracks the location of eachesm

oresm-sk. The guards and updates of each guarded command are as defined in Section 2.2, and the updates include the update to the distinguished location variable for eachesmand

esm-skas well. The guards and updates of the guarded commands are also transformed by the compiler to useselect,store,projectandupdatefunctions12 for reads and updates of arrays and records respectively. Furthermore, repeated assignments to the same variable in a guarded command are coalesced into a single assignment. In effect, each variable (be it of a scalar type, an array type or a record type) hasat most oneassignment to it in the list of updates associated

with each guarded command. These transformations on the guarded commands make it easier to compute the weakest preconditions of predicates with respect to the guarded commands, as we shall now explain.

Let the set of guarded commands beG, given a guarded commandcmd∈G, we define guard(cmd)to be the guard ofcmdandupdate(cmd)to be the list of coalesced updates of

cmd. The weakest precondition of a predicate ϕwith respect to an assignment statement stmt,l:=eis defined aswp(stmt,ϕ)≡ϕ[l7→e], whereϕ[l7→e]is the expression obtained by replacing all instances of the sub-expressionlinϕwith the expressione. We extend the definition of the weakest precondition of a predicateϕwith respect to a sequence of statements in the natural way. The weakest precondition of a predicateϕ with respect to a guarded commandcmdis defined is defined aswpcmd(cmd,ϕ)≡guard(cmd)→wp(update(cmd),ϕ). In the rest of this section, we use the symbol>to refer to the Boolean constanttrueand the symbol⊥to refer tofalse, respectively, for brevity and readability.

Analyzing Deadlocks

In Figure 1.13(b), consider the candidate interpretation where bothgcrit,gwaitare set to be uni- versallyfalse. Two deadlock states are then reachable:S1= ((L3,L3),{flag7→ h>,>i,turn7→ 12These are functions defined in the theory of arrays and records by the SMTLIB2 standard. For details, see

P1}andS2= ((L3,L3),{flag7→ h>,>i,turn7→P0}. We strengthenϕby asserting that these deadlocks do not occur in future interpretations: eitherS1is unreachable, or the system can make a transition fromS1 (and similarly forS2). In this example, the reachability of both deadlock states is not dependent on the interpretation,i.e., the execution that leads to the

states does not exercise any unknown function, hence, we need to make sure that the states are not deadlocks. The possible transitions out of location(L3,L3)are the transitions fromL3 toL3(waiting transition) and fromL3toL4(critical transition) for each of the two processes. In each deadlock state, at least one of the four guards has to be true. So in the case of the deadlock in stateS1, we add the following disjunction to the set of constraints:

gwait(P0,P1,h>,>i,P1)∨gcrit(P0,P1,h>,>i,P1)∨

gwait(P1,P0,h>,>i,P1)∨gcrit(P1,P0,h>,>i,P1)

Similarly for the case of the deadlock in stateS2, we add the following disjunction to the set of constraints:

gwait(P0,P1,h>,>i,P0)∨gcrit(P0,P1,h>,>i,P0)∨

gwait(P1,P0,h>,>i,P0)∨gcrit(P1,P0,h>,>i,P0)

The two disjunctions are added to the set of constraints, since any candidate interpretation has to satisfy them in order for the resulting product to be deadlock-free.

Analyzing Safety Violations

Consider now an erroneous interpretation where the critical transition guards are true for both processes whenturnisP0, that is: gcrit(P0,P1,h>,>i,P0)andgcrit(P1,P0,h>,>i,P0)are set to true. Under this interpretation the product can reach the error location(L4,L4). We perform a weakest precondition analysis on the corresponding execution to obtain a necessary condition under which the safety violation is possible. In this case, the execution crosses both critical transitions and the generated constraint is¬gcrit(P0,P1,h>,>i,P0)∨ ¬gcrit(P1,P0,h>,>i,P0). Note that the constraints obtained from this analysis are necessary: the protocol under any interpretation that satisfies the negation of the constraints would exhibit the same safety violation.

More formally, given an error trace that is a non-repeating execution (i.e., a witness for a

of guarded commands fromG, say, cmd1,cmd2, . . . ,cmdn. Given a predicate Γ, we define pre0(Γ)≡Γ, and recursively defineprei(Γ)≡wpcmd(cmdni1,prei-1(Γ)). Then, if the trace is a witness for a safety violation, we add the constraintC,pren(Γ)[v7→ σ0(v)], for every variablevin the system, to our set of constraintsϕ, whereΓ is the invariant which was violated. We note that after simplifications, Cwill be a constraint that refers only to the unknown functionsfu ∈U; also, all arguments to an unknown functionfu will beconcrete valuesinC.

In fact,Cwill not refer toanyvariable at all, once it has been appropriately simplified. Our prototype employs extensive simplifications at each step during the computation of weakest preconditions to ensure that the formulas do not grow to be unmanageably large.

On the other hand if the trace is a witness for a deadlock, we add the constraint C , pren WcmdGguard(cmd)[v7→σ0(v)], for every variablevin the system, to the set of con- straintsϕmaintained by the algorithm. This constraint ensures that if this particular execution is ever permitted under an interpretation for the unknown functionsUchosen in the future, then some guarded command is enabled at the end of the execution, under that interpretation, therefore no longer rendering the final state of the execution a deadlock.

Analyzing Liveness Violations

An interpretation that satisfies the constraints gathered above is one that, when turnisP0,

enables both waiting transitions and disables the critical ones. Intuitively, under this interpreta- tion, the two processes will not make progress ifturnisP0when they reachL3. The executions in which the processes are atL3and eitherP0orP1continuously take the waiting transition is an accepting one. As with safety violations, we eliminate liveness violations by adding con- straints generated through weakest precondition analysis of the accepting executions. In this case, this results in two constraints: ¬gwait(P0,P1,h>,>i,P0)and¬gwait(P1,P0,h>,>i,P0). However, in the presence of fairness assumptions, these constraints are too strong. This is because removing an execution that causes a fair liveness violation is not the only way to resolve it: another way is to make it unfair. Given the weak fairness assumption on the transitions on the criticalPichannels, the correct constraint generated for the liveness violation of ProcessP0

is: ¬gwait(P0,P1,h>,>i,P0)∨gcrit(P0,P1,h>,>i,P0)∨gcrit(P1,P0, true, true,P0), where the last two disjuncts render the accepting execution unfair.

To describe the process of analyzing liveness counterexamples more formally, we assume that infinite accepting executions are given as a pair of a finite stem execution of sizenand a finite

cycle execution of sizem. First, we describe the case where no fairness assumptions exist in the system. The constraint computed from an accepting execution asserts either that the sequence of transitions should not be enabled or that the state of the system at the beginning of the cycle should be not be the same as the state at the end. If the set of variables ofΠis{v1, . . . ,vN}we introduce symbolic constantsv10, . . . ,vN0 and setΓ ≡v16=v10 ∨v26=v20∨· · ·∨vN6=vN0 . We first computeC=prem(Γ)on the cycle execution and then substitutev10, . . . ,vN0 forv1, . . . ,vN inC:C0 =C[v17→v10, . . . ,vN7→vN0 ]. We then get the final constraint by computingpren(C0) on the stem execution.

We now describe the case where strong fairness assumptions are present. LetFsbe the set

of strong fairness assumptions andGbe the union of all setsF∈Fssuch that every guarded

command inFis disabledeverywherein the cycle. We adapt the computation ofpreiin the cycle execution as follows: pre0i(Γ)≡wpcmd(cmdni1,prei-1(Γ)∨ W

cmd∈Gguard(cmd))

. Enabling a commandcmdinGat a step in the cycle execution has the effect of making the accepting cycle unfair: sincecmdis never executed in the cycle, enforcingguard(cmd)makes

cmdinfinite often enabled but never taken.

The case where weak fairness requirements are present is similar: we setGto be the union of all the setsF ∈ Fw, such that: (1) there exists at least one state in the cycle which has the property thateveryguarded command inFis disabled at that state, and (2) no guarded

command inFis ever executed anywhere in the cycle,i.e., there do not exist statess1ands2 in the cycle such thats2can be reached froms1by executing some command inF. The rest of the process to obtain a constraint that ensures that the cycle is unfair is the same as for strong fairness assumptions.