230 likes | 348 Views
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:
E N D
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 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 head tail s s m m m -∞ 5 10 +∞
Example Add(8) s s 8 m sPred = head sSucc = mSucc tail m s s mPred m m m -∞ 5 10 +∞
How to verify program invariants Assume that we have the invariant I of program P andwewant to verify it. We need to: AnnotateprogramPby computingassertionsat program points and then verifyIat 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 For each predicate P from the abstract domain If it is valid in A' that means that if post(A,S) P Add P to the assertion Abstract Domain head →* tail, head = pred pred →* x, x →* tail A.head = pred ˄ pred→* x x.next := tail A’.? } head = pred ok pred→* x: ok x→* tail: ok head→* tail: ok Post(head = pred ˄ pred →* x, x.next := tail ) = head = pred ˄ pred →* x ˄ x→tail Assertion: head = pred ˄ pred→* x ˄ x→* tail ˄ head →* tail
Assertion Template for Skiplists • Invariant: u,v (Pi (u,v) ei(u,v)) • Assertion form at each program point E u,v(Pi (u,v) ei(u,v)) 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) • 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 • 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 • 9.return 0 • 10.} 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˄ sPred →s* n ˄ n →s*sSucc˄ mPred < n ˄ n < mSucc ˄ sPred < n ˄ n < sSucc 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 • Isu,v(Pi (u,v) ei(u,v)) valid in A’ ? E u,v (Pi (u,v) ei(u,v)) A S E’ post(u,v (Pi (u,v) ei(u,v))) A’
Assertion Verifing • Check that: E’u,vpost( (Pi (u,v) ei(u,v))) u,v (Pi (u,v) ei(u,v)) General Form: E’ 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 E’ = sPredm* n ˄ ...... Program point 9 = ˥(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.pdf 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