Title: Automated Verification of Concurrent Linked Lists with Counters
1Automated Verification of Concurrent Linked Lists
with Counters
- Tuba Yavuz-Kahveci and Tevfik Bultan
- Department of Computer Science
- University of California, Santa Barbara
- tuba,bultan_at_cs.ucsb.edu
- http//www.cs.ucsb.edu/bultan/composite
2General Problem
- Concurrent programming is difficult and error
prone - Sequential programming states of the variables
- Concurrent programming states of the variables
and the processes - Linked list manipulation is difficult and error
prone - States of the heap possibly infinite
- We would like to guarantee properties of a
concurrent linked list implementation
3More Specific Problem
- There has been work on verification of concurrent
systems with integer variables (and linear
constraints) - Bultan, Gerber and Pugh, TOPLAS 99
- Delzanno and Podelski STTT01
- Use widening based on earlier work of Cousot and
Halbwachs POPL 77 on analyzing programs with
integer variables - There has been work on verification of
(concurrent) linked lists - Yahav POPL01
- What can we do for concurrent systems
- where both integer and heap variables influence
the control flow, - or the properties we wish to verify involve both
integer and heap variables?
4Our Approach
- Use symbolic verification techniques
- Use polyhedra to represent the states of the
integer variables - Use BDDs to represent the states of the boolean
and enumerated variables - Use shape graphs to represent the states of the
heap - Use composite representation to combine them
- Use forward-fixpoint computations to compute
reachable states - Truncated fixpoint computations can be used to
detect errors - Over-approximation techniques can be used to
prove properties - Polyhedra widening
- Summarization in shape graphs
5Action Language Tool Set
Action Language Specification of the
Concurrency Component
Action Language Parser
Composite Symbolic Library
Code Generator
Omega Library
CUDD Package
MONA
Verified code (Java monitor classes)
6Outline
- Specification of concurrent linked lists
- Action Language
- Symbolic verification
- Composite representation
- Approximation techniques
- Summarization
- Widening
- Counting abstraction
- Experimental results
- Related Work
- Conclusions
7Action Language Bultan ICSE00 Yavuz-Kahveci,
Bultan ASE01
- A state based language
- Actions correspond to state changes
- States correspond to valuations of variables
- Integer (possibly unbounded), heap, boolean and
enumerated variables - Parameterized constants are allowed
- Transition relation is defined using actions
- Atomic actions Predicates on current and next
state variables - Action composition synchronous () or
asynchronous () - Modular
- Modules can have submodules
- Properties to be verified
- Invariant(p) p always holds
8Composite Formulas State Formulas
- We use state formulas to express the properties
we need to check - No primed variables in state formulas
- State formulas are boolean combination (?, ?,
?,?,?) of integer, boolean and heap formulas - numItemsgt2 gt top.next!null
integer formula
heap formula
9State formulas
- Boolean formulas
- Boolean variables and constants (true, false)
- Relational operators , ?
- Boolean connectives (?, ?, ?,?,?)
- Integer formulas (linear arithmetic)
- Integer variables and constants
- Arithmetic operators ,-, and with a constant
- Relational operators , ?, gt , lt, ?, ?
- Boolean connectives (?, ?, ?,?,?)
- Heap formulas
- Heap variable, heap-variable.selector, heap
constant null - Relational operators , ?
- Boolean connectives (?, ?, ?,?,?)
10Composite Formulas Transition Formulas
- We use transition formulas to express the actions
- In transition formulas primed-variables denote
the next-state values, unprimed-variables denote
the current-sate values - pcchecknull and numItems0 and topadd and
add.nextnull and - numItems1 and pccreate and mutex
current state variables
next state variables
11Transition Formulas
- Transition formulas are in the form
- boolean-formula ? integer-formula ?
heap-transition-formula - Heap transition formulas are in the form
- guard-formula ? update-formula
- A guard formula is a conjunction of terms in the
form - id1 id2 id1 ? id2
- id1.f id2 id1.f ? id2
- id1.f id2.f id1.f ? id2.f
- id1 null id1 ? null
- id1.f null id1.f ? null
- An update formula is a conjunction of terms in
the form - id1 id2 id1 id2.f
- id1.f id2 id1.f id2.f
- id1 null id1.f null
- id1 new id1.f new
12Stack Example
Variable declarations define the state space of
the system
- module main()
- heap next top, add, get, newTop
- boolean mutex
- integer numItems
-
- initial topnull and mutex and numItems0
- module push()
-
- enumerated pc create, checknull,updateTop
-
- initial pccreate and addnull
-
- push1 pccreate and mutex and !mutex and
addnew and - pcchecknull
- push2 pcchecknull and topnull and topadd
and add.nextnull - and numItems'1 and pccreate and mutex
- push3 pcchecknull and top!null and
add.nexttop and - pcupdateTop
Predicates defining the initial states
Atomic actions primed variables denote next sate
variables
Transition relation of the push module is defined
as asynchronous composition of its atomic actions
13Stack (Contd)
- module pop()
- enumerated pc copyTopNext, getTop, updateTop
- initial pccopyTopNext and getnull and
newTopnull - pop1 pccopyTopNext and mutex and top!null
and - newToptop.next and !mutex and pcgetTop
- pop2 pcgetTop and gettop and pcupdateTop
- pop3 pcupdateTop and topnewTop and mutex
- and numItemsnumItems-1 and pccopyTopNext
- pop pop1 pop2 pop3
- endmodule
-
- main pop() pop() push() push()
-
- spec invariant(numItems0 gt topnull)
- spec invariant(numItemsgt2 gt top-gtnext!null)
- endmodule
Transition relation of main defined as
asynchronous composition of two pop and two push
processes
Invariants to be verified
14Stack (with integer guards)
-
- module main()
- heap next top, add, get, newTop
- boolean mutex
- integer numItems
- initial topnull and mutex and numItems0
- module push()
- enumerated pc create, checknull,updateTop
- initial pccreate and addnull
- push1 pccreate and mutex and !mutex and
addnew and pcchecknull -
- push2 pcchecknull and numItems0 and topadd
and add.nextnull and numItems1 and pccreate
and mutex -
- push3 pcchecknull and numItemsgt0 and
add.nexttop and pcupdateTop -
- push4 pcupdateTop and topadd and
numItemsnumItems1 and mutex and
pccreate - push push1 push2 push3 push4
- endmodule
-
15Outline
- Specification of concurrent linked lists
- Action Language
- Symbolic verification
- Composite representation
- Approximation techniques
- Summarization
- Widening
- Counting abstraction
- Experimental results
- Related Work
- Conclusions
16Symbolic Verification Forward Fixpoint
- Forward fixpoint for the reachable states can be
computed by iteratively manipulating symbolic
representations - We need forward-image (post-condition), union,
and equivalence check computations - ReachableStates(I Set of initial states,
- T Transition relation)
- RS I
- repeat
- RSold RS
- RS RSold ? forwardImage(RSold, T)
- until (RSold RS)
-
17Symbolic Verification Symbolic Representations
- Use a symbolic representation for the sets of
states - A boolean logic formula (stored as a BDD)
represents the sets of states of the boolean
variables - pccreate ? mutex
- An arithmetic constraint (stored as polyhedra)
represents the sets of states of integer
variables - numItemsgt0
- Shape graphs are used to represent the sates of
the heap variables and the heap
18Composite Representation
- Each variable type is mapped to a symbolic
representation type - Boolean and enumerated types ? BDD representation
- Integer variables ? Polyhedra
- Heap variables ? Shape graphs
- Each conjunct in a transition formula operates on
a single symbolic representation - Composite representation A disjunctive
representation to combine different symbolic
representations - Union, equivalence check and forward-image
computations are performed on this disjunctive
representation
19Composite Representation
- A composite representation A is a disjunction
-
-
- where
- n is the number of composite atoms in A
- t is the number of basic symbolic representations
- Each composite atom is a conjunction
- Each conjunct corresponds to a different symbolic
representation
20Composite Representation Example
A list of shape graphs
BDD
A list of polyhedra
?
?
pccreate ? mutex
numItems2
?
add
top
?
?
pccheckNull ? ?mutex
numItems2
?
add
top
?
?
pcupdateTop ? ?mutex
numItems2
?
add
top
?
?
pccreate ? mutex
numItems3
21Composite Symbolic Library Yavuz-Kahveci,
Tuncer, Bultan TACAS01, Yavuz-Kahveci, Bultan
STTT02
- Our library implements this approach using an
object-oriented design - A common interface is used for each symbolic
representation - Easy to extend with new symbolic representations
- Enables polymorphic verification
- As a BDD library we use Colorado University
Decision Diagram Package (CUDD) Somenzi et al - As an integer constraint manipulator we use Omega
Library Pugh et al - For encoding the states of the heap variables and
the heap we use shape graphs encoded as BDDs
(using CUDD)
22Composite Symbolic Library Class Diagram
Symbolic
- union()
- isSatisfiable()
- isSubset()
- forwardImage()
-
BoolSym
HeapSym
IntSym
representation BDD
representation list of ShapeGraph
representation list of Polyhedra
CUDD Library
OMEGA Library
23Satisfiability Checking for Composite
Representation
is
- boolean isSatisfiable(CompSym A)
- for each compAtom a in A do
- if a is satisfiable then
- return true
- return false
- boolean isSatisfiable(compAtom a)
- for each symbolic representation t do
- if at is not satisfiable then
- return false
- return true
Satisfiable?
isSatisfiable?
isSatisfiable?
or
is
is
is
is
and
and
?
Satisfiable?
Satisfiable?
Satisfiable?
Satisfiable?
24Forward Image for Composite Representation
R
A
- CompSym forwardImage(Compsym A,
-
transitionRelation R) - CompSym C
- for each compAtom a in A do
- for each atomic action r in R do
- insert forwardImage( a,r ) into C
- return C
-
C
25Forward Image for Composite Atom
- compAtom forwardImage(compAtom a, atomic action
r) - for each symbolic representation type t do
- replace at by forwardImage(at , rt )
- return a
r
a
26Forward-Image Computation Example
add
top
?
?
pcupdateTop ? ?mutex
numItems2
27ForwardFixpoint Computation (Repeatedly Applies
Forward-Image)
add
top
?
?
pccreate ? mutex
numItems0
28(No Transcript)
29?
. . .
30Forward-Fixpoint does not Converge
- We have two reasons for non-termination
- integer variables can increase without a bound
- the number of nodes in the shape graphs can
increase without a bound - The state space is infinite
- Even if we ignore the heap variables,
reachability is undecidable when we have
unbounded integer variables - So, we use conservative approximations
31Outline
- Specification of concurrent linked lists
- Action Language
- Symbolic verification
- Composite representation
- Approximation techniques
- Summarization
- Widening
- Counting Abstraction
- Experimental results
- Related Work
- Conclusions
32Conservative Approximations
- To verify or falsify a property p
- Compute a lower ( RS ? ) or an upper ( RS )
approximation to the set of reachable states - There are three possibilities
33Conservative Approximations
34Computing Upper and Lower Bounds for Reachable
States
- Truncated fixpoint computation
- To compute a lower bound for a least-fixpoint
computation - Stops after a fixed number of iterations
- Widening
- To compute an upper bound for the least-fixpoint
computation - We use a generalization of the polyhedra widening
operator by Cousot and Halbwachs POPL77 - Summarization
- Generate heap nodes in the shape graphs which
represent more than one concrete node - Materialization we need to generate concrete
nodes from the summary nodes when needed
35Summarization
- The nodes mapped to a summary node form a chain
- No heap variable points to any concrete node that
is mapped to a summary node - Each concrete node mapped to a summary node is
only pointed by one pointer - During summarization, we also introduce an
integer variable which counts the number of
concrete nodes mapped to a summary node
...
36Summarization Example
add
top
?
?
pccreate ? mutex
numItems3
37Summarization
- Summarization guarantees that the number of
different shape graphs that can be generated are
finite - However, the summary-counts can still increase
without a bound - We use polyhedral widening operation to force the
fixpoint computation to convergence
38Lets Continue the Forward-fixpoint
?
add
top
numItems3 ? summaryCount2
?
pccreate ? mutex
?
39Summarization
add
top
?
numItems4 ? summaryCount2
pccreate ? mutex
?
40Simplification
- After each fixpoint iteration we try to merge as
many composite atoms as possible - For example, following composite atoms can be
merged
add
top
numItems3 ? summaryCount2
?
pccreate ? mutex
?
add
top
?
numItems4 ? summaryCount3
pccreate ? mutex
?
41Simplification
add
top
numItems3 ? summaryCount2
?
pccreate ? mutex
?
?
add
top
?
numItems4 ? summaryCount3
pccreate ? mutex
?
42Simplification on the integer part
add
top
?
- (numItems4
- summaryCount3
- numItems3
- ? summaryCount2)
pccreate ? mutex
?
43Widening
- Forward-fixpoint computation still will not
converge since numItems and summaryCount keep
increasing without a bound - We use the widening operation
- Given two composite atoms c1 and c2 in
consecutive fixpoint iterates, assume that - c1 b1 ? i1 ? h1
- c2 b2 ? i2 ? h2
- where b1 b2 and h1 h2 and i1 ? i2
- Also assume that i1 is a single polyhedron (i.e.
a conjunction of arithmetic csontraints) and i2
is also a single polyhedron
44Widening
- Then
- i1 ? i2 is defined as all the constraints in i1
which are also satisfied by i2 - Replace i2 with i1 ? i2 in c2
- This gives a majorizing sequence to the
forward-fixpoint computation
45Widening Example
add
top
?
?
pccreate ? mutex
- numItemssummaryCount1
- 3 ? numItems
- numItems ? 4
?
add
?
?
top
pccreate ? mutex
- numItemssummaryCount1
- 3 ? numItems
- numItems ? 5
46Dealing with Arbitrary Number of Processes
- Use counting abstraction Delzanno CAV00
- Create an integer variable for each local state
of a process - Each variable will count the number of processes
in a particular state - Local states of the processes have to be finite
- Shared variables of the monitor can be unbounded
- Counting abstraction can be automated
47Stack After Counting Abstraction
Variables for counting the number of processes in
each state
- module main()
- heap top, add, get, newTop
- boolean mutex
- integer numItems
- integer CreateC, ChecknullC,UpdateTopC
- parameterized integer numProcesses
- initial topnull and mutex and numItems0 and
CreateCnumProcesses and ChecknullC0
and - UpdateTopC0
- restrict numProcessesgt0
- module push()
- //enumerated pc create, checknull,updateTop
- initial addnull
- push1 CreateCgt0 and mutex and !mutex' and
add'new and CreateC'CreateC-1 and
ChecknullC'ChecknullC1 - push2 ChecknullCgt0 and topnull and top'add
and add'-gtnextnull and numItems'1 and
ChecknullC'ChecknullC-1 and
CreateC'CreateC1 and mutex' - push3 ChecknullCgt0 and top!null and
add'-gtnexttop and
ChecknullC'ChecknullC-1 and UpdateTopC'UpdateTop
C1 push4 UpdateTopCgt0 and top'add and
numItems'numItems1 and mutex' and
UpdateTopC'UpdateTopC-1 and CreateC'CreateC1
- push push1 push2 push3 push4
- endmodule
Parameterized constant representing the number of
processes
Initialize initial state counter to the number
of processes. Initialize other states to 0.
When local state changes, decrement current local
state counter and increment next local state
counter
48Verified Properties
SPECIFICATION VERIFIED INVARIANTS
Stack topnull ? numItems0
top?null ? numItems?0
numItems2 ? top.next ?null
Single Lock Queue headnull ? numItems0
head?null ? numItems?0
(headtail ? head ?null) ? numItems1
head?tail ? numItems?0
Two Lock Queue numItemsgt1 ? head?tail
numItemsgt2 ? head.next?tail
49Experimental Results - Verification Times
Number of Processes Queue HC Queue IC Stack HC Stack IC 2Lock Queue HC 2Lock Queue IC
1P-1C 10.19 12.95 4.57 5.21 60.5 58.13
2P-2C 15.74 21.64 6.73 8.24 88.26 122.47
4P-4C 31.55 46.5 12.71 15.11 ? ?
1P-PC 12.85 13.62 5.61 5.73 ? ?
PP-1C 18.24 19.43 6.48 6.82 ? ?
50Related Work
- There is a lot of work on Shape analysis, I will
just mention the ones which directly influenced
us - Sagiv,Reps, Wilhelm TOPLAS98, Dor, Rodeh,
Sagiv SAS00 - Verification of concurrent linked lists with
arbitrary number of processes in Yahav POPL01 - Lev-Ami, Reps, Sagiv, Wilhelm ISSTA 00 use
3-valued logic and instrumentation predicates to
verify properties that cannot be expressed in our
framework, however, our approach does not require
instrumentation predicates - Deutch used integer constraint lattices to
compute aliasing information using symbolic
access paths Deutch PLDI94 - Use of BDDs goes back to symbolic model checking
McMillan93 and verification with arithmetic
constraints goes back to Cousot and Halbwachs77
51Conclusions and Future Work
- One of the weakness of the summarization
algorithm we used is the fact that it only works
on singly linked lists - We need to find a more general summarizaton
algorithm which counts the number of summary
nodes - Implementation is not efficient, we are working
on improving the performance - Liveness properties?
- We would like to do full CTL model checking
- Need to implement the backward image computation
52APPENDIX
53Action Language Verifier
- An infinite state symbolic model checker
- Composite representation
- uses a disjunctive representation to combine
different symbolic representations - Computes fixpoints by manipulating formulas in
composite representation - Heuristics to ensure convergence
- Widening collapsing
- Loop closure
- Approximate reachable states
54Readers Writers Monitor in Action Language
- module main()
- integer nr
- boolean busy
- restrict nrgt0
- initial nr0 and !busy
- module Reader()
- boolean reading
- initial !reading
- rEnter !reading and !busy and
- nrnr1 and reading
- rExit reading and !reading and nrnr-1
- Reader rEnter rExit
- endmodule
- module Writer()
- boolean writing
- initial !writing
- wEnter !writing and nr0 and !busy and
- busy and writing
- wExit writing and !writing and !busy
55Action Language Verifier
- An infinite state symbolic model checker
- Uses composite symbolic representation to encode
a system defined by (S,I,R) - S set of states, I set if initial states, R
transition relation - Maps each variable type to a symbolic
representation type - Maps boolean and enumerated types to BDD
representation - Maps integer type to arithmetic constraint
representation - Uses a disjunctive representation to combine
symbolic representations - Each disjunct is a conjunction of formulas
represented by different symbolic representations
56Conjunctive Decomposition
- Each composite atom is a conjunction
- Each conjunct corresponds to a different symbolic
representation - x integer y boolean h heap
- xgt0 and xx1 and y?y
- Conjunct xgt0 and x?x1 will be represented by
arithmetic constraints - Conjunct y?y will be represented by a BDD
- Advantage Image computations can be distributed
over the conjunction (i.e., over different
symbolic representations).
57BDDs
- Efficient representation for boolean functions
- Disjunction, conjunction complexity at most
quadratic - Negation complexity constant
- Equivalence checking complexity constant or
linear - Image computation complexity can be exponential
58Arithmetic Constraint-Based Verification
- Can we use linear arithmetic constraints as a
symbolic representation? - Required functionality
- Disjunction, conjunction, negation, equivalence
checking, existential variable elimination - Advantages
- Arithmetic constraints can represent infinite
sets - Heuristics based on arithmetic constraints can be
used to accelerate fixpoint computations - Widening, loop-closures
59Linear Arithmetic Constraints
- Disjunction complexity linear
- Conjunction complexity quadratic
- Negation complexity can be exponential
- Because of the disjunctive representation
- Equivalence checking complexity can be
exponential - Uses existential variable elimination
- Image computation complexity can be exponential
- Uses existential variable elimination
60Linear Arithmetic Constraints
- Can be used to represent sets of valuations of
unbounded integers - Linear integer arithmetic formulas can be stored
as a set of polyhedra - where each ckl is a linear equality or
inequality constraint and each - is a polyhedron
61A Linear Arithmetic Constraint Manipulator
- Omega Library Pugh et al.
- Manipulates Presburger arithmetic formulas First
order theory of integers without multiplication - Equality and inequality constraints are not
enough Divisibility constraints are also needed
(a variable is divisible by a constant) - Existential variable elimination in Omega
Library Extension of Fourier-Motzkin variable
elimination to integers - Eliminating one variable from a conjunction of
constraints may double the number of constraints - Integer variables complicate the problem even
further
62Fourier-Motzkin Variable Elimination
- Given two constraints ? ? bz and az ? ? we have
- a? ? abz ? b?
- We can eliminate z as
- ?z . a? ? abz ? b? if and only if a? ? b?
- Every upper and lower bound pair can generate a
separate constraint, the number of constraints
can double for each eliminated variable
real shadow
63Integers are More Complicated
- If z is integer
- ?z . a? ? abz ? b? if a? (a - 1)(b - 1) ?
b? - Remaining solutions can be characterized using
periodicity constraints in the following form - ?z . ? i bz
dark shadow
64Consider the constraints
?y . 0 ? 3y x ? 7 ? 1? x 2y ? 5
We get the following bounds for y
2x ? 6y
6y ? 2x 14
6y ? 3x - 3
3x - 15 ? 6y
When we combine 2 lower bounds with 2 upper
bounds we get four constraints
0 ? 14 , 3 ? x , x ? 29 , 0 ? 12
Result is 3 ? x ? 29
65y
x 5 ? 2y
2y ? x 1
x ? 3y
3y ? x 7
29
3
x
dark shadow
real shadow
66Temporal Properties ? Fixpoints
backwardImage of ?p
Backward fixpoint
Initial states
?p
initial states that violate Invariant(p)
states that can reach ?p i.e., states that
violate Invariant(p)
Invariant(p)
Forward fixpoint
Initial states
?p
reachable states that violate p
reachable states of the system
forward image of initial states
67Simplification Example
(y ? z z 1)
(x ? z z 1)
((x ? y) ? z gt z)
?
?
?
?
((x ? y) ? z ? z)
?
68Polymorphic Verifier
- Symbolic TranSyscheck(Node f)
-
-
-
- Symbolic s check(f.left)
- case EX
- s.backwardImage(transRelation)
- case EF
- do
- snew s
- sold s
- snew.backwardImage(transRelation)
- s.union(snew)
- while not sold.isEqual(s)
-
-
-
? Action Language Verifier is polymorphic ? When
there are no integer variable it becomes a BDD
based model checker