<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Model Checking for Stability Analysis in Rely-Guarantee Proofs</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Hasan Amjad</string-name>
          <email>Hasan.Amjad@cl.cam.ac.uk</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Richard Bornat</string-name>
          <email>R.Bornat@mdx.ac.uk</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Middlesex University School of Computing Science</institution>
          ,
          <addr-line>London NW4 4BT</addr-line>
          ,
          <country country="UK">UK</country>
        </aff>
      </contrib-group>
      <fpage>3</fpage>
      <lpage>11</lpage>
      <abstract>
        <p>Rely-guarantee (RG) reasoning is useful for modular Hoare-style proofs of concurrent programs. However, RG requires that assertions be proved stable under the actions of the environment. We cast stability analysis as a model checking problem and show how this may be of use in interactive and automatic verification.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
      <p>Multi-core and multi-processor computing systems are now mainstream.
Consequently, concurrent programs are the focus of much recent research on
automatically proving safety, correctness and liveness properties. Often, the assertions
we would like to prove are not amenable to existing automatic analyses. This
paper studies one such scenario, and shows how existing automatic techniques
can nonetheless help the proof process. The demonstration is expected to be the
first step towards a fully automatic method.</p>
      <p>Shared-memory concurrency, where multiple threads have read/write access
to the same memory addresses, is commonplace. The main challenge in proving
properties of such programs, and indeed in their design, is dealing with
interference, i.e., the possibility that threads may concurrently make changes to the
same memory address.</p>
      <p>
        The concurrent programming community has evolved several synchronisation
schemes to avoid interference. Most rely on some form of access denial, such as
locks. Whereas locks make it easy to reason about the correctness, they may
also cause loss of efficiency as threads wait to acquire locks on needed resources.
Locking schemes have thus become increasingly fine-grained, attempting to deny
access to the smallest possible size of resource, to minimise waiting and maximise
concurrency. The ultimate form of such fine-grained concurrency are programs
that manage without any synchronisation at all [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ].
      </p>
      <p>The finer the concurrency, the more involved the logic for avoiding
interference. This logic must implicitly or explicitly take the actions of other threads
into account. This is a problem for program proofs where we strive for
modularity, i.e., we wish to be able to reason about a piece of code in isolation from
the various environments it could execute in.</p>
      <p>
        Rely-guarantee reasoning [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ] offers a solution to this problem within the
framework of Hoare-style program proofs [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ], by encoding the environment into
the proof: all assertions must be shown to be unaffected under the actions of the
environment. Automatically checking for and ensuring such non-interference can
be problematic in many cases. In this paper, we describe preliminary progress
on a possible solution.
      </p>
      <p>
        The next section gives brief relevant background. We then describe our
method, and comment on shortcomings and possible developments. We assume
some familiarity with program proofs using Hoare logic [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ], and with model
checking [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ].
2
2.1
      </p>
    </sec>
    <sec id="sec-2">
      <title>Preliminaries</title>
      <sec id="sec-2-1">
        <title>Rely-guarantee Reasoning</title>
        <p>
          Rely-guarantee (RG) is a compositional verification method for shared memory
concurrency introduced by Jones [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ]. Interference between threads is described
using binary relations. In that treatment, post-conditions were relational, so
assertions could talk about the state before and after an action. Here, in line
with traditional Hoare logic, we shall use post-conditions of a single state, as this
usually makes for simpler proofs. In either case, the essence of RG is unaffected
by this choice.
        </p>
        <p>
          Our command language will be the one used by Jones [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ], i.e., with
assignment, looping, branching, sequential composition and parallel composition,
using C-like syntax. For parallel composition we assume standard interleaved
execution semantics, i.e., threads are programs with access to some shared state,
and atomic instructions occur interleaved.
        </p>
        <p>Program variables will range over B and N. It may seem odd to have program
variables range over infinite types. In practice however, reasoning about numbers
with the aid of abstraction, has been found to be more tractable than reasoning
about finite but huge state spaces over words or bit-vectors, which are harder
to abstract due to fiddly problems with overflow and underflow.</p>
        <p>
          RG can be seen as a compositional version of the Owicki-Gries method [
          <xref ref-type="bibr" rid="ref15">15</xref>
          ].
The specification for a command C is a four-tuple (P, R, G, Q), where P and Q
are the usual Hoare logic pre- and post-condition assertions on a single state. C
satisfies this specification if from a state satisfying P , and under environmental
interference R (the rely), C causes interference at most G (the guarantee), and
if it terminates, it does so in a state satisfying Q.
        </p>
        <p>R and G summarise the properties of the individual atomic actions invoked
by the environment and the thread respectively. An action is given as a binary
relation on the shared state, and is written P Q. This notation indicates that
the action updates the part of shared state that satisfies P (at the moment the
action executes), so that it satisfies Q.</p>
        <p>For example, the action corresponding to the command x := x + 1, that
increments a shared integer x, might be written as
x = N</p>
        <p>x = N + 1
where the implicitly existentially quantified N serves to relate the state before
and after the execution. Such logical variables are required for describing actions
using single-state assertions. We shall denote them using N, M, . . . and assume
they are existentially quantified with scope limited to the action.</p>
        <p>G is the relation given by the reflexive and transitive closure of all actions
of the thread being specified. The actions are given by manual annotation, as in
general, automatic action discovery is non-trivial. R is calculated in an identical
manner from the actions of the environment. Typically, the actions comprising
R are just the G actions of all the other threads.</p>
        <p>An assertion P on a single state is considered stable under interference from
a binary relation R if (P ; R) ⇒ P , i.e., if P (s) and (s, s0) ∈ R, then P (s0).
More specifically, if P is the pre-condition for some command C, then it must
continue to hold after any environment action, before the execution of C. For
our purpose, we do not need to pin down the level of atomicity of execution.</p>
        <p>Jones gives a full proof system for the satisfaction relation, but we will not
need it for this work. However, we reproduce the two critical rules here, to make
our assumptions about RG concrete. The first rule is parallel composition, where
|| is the interleaving parallel composition operator.</p>
        <p>(P1, R ∨ G2, G1, Q1)</p>
        <p>C1
(P2, R ∨ G1, G2, Q2)</p>
        <p>C2
(P1 ∧ P2, R, G1 ∨ G2, Q1 ∧ Q2)</p>
        <p>C1||C2
The second rule tells us what it means for a command to be atomic.
(P, id, true, Q ∧ G)
(P, R, G, Q)</p>
        <p>C</p>
        <p>P stable under R
atomic(C)</p>
        <p>Note one departure from standard RG: the post-condition of the very last
line of code is not checked for stability. It is instantaneously true immediately
after execution of that line. At this point, either the thread terminates, so that
we do not care whether the environment interferes with the post-condition, or,
the thread resumes execution from some command the pre-condition of which
will be the same as this post-condition, and thus will be checked for stability.
2.2</p>
      </sec>
      <sec id="sec-2-2">
        <title>Temporal Logic Model Checking</title>
        <p>Let V be the set of program variables (or state variables) used in a program (with
appropriate scope management, which we ignore without loss of generality).
Each v ∈ V ranges over a non-empty set of values Dv. The state space S of
the program is given by Qv∈V Dv. A single state of the program is then a value
assignment to each v ∈ V .</p>
        <p>Suppose AP is the set of all those atomic propositions over V that we might
use in the specification of a program. Then we can turn the program into a state
machine (technically, a Kripke structure) M represented as a tuple (S, S0, T, L)
where S is the set of states, S0 ⊆ S is the set of initial states, T ⊆ S × S is the
transition relation, and L : S → 2AP labels each state with the subset of AP
that is true in that state.</p>
        <p>A temporal logic augments propositional logic with modal and fix-point
operators. The semantics of a temporal logic formula in which the atomic
propositions range over AP can be expressed in terms of sets of states and/or sequences
of states of M . If we turn a program into a state machine, we can use temporal
logics to express time-dependent properties of the program.</p>
        <p>The most common such property is the global invariant, i.e., a property that
holds in all states of a state machine, or equivalently, always holds during the
execution of a program.</p>
        <p>Global invariants can be checked automatically using proof procedures known
as model checkers, subject only to time and space constraints. More importantly,
if the proof attempt fails, the model checker can return a counterexample, which
is an execution path (sequence of states) leading from an initial state to a state
in which the invariant is not satisfied.</p>
        <p>
          The problem of model checking global invariants is in general undecidable
when the state space is infinite. However, the ability to produce counterexamples
has led to the development of counterexample guided abstraction refinement
(CEGAR) [
          <xref ref-type="bibr" rid="ref16 ref3">3, 16</xref>
          ], where the state space is first abstracted to a simpler one,
and if the constructed abstraction is too general it can often be automatically
iteratively refined until the desired property is verified. For our purposes we
will assume a simple abstraction scheme consisting of a single total abstraction
function α : S → A, where A is the abstract state space (the exact structure of
which depends on the α under consideration). Typically, α is not injective and
need not be surjective.
        </p>
        <p>
          We do not need to describe model checking or CEGAR in more depth,
particularly as there are many different abstraction schemes and CEGAR techniques.
Further details may be found in [
          <xref ref-type="bibr" rid="ref16 ref2 ref3 ref7">2, 3, 7, 16</xref>
          ].
3
        </p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Stability Analysis as Model Checking</title>
      <p>If the assertion permits, stability can be checked syntactically and unstable
assertions can be automatically stabilised by a fix-point computation that
disjunctively adds state until stability is achieved. More precisely, given an assertion
satisfying a set of states s, we compute the fix-point by
until sn+1 = sn, i.e, performing n environment transitions. If the domain of any
program variable is infinite, this fix-point computation might not terminate. In
such cases, automatic stabilisation techniques rely on abstract interpretation to
simplify the domain.</p>
      <p>As a simple example, consider the assertion x = 10 that is clearly unstable
under the environment action x = N x = N + 1. To stabilise, we would
proceed
s0 = (x = 10)
s1 = (x = 10 ∨ x = 11)
s2 = (x = 10 ∨ x = 11 ∨ x = 12)
.
.</p>
      <p>.
so automatic stabilisation will not terminate. To fix it, we could use the boolean
abstraction α(x) ⇐⇒ x ≥ 10. Under this abstraction the action above becomes
the identity action in all cases except when x = 9, but in that case x = 10 does
not hold anyway, so we have stability immediately, and the assertion is stabilised
to x ≥ 10.</p>
      <p>In general, if the abstraction is too weak, it may throw away so much
information that the proof becomes impossible (e.g., we can trivially stabilise any
assertion by replacing it with true). But if the abstraction is too strong, the
fix-point computation may not terminate, or may run out of time or space
resources.</p>
      <p>
        Current techniques therefore use hand-crafted abstraction heuristics that are
found to work in practice, for the underlying variable domains [
        <xref ref-type="bibr" rid="ref17 ref5">5, 17</xref>
        ].
      </p>
      <p>We have seen in §2.2 that this problem of finding exactly the right level of
abstraction also occurs in model checking. It is our hope that the model checking
solution can be applied to stability analysis as well. If so, the vast amount of
model checking research on this topic can be brought to bear on the problem.
We now present the first step towards this goal, by representing stability analysis
as a model checking problem.</p>
      <p>Rather than representing R and G as the reflexive transitive closures of their
constituent actions, we consider them as state machines over the shared state.
In addition, the state machine also has state variables for the program counters
of the constituent threads. Tracking program counters allows us to easily encode
the flow control of actions in the state machine.</p>
      <p>The state machine for the guarantee condition Gt for a thread t, is Mt =
(St, S0t, t, Lt) and is constructed as follows. Let Vt be the set of all shared
program variables used in t as well as the t program counter pct : N. Then St is
constructed like S in §2.2. S0t is those states of St in which pct = 0 and in which
any other v ∈ Vt are assigned their initial values if any. Let al be the (possibly
empty) set of actions associated with the primitive command on line l of the
thread code (this is for easy specification: in reality a single atomic statement
can only have a single associated action, so the analysis simply conjoins them).
Then
t((s, pct), (s0, pc0t)) = _
l
pct = l ∧ pc0t = next(s, l) ∧
^ a(s, s0)</p>
      <p>!
a∈al
where the next function encodes the control flow of thread t. Finally, Lt(s) =
{p ∈ AP | p(s) = true}. The state machine for R, MR = (SR, S0R, TR, LR) over
variables VR, is constructed analogously, though of course it is more complicated
since it encompasses the actions of all the other threads.</p>
      <p>Now suppose that we wish to stabilise an assertion P that is the pre-condition
of a command at program line l in a thread t. The first step is to check whether
the assertion is already stable. To do this we augment MR with fresh1 variables
corresponding to any thread-local variables that occur in P , and also add
identity actions over these variables to TR so that their values never change. This
represents our intuition that when checking the stability under the environment
of an assertion in thread t, t itself is not executing.</p>
      <p>
        We can now model check the augmented state machine M R0 for the global
invariant P . Note that here we can use standard model checking abstraction
construction techniques [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] to try and avoid non-termination. If the invariant
holds, then since it is a global invariant and α is total, it holds in the concrete
state space as well. Otherwise, we will obtain a counter-example giving a
sequence of actions of the abstract state machine that violates the invariant. At
this point, standard CEGAR techniques can be employed to check whether the
counterexample has a corresponding concrete trace, in which case the stability
check has failed. If not, the abstract trace is spurious (caused by too weak an
abstraction), so we refine the abstraction using standard CEGAR methods and
call the model checker again, until we have success or failure.
      </p>
      <p>At this point we have already improved on existing stabilisation methods by
not being reliant on having a syntactic check for stability. However, we still have
to handle the case where the stability check fails.</p>
      <p>In this situation, we have at hand a counterexample trace π showing a
sequence of environment actions that falsified P , and also the particular
abstraction function α being used by the model checker when the stability check failed.
These two pieces of information can be used to weaken P and then repeat the
stability check, and iterate until P is stable.
1 So that there is no name clash with any v ∈ VR.</p>
      <p>For example, if we are using predicate abstraction techniques, then for our
running example where we are checking stability of P ≡ x = 10, we may have
α(x) ⇐⇒ x = 10
and
π ≡ x = 10
where k uniquely identifies the action responsible. This information suggests
generalising P to x ≥ 10, and then the stability check succeeds.</p>
      <p>
        This is as far as we have come. The new weakened assertion must be found
manually for now, using the point-of-failure α and π as guides, as in the example
above. Of course, we could simply use the existing method of repeated disjunctive
addition of the resultant state of the involved actions (which in this
cherrypicked example fails to terminate). However, the model checking approach gives
us extra information (point-of-failure π and α) which should hopefully allow
us to do better. We plan to develop an automatic method that uses symbolic
simulation driven by the counterexample traces, perhaps in combination with
heuristics, to weaken P in a useful manner. Here, we expect to use existing model
checking research on automatic abstraction construction [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ].
      </p>
      <p>
        In fact, at the moment our in-development tool (effectively a translation layer
on top of the NuSMV model checker [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]) does not even perform abstraction, as
all our test assertions are over finite domains. This is because while it would be
simple to switch to a tool supporting automatic abstraction (e.g., BLAST [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]),
we are more interested in finding out how to use π to weaken P , which is the
real challenge.
3.1
      </p>
      <sec id="sec-3-1">
        <title>Comment: Refining Stability</title>
        <p>In standard RG, the rely is represented as the reflexive transitive closure of all
actions that the environment can execute. This can also be thought of as a state
machine, albeit a not very informative one in which any transition (action) can
execute from any state. Thus, our representation of R and G as state machines
of actions can be seen as a refinement of the standard RG representation. The
latter can be thought of as the state machine consisting of all states reachable
from any state via all possible interleavings of the underlying actions, regardless
of whether these interleavings will ever actually occur. Our refinement proceeds
by adding control flow information, thus ruling out certain interleavings.</p>
        <p>Thus it is possible for us to prove the stability of stronger assertions than is
possible in standard RG. Since the stability check is orthogonal to the RG proof
system, this means that we automatically obtain a stronger proof system.</p>
        <p>Indeed, we can parameterise the RG proof system by the level of refinement
of R and G. We have experimented along these lines by adding some G actions
to R, or by selectively exposing the thread-local state of the environment, both
of which rule out some class of impossible action sequences. In each case we
have been able to prove properties that are stronger, and often more intuitive
to specify.</p>
        <p>There is a trade-off here, since adding more information to R and G will
almost certainly make the underlying model checking problem harder, affecting
scalability. Nonetheless, increasing the refinement level is attractive not only
because it permits stronger properties to be proved, but also because the stabilised
assertion may be syntactically smaller and thus more readable. This latter
consideration is important if these methods are used as part of a larger interactive
proof framework, such as a theorem prover.
4</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Remarks</title>
      <p>
        We do not know of any other work that uses model checking for stability analysis
in Hoare-style RG proofs. There is work underway at MSR Cambridge [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ] that
also represents R and G as state machines, but their aim is to deal with questions
of liveness. Other than that we know only of the automatic stabilisation work
that inspired our own effort [
        <xref ref-type="bibr" rid="ref17">17</xref>
        ].
      </p>
      <p>
        It is well known [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] that the standard RG proof rule for parallel composition
can become unsound if the satisfaction relation is strengthened (e.g., to include
liveness). We are safe since stability is a safety property, for which the standard
RG proof system is sound.
      </p>
      <p>
        Apart from the unfinished aspect, this approach has other shortcomings. An
important one is that refining R and G quickly makes the underlying model
checking problem more resource intensive. The same refinement (specifically,
the need to track program counters) also prevents the results from scaling up
to arbitrary numbers of threads for free, unlike in standard RG. We expect
that model checking techniques like paramatric verification [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ] and
assumeguarantee reasoning [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ] (not to be confused with rely-guarantee) may help
with this. More generally, our ability to change the refinement level of R and G
should also help ameliorate the situation.
      </p>
      <p>
        We are also considering the use of separation logic in this framework, to
frame out irrelevant state and thus alleviate our model checking woes. RG and
separation logic have already been combined [
        <xref ref-type="bibr" rid="ref18">18</xref>
        ]. Extending that framework to
our method will be another thread of future work.
      </p>
      <p>Acknowledgement The first author would like to thank Viktor Vafeiades for
permission to copy from the description of RG in his Ph.D. thesis.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>Alessandro</given-names>
            <surname>Cimatti</surname>
          </string-name>
          ,
          <string-name>
            <surname>Edmund M. Clarke</surname>
          </string-name>
          , Enrico Giunchiglia, Fausto Giunchiglia, Marco Pistore, Marco Roveriand, Roberto Sebastiani, and Armando Tacchella.
          <article-title>NuSMV 2: An OpenSource tool for symbolic model checking</article-title>
          . In Ed Brinksma and Kim Guldstrand Larsen, editors,
          <source>Computer Aided Verification</source>
          , volume
          <volume>2404</volume>
          <source>of LNCS</source>
          . Springer, March
          <year>2002</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <given-names>E. M.</given-names>
            <surname>Clarke</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Grumberg</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Peled</surname>
          </string-name>
          . Model Checking. The MIT Press,
          <year>1999</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <given-names>E. M.</given-names>
            <surname>Clarke</surname>
          </string-name>
          , Orna Grumberg, Somesh Jha, Yuan Lu, and
          <string-name>
            <given-names>Helmut</given-names>
            <surname>Veith</surname>
          </string-name>
          .
          <article-title>Counterexampleguided abstraction refinement</article-title>
          .
          <source>In Allen Emerson and A</source>
          . Prasad Sistla, editors,
          <source>Computer Aided Verification - (CAV'00)</source>
          , volume
          <volume>1855</volume>
          <source>of LNCS</source>
          , pages
          <fpage>154</fpage>
          -
          <lpage>169</lpage>
          . Springer,
          <year>2000</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4. Willem-Paul de Roever, Frank de Boer, Ulrich Hannemann, Jozef Hooman, Yassine Lakhnech, Mannes Poel, and
          <string-name>
            <given-names>Job</given-names>
            <surname>Zwiers</surname>
          </string-name>
          . Concurrency Verification:
          <article-title>Introduction to Compositional and Noncompositional Methods</article-title>
          . CUP,
          <year>2001</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <given-names>Dino</given-names>
            <surname>Distefano</surname>
          </string-name>
          ,
          <string-name>
            <surname>Peter O'Hearn</surname>
            ,
            <given-names>and Hongseok</given-names>
          </string-name>
          <string-name>
            <surname>Yang</surname>
          </string-name>
          .
          <article-title>A local shape analysis based on separation logic</article-title>
          .
          <source>In Holger Hermanns and Jens Palsberg</source>
          , editors,
          <source>TACAS</source>
          , volume
          <volume>3920</volume>
          <source>of LNCS</source>
          , pages
          <fpage>287</fpage>
          -
          <lpage>302</lpage>
          . Springer,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6.
          <string-name>
            <given-names>Alexey</given-names>
            <surname>Gotsman</surname>
          </string-name>
          , Byron Cook, Matthew Parkinson, and
          <string-name>
            <given-names>Viktor</given-names>
            <surname>Vafeiadis</surname>
          </string-name>
          .
          <article-title>Proving liveness properties of non-blocking data structures</article-title>
          .
          <source>Submitted to POPL</source>
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <given-names>S.</given-names>
            <surname>Graf</surname>
          </string-name>
          and
          <string-name>
            <given-names>H.</given-names>
            <surname>Saidi</surname>
          </string-name>
          .
          <article-title>Construction of abstract state graphs with PVS</article-title>
          . In Orna Grumberg, editor,
          <source>Proceedings of Computer Aided Verification (CAV '97)</source>
          , volume
          <volume>1254</volume>
          <source>of LNCS</source>
          , pages
          <fpage>72</fpage>
          -
          <lpage>83</lpage>
          . Springer-Verlag,
          <year>June 1997</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <string-name>
            <given-names>Arie</given-names>
            <surname>Gurfinkel</surname>
          </string-name>
          , Ou Wei, and
          <string-name>
            <given-names>Marsha</given-names>
            <surname>Chechik</surname>
          </string-name>
          .
          <article-title>Systematic construction of abstractions for modelchecking</article-title>
          . In E. Allen Emerson and Kedar S. Namjoshi, editors,
          <source>VMCAI</source>
          , volume
          <volume>3855</volume>
          <source>of LNCS</source>
          , pages
          <fpage>381</fpage>
          -
          <lpage>397</lpage>
          . Springer,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9.
          <string-name>
            <surname>Thomas</surname>
            <given-names>A.</given-names>
          </string-name>
          <string-name>
            <surname>Henzinger</surname>
            , Ranjit Jhala, Rupak Majumdar, and
            <given-names>Shaz</given-names>
          </string-name>
          <string-name>
            <surname>Qadeer</surname>
          </string-name>
          .
          <article-title>Thread-modular abstraction refinement</article-title>
          .
          <source>In Warren A. Hunt Jr. and Fabio</source>
          Somenzi, editors,
          <source>Computer-Aided Verification (CAV)</source>
          , volume
          <volume>2725</volume>
          <source>of LNCS</source>
          , pages
          <fpage>262</fpage>
          -
          <lpage>274</lpage>
          . Springer,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <string-name>
            <given-names>C. A. R.</given-names>
            <surname>Hoare</surname>
          </string-name>
          .
          <article-title>An axiomatic basis for programming</article-title>
          .
          <source>Communications of the ACM</source>
          ,
          <volume>12</volume>
          (
          <issue>10</issue>
          ):
          <fpage>576</fpage>
          -
          <lpage>580</lpage>
          ,
          <year>1969</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <string-name>
            <surname>Cliff</surname>
            <given-names>B.</given-names>
          </string-name>
          <string-name>
            <surname>Jones</surname>
          </string-name>
          .
          <article-title>Specification and design of (parallel) programs</article-title>
          .
          <source>In IFIP Congress</source>
          , pages
          <fpage>321</fpage>
          -
          <lpage>332</lpage>
          ,
          <year>1983</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12.
          <string-name>
            <surname>K. L. McMillan</surname>
          </string-name>
          .
          <article-title>Verification of infinite state systems by compositional model checking</article-title>
          . In Laurence Pierre and Thomas Kropf, editors,
          <source>Correct Hardware Design and Verification Methods</source>
          , volume
          <volume>1703</volume>
          <source>of LNCS</source>
          , pages
          <fpage>219</fpage>
          -
          <lpage>234</lpage>
          . Springer,
          <year>1999</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13.
          <string-name>
            <surname>K. L. McMillan</surname>
          </string-name>
          .
          <article-title>Parameterized verification of the FLASH cache coherence protocol by compositional model checking</article-title>
          . In Tiziana Margaria and Thomas F. Melham, editors,
          <source>Proceedings of the 11th International Conference on Correct Hardware Design and Verification Methods</source>
          , volume
          <volume>2144</volume>
          <source>of LNCS</source>
          , pages
          <fpage>179</fpage>
          -
          <lpage>195</lpage>
          . Springer,
          <year>2001</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14.
          <string-name>
            <surname>Maged</surname>
            <given-names>M.</given-names>
          </string-name>
          <string-name>
            <surname>Michael</surname>
            and
            <given-names>Michael L.</given-names>
          </string-name>
          <string-name>
            <surname>Scott</surname>
          </string-name>
          . Simple, fast, and
          <article-title>practical non-blocking and blocking concurrent queue algorithms</article-title>
          .
          <source>In PODC '96: Proceedings of the fifteenth annual ACM symposium on Principles of distributed computing</source>
          , pages
          <fpage>267</fpage>
          -
          <lpage>275</lpage>
          . ACM Press,
          <year>1996</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15.
          <string-name>
            <given-names>S.</given-names>
            <surname>Owicki</surname>
          </string-name>
          and
          <string-name>
            <given-names>D.</given-names>
            <surname>Gries</surname>
          </string-name>
          .
          <article-title>Verifying properties of parallel programs: an axiomatic approach</article-title>
          .
          <source>Commun. ACM</source>
          ,
          <volume>19</volume>
          (
          <issue>5</issue>
          ):
          <fpage>279</fpage>
          -
          <lpage>285</lpage>
          ,
          <year>1976</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16. H.
          <article-title>Sa¨ıdi. Model checking guided abstraction and analysis</article-title>
          . In Jens Palsberg, editor,
          <source>Proceedings of the 7th International Static Analysis Symposium</source>
          , volume
          <volume>1824</volume>
          <source>of LNCS</source>
          , pages
          <fpage>377</fpage>
          -
          <lpage>396</lpage>
          . Springer,
          <year>July 2000</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          17.
          <string-name>
            <given-names>Viktor</given-names>
            <surname>Vafeiadis</surname>
          </string-name>
          .
          <article-title>Modular fine-grained concurrency verification</article-title>
          .
          <source>PhD thesis</source>
          , University of Cambridge,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          18.
          <string-name>
            <given-names>Viktor</given-names>
            <surname>Vafeiadis</surname>
          </string-name>
          and
          <string-name>
            <given-names>Matthew J.</given-names>
            <surname>Parkinson</surname>
          </string-name>
          .
          <article-title>A Marriage of Rely/Guarantee and Separation Logic</article-title>
          .
          <source>In CONCUR</source>
          , volume
          <volume>4037</volume>
          <source>of LNCS</source>
          , pages
          <fpage>256</fpage>
          -
          <lpage>271</lpage>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>