u,v

advertisement
Formal verification of skiplist
algorithms
Student:
Trinh Cong Quy
Supervisor: Bengt Jonsson
Reviewer:
Parosh Abdulla
Outline
• Motivation
• Methodology
• Results and Future Work
Motivation
How do we verify skiplist algorithms? Why?
Why:
• Skiplists are important data structures, eg in databases, distributed
systems
• Verifying is complicated because skiplists are multi-pointers structures
• There is no previous work that formally verify skiplists algorithms
Our Motivation:
• Employ transitive closure logic to handle multi-pointers data
structures
• Introduce a method to discover and verify quantified invariants for
multi-pointers programs
• Apply such method to skiplist algorithms.
Skiplist
Skiplist is a list with a number of sorted single linked lists,
each linked list is located at a layer
head
tail
s
m
-∞
s
m
5
m
10
+∞
Properties:
Every single linked list at any layer is sorted accorrding
to node’s key values
List at higer layer is a sublist of list at lower layer
Example
Add(8)
s
sPred =
s
8
head
m
m
sSucc = mSucc
s
tail
s
mPred
m
-∞
m
5
m
10
+∞
How to verify program invariants
Assume that we have the invariant I of program P and
we want to verify it. We need to:
Annotate program P by computing assertions at program
points and then verify I at all assertions
Program Assertion
Assertion:
Assertion at each program point is a conjunction of atomic
predicates which are valid in that point and taken from
abstract domain
Example: P1: (x = y)  (y * z)  (x * t)
Abstract Domain:
Set of predicates P = { P1, …, Pn } given by users
Each predicate describes relations between program variables
Example
1.int insert(x)
Abstract Domain
2.{
head →* tail, head = pred
head →* tail
pred →* x, x →* tail
3. node* pred = head
head = pred ˄ head →* tail
4. pred.next := x
head = pred ˄ pred →* x
5. x.next := tail
?
}
How to get assertion for each program point?
Compute Post Assertion
Let A’ is successor of program point A, then its
assertion is obtained as below
• For each predicate P from the abstract domain
• If it is valid in A' that means if
post(A,S)  P
• Add P to the assertion
Here post(A,S) is post-condition which are program states
reached from A when we execute the statement S
Example
Abstract Domain
head →* tail, head = pred
For each predicate P from the
abstract domain
pred →* x, x →* tail
A.head = pred ˄ pred →* x
x.next := tail
A’.?
}
If it is valid in A' that means that if
post(A,S)  P
Add P to the assertion
Post(head = pred ˄ pred →* x, x.next := tail ) =
head = pred ˄ pred →* x ˄ x → tail
head = pred
ok
pred →* x:
ok
x →* tail:
ok
head →* tail:
ok
Assertion: head = pred ˄ pred →* x ˄ x →* tail
˄ head →* tail
Assertion Template for Skiplists
• Invariant:
u,v
 (P (u,v)  e (u,v))
i
i
• Assertion form at each program point
E  u,v
 (P (u,v)  e (u,v))
i
i
Where
♦ E: conjunction of atomic predicates valid at that point
♦ ei(u,v): an atomic predicate of u and v
♦ Pi(u,v): conjunction of atomic predicates of u and v
global variables
Example: E  u,v (u →m* v  u ≤ v)
Assertion Inferring
• Start with an empty list
• Run for a loop to insert and delete nodes randomlly
• For each loop iteration
Generate environments for program points
• When the loop is terminated , take intersection of
environments at the same program points.
• For each common environment:
Find minimal conjunction Pi (u,v) such that
Pi (u,v)  ei (u,v)
Example
1.int insert(x)
2.{
3.find(x, mPred,sPred,
mSucc,sSucc)
1.int insert(x)
2.{
3.find(x, mPred,sPred,
mSucc,sSucc)
head = mPred ˄ head = sPred ˄
tail = mSucc ˄ tail = sSucc
head →m mPred ˄ head →s sPred ˄
mSucc →m tail ˄ sSucc →s tail
4.node* n := Node(x,2)
5.n.mNext = mPred
6.mPred.mNext := n
7.n.sNext = sPred
8.mPred.mNext := n
4.node* n := Node(x,2)
5.n.mNext = mPred
6.mPred.mNext := n
7.n.sNext = sPred
8.mPred.mNext := n
head = mPred ˄ head = sPred ˄
tail = mSucc ˄ tail = sSucc ˄
mPred = sPred ˄ mSucc = sSucc ˄
head m mPred ˄ head s sPred ˄
mSucc m tail ˄ sSucc s tail
mPred = sPred ˄ mSucc = sSucc ˄
mPred →m* n ˄ n →m* mSucc ˄
sPred →s* n ˄ n →s* sSucc ˄
mPred < n ˄ n < mSucc ˄
sPred < n ˄ n < sSucc
mPred →m* n ˄ n →m* mSucc ˄
sPred →s* n ˄ n →s* sSucc ˄
mPred < n ˄ n < mSucc ˄
sPred < n ˄ n < sSucc
9.return 0
10.}
9.return 0
10.}
Example (cont)
Common environment at program point 9
head →m* mPred ˄ head →s* sPred ˄ mSucc →m* tail ˄ sSucc →s* tail ˄
mPred = sPred ˄ mSucc = sSucc ˄ mPred →m* n ˄ n →m* mSucc ˄
sPred →s* n ˄ n →s* sSucc ˄ mPred < n ˄ n < mSucc ˄ sPred < n ˄ n < sSucc
Invariant: u →s* v  u →m* v
Inductive Assertion
Assertion is inductive
 Holds at initial program points
 If it holds at a program point A, it also holds at A’s
sucssesor
Assertion Verifing
A
E  u,v
 (P (u,v)  e (u,v))
i
i
S
A’
E’  post(u,v
 (P (u,v)  e (u,v)))
i
i
• Is u,v  (Pi (u,v)  ei (u,v)) valid in A’
?
Assertion Verifing
• Check that:
E’
 u,v post( (Pi (u,v)  ei (u,v)))
 u,v
 (P (u,v)  e (u,v))
i
General Form: E’
i
 X (X)  X (Y)
Quantifier Instantiation
• To prove:
E’  X (X)  X (Y)
Using terms Y1, Y2,…., Yn that appear in E’
Expand as ψ (Y1)  … ψ (Yn)  ψ (Y)  (Y)
• If unsatisfiable, then so is quantified formula
• The approach is sound, but incomplete
Example
Assume that the invariant u,v (x →s* y  x →m* y) holds
in program point 8 of previous insert function.
Then we will show how to prove that its preserved in
program point 9
1.int insert(x)
2.{
3.find(x, mPred,sPred,mSucc,sSucc)
head = mPred ˄ head = sPred ˄ tail = mSucc ˄ tail = sSucc
4.node* n := Node(x,2)
5.n.mNext = mPred
6.mPred.mNext := n
7.n.sNext = sPred
8.mPred.mNext := n
head = mPred ˄ head = sPred ˄ tail = mSucc ˄ tail = sSucc ˄
mPred = sPred ˄ mSucc = sSucc ˄ mPred →m* n ˄ n →m* mSucc ˄ ˄ n < sSucc
sPred →s* n ˄ n →s* sSucc ˄ mPred < n ˄ n < mSucc ˄ sPred < n
9.return 0
10.}
Example(cont)
Program point 8
 = u →s* v  u →m* v = ˥(u →s* v) ˅ u →m* v
After statement: sPred.sNext := n
Program point 9
E’ = sPred m* n ˄ ......
 = ˥(u →s* v) ˅ (u →s* sPred ˄ n →s* v) ˅ u →m* v
Prove: E’  u,y (u,v)  u,v (u,v) <-> E’  u,y (u,v) ˄ ˥(u1, v1) is unsastifiable
(u1,sPred) = ˥(u1 →s* sPred) ˅ u1 →m* sPred
(n, v1)
= ˥(n →s* v1) ˅ n →m* v1
(u1, v1)
= ˥(u1 →s* v1) ˅ (u1 →s* sPred ˄ n →s* v1) ˅ u →m* v1
˥(u1, v1) = u1 →s* v1 ˄ ˥(u1 →m* v1)
E ˄ (u1, v1) ˄ ˥(u1, v1) ˄ (u1,sPred) ˄ (n, v1)
= u1 →m* sPred ˄ sPred →m* n ˄ n →m* v1 ˄ ˥(u1 →m* v1) ˄ (u1 →s* sPred ˄ n →s* v1)
contradiction
Results
• New method to infer and verify quantidied invariants of
multi-pointers structures
• Apply such method to skiplist algorithms, manually infer
and verify the invariant of the skiplist algorithm in the
paper:
A Simple Optimistic skip-list Algorithm
http://www.cs.brown.edu/~levyossi/Pubs/LazySkipList.p
df when we simplify it to two layers skiplist algorithm.
x,y(x →s* y  x →m* y)  (x →m* y  x ≠ y  x< y)
• This algorithm is concurrent, so we use thread modular
technique compute assertions but its not too important in
this thesis
Future Work
• Implement the framework
• Develop methods to refine abstract domain automatically
Thank You
Download