leonardo de moura microsoft research verification
play

Leonardo de Moura Microsoft Research Verification/Analysis tools - PowerPoint PPT Presentation

Leonardo de Moura Microsoft Research Verification/Analysis tools need some form of Symbolic Reasoning Logic is The Calculus of Computer Science (Z. Manna). High computational complexity Test case generation Verifying Compilers


  1. a = b, b = c, d = e, b = s, d = t, v 3  v 4 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Unsatisfiable Congruence Rule: x 1 = y 1 , …, x n = y n implies f(x 1 , …, x n ) = f(y 1 , …, y n )

  2. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) Changing the problem a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Congruence Rule: x 1 = y 1 , …, x n = y n implies f(x 1 , …, x n ) = f(y 1 , …, y n )

  3. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Congruence Rule: x 1 = y 1 , …, x n = y n implies f(x 1 , …, x n ) = f(y 1 , …, y n )

  4. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Congruence Rule: x 1 = y 1 , …, x n = y n implies f(x 1 , …, x n ) = f(y 1 , …, y n )

  5. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 )  1  2  3  4 a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(a) = M(b) = M(c) = M(s) =  1 M(d) = M(e) = M(t) =  2 M(v 1 ) = M(v 2 ) =  3 M(v 3 ) = M(v 4 ) =  4

  6. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 )  1  2  3  4 a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Model construction: Missing: |M| = {  1 ,  2 ,  3 ,  4 } Interpretation for M(a) = M(b) = M(c) = M(s) =  1 f and g. M(d) = M(e) = M(t) =  2 M(v 1 ) = M(v 2 ) =  3 M(v 3 ) = M(v 4 ) =  4

  7. Building the interpretation for function symbols M(g) is a mapping from |M| to |M| Defined as: M(g)(  i ) =  j if there is v  g(a) s.t. M(a) =  i M(v) =  j =  k , otherwise (  k is an arbitrary element) Is M(g) well-defined?

  8. Building the interpretation for function symbols M(g) is a mapping from |M| to |M| Defined as: M(g)(  i ) =  j if there is v  g(a) s.t. M(a) =  i M(v) =  j =  k , otherwise (  k is an arbitrary element) Is M(g) well-defined? Problem: we may have v  g(a) and w  g(b) s.t. M(a) = M(b) =  1 and M(v) =  2 ≠  3 = M(w) So, is M(g)(  1 ) =  2 or M(g)(  1 ) =  3 ?

  9. Building the interpretation for function symbols M(g) is a mapping from |M| to |M| Defined as: This is impossible because of M(g)(  i ) =  j if there is v  g(a) s.t. the congruence rule! M(a) =  i a and b are in the same “ball” , M(v) =  j then so are v and w =  k , otherwise (  k is an arbitrary element) Is M(g) well-defined? Problem: we may have v  g(a) and w  g(b) s.t. M(a) = M(b) =  1 and M(v) =  2 ≠  3 = M(w) So, is M(g)(  1 ) =  2 or M(g)(  1 ) =  3 ?

  10. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 )  1  2  3  4 a,b,c,s d,e,t v 1 ,v 2 v 3, v 4 Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(a) = M(b) = M(c) = M(s) =  1 M(d) = M(e) = M(t) =  2 M(v 1 ) = M(v 2 ) =  3 M(v 3 ) = M(v 4 ) =  4

  11. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(g)(  i ) =  j if there is v  g(a) s.t. M(a) = M(b) = M(c) = M(s) =  1 M(a) =  i M(d) = M(e) = M(t) =  2 M(v) =  j M(v 1 ) = M(v 2 ) =  3 =  k , otherwise M(v 3 ) = M(v 4 ) =  4

  12. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(g)(  i ) =  j if there is v  g(a) s.t. M(a) = M(b) = M(c) = M(s) =  1 M(a) =  i M(d) = M(e) = M(t) =  2 M(v) =  j M(v 1 ) = M(v 2 ) =  3 =  k , otherwise M(v 3 ) = M(v 4 ) =  4 M(g) = {  2 →  3 }

  13. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(g)(  i ) =  j if there is v  g(a) s.t. M(a) = M(b) = M(c) = M(s) =  1 M(a) =  i M(d) = M(e) = M(t) =  2 M(v) =  j M(v 1 ) = M(v 2 ) =  3 =  k , otherwise M(v 3 ) = M(v 4 ) =  4 M(g) = {  2 →  3 }

  14. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(g)(  i ) =  j if there is v  g(a) s.t. M(a) = M(b) = M(c) = M(s) =  1 M(a) =  i M(d) = M(e) = M(t) =  2 M(v) =  j M(v 1 ) = M(v 2 ) =  3 =  k , otherwise M(v 3 ) = M(v 4 ) =  4 M(g) = {  2 →  3 , else →  1 }

  15. a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) Model construction: |M| = {  1 ,  2 ,  3 ,  4 } M(g)(  i ) =  j if there is v  g(a) s.t. M(a) = M(b) = M(c) = M(s) =  1 M(a) =  i M(d) = M(e) = M(t) =  2 M(v) =  j M(v 1 ) = M(v 2 ) =  3 =  k , otherwise M(v 3 ) = M(v 4 ) =  4 M(g) = {  2 →  3 , else →  1 } M(f) = { (  1 ,  3 ) →  4 , else →  1 }

  16. What about predicates? p(a, b),  p(c, b)

  17. What about predicates? p(a, b),  p(c, b) f p (a, b) = T, f p (c, b) ≠ T

  18. It is possible to eliminate function symbols using a method called Ackermannization . a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 d  e  v 1 = v 2 , a  v 1  b  v 2  v 3 = v 4

  19. It is possible to eliminate function symbols using a method called Ackermannization . a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 v 1  g(d), v 2  g(e), v 3  f(a, v 1 ) , v 4  f(b, v 2 ) a = b, b = c, d = e, b = s, d = t, a  v 4 , v 2  v 3 d  e  v 1 = v 2 , a  v 1  b  v 2  v 3 = v 4 Main Problem: quadratic blowup

  20. It is possible to implement our procedure in O(n log n)

  21. d,e,t Sets (equivalence classes)  d,e t = d,e,t Union a  s a,b,c,s Membership

  22. Key observation: d,e,t Sets (equivalence classes) The sets are disjoint!  d,e t = d,e,t Union a  s a,b,c,s Membership

  23. Union-Find data-structure Every set (equivalence class) has a root element (representative). root s a,b,c,s,r b r a c We say: find[c] is b

  24. Union-Find data-structure a,b,c,s,r s,r a,b,c  = s b s r b a c r a c

  25. Tracking the equivalence classes size is important!  a 1 a 2 a 3 = a 1 a 2 a 3  a 4 = a 1 a 2 a 3 a 4 a 1 a 2 a 3 …  a 1 a 2 a 3 … a n-1 a n = a 1 a 2 a 3 … a n-1 a n

  26. Tracking the equivalence classes size is important!  a 1 a 2 a 3 = a 1 a 2 a 3  a 4 = a 1 a 2 a 3 a 1 a 2 a 3 a 4 … a 2 a 2  = a n a n … … a 1 a n-1 a 3 a 1 a n-1 a 3

  27. Tracking the equivalence classes size is important! We can do n merges in  a 1 a 2 a 3 = a 1 a 2 a 3 O(n log n)  a 4 = a 1 a 2 a 3 a 1 a 2 a 3 a 4 … a 2 a 2  = a n a n … … a 1 a n-1 a 3 a 1 a n-1 a 3 Each constant has two fields: find and size.

  28. Implementing the congruence rule. Occurrences of a constant: we say a occurs in v iff v  f(…,a,…) When we “merge” two equivalence classes we can traverse these occurrences to find new congruences. s b  r a c occurrences[b] = { v 1  g(b), v 2  f(a) } occurrences[s] = { v 3  f(r) }

  29. Implementing the congruence rule. Occurrences of a constant: we say a occurs in v iff v  f(…,a,…) When we “merge” two equivalence classes we can traverse these occurrences to find new congruences. Inefficient version: s b  for each v in occurrences(b) for each w in occurrences(s) r a c if v and w are congruent occurrences(b) = { v 1  g(b), v 2  f(a) } add (v,w) to todo queue occurrences(s) = { v 3  f(r) } A queue of pairs that need to be merged.

  30. s b  r a c occurrences[b] = { v 1  g(b), v 2  f(a) } occurrences[s] = { v 3  f(r) } We also need to merge occurrences[b] with occurrences[s]. This can be done in constant time: Use circular lists to represent the occurrences. (More later) v 1 v 1  = v 3 v 3 v 2 v 2

  31. Avoiding the nested loop: for each v in occurrences[b] for each w in occurrences[s] … Use a hash table to store the elements v 1  f(a 1 , …, a n ). Each constant has an identifier (e.g., natural number). Compute hash code using the identifier of the (equivalence class) roots of the arguments. hash(v 1 ) = hash-tuple(id(f), id(root(a 1 )), …, id(root(a n )))

  32. Avoiding the nested loop: for each v in occurrences(b) for each w in occurrences(s) … Use a hash table to store the elements v 1  f(a 1 , …, a n ). hash-tuple can be the Jenkin’s hash function for strings. Each constant has an identifier (e.g., natural number). Just adding the ids produces a Compute hash code using the identifier of the (equivalence very bad hash-code! class) roots of the arguments. hash(v 1 ) = hash-tuple(id(f), id(root(a 1 )), …, id(root(a n )))

  33. Efficient implementation of the congruence rule. Merging the equivalences classes with roots: a 1 and a 2 Assume a 2 is smaller than a 1 Before merging the equivalence classes: a 1 and a 2 for each v in occurrences[a 2 ] remove v from the hash table (its hashcode will change) After merging the equivalence classes: a 1 and a 2 for each v in occurrences[a 2 ] if there is w congruent to v in the hash-table add (v,w) to todo queue else add v to hash-table

  34. Trick: Use dynamic arrays to represent the occurrences Efficient implementation of the congruence rule. Merging the equivalences classes with roots: a 1 and a 2 Assume a 2 is smaller than a 1 Before merging the equivalence classes: a 1 and a 2 for each v in occurrences[a 2 ] remove v from the hash table (its hashcode will change) After merging the equivalence classes: a 1 and a 2 for each v in occurrences[a 2 ] if there is w congruent to v in the hash-table add (v,w) to todo queue else add v to hash-table add v to occurrences(a 1 )

  35. The efficient version is not optimal (in theory). Problem: we may have v  f(a 1 , …, a n ) with “huge” n. Solution: currying Use only binary functions, and represent f(a 1 , a 2 ,a 3 ,a 4 ) as f(a 1 , h(a 2 , h(a 3 , a 4 ))) This is not necessary in practice, since the n above is small.

  36. Each constant has now three fields: find, size, and occurrences. We also has use a hash-table for implementing the congruence rule. We will need many more improvements!

  37. Many verification/analysis problems require: case-analysis x  0, y = x + 1, (y > 2  y < 1)

  38. Many verification/analysis problems require: case-analysis x  0, y = x + 1, (y > 2  y < 1) Naïve Solution: Convert to DNF (x  0, y = x + 1, y > 2)  (x  0, y = x + 1, y < 1)

  39. Many verification/analysis problems require: case-analysis x  0, y = x + 1, (y > 2  y < 1) Naïve Solution: Convert to DNF (x  0, y = x + 1, y > 2)  (x  0, y = x + 1, y < 1) Too Inefficient! (exponential blowup)

  40. Theory SAT SMT Solvers Equality + UF Arithmetic Case Analysis Bit-vectors …

  41. p  q, p   q,  p  q,  p   q

  42. p  q , Assignment: p   q , p = false,  p  q , q = false  p   q

Recommend


More recommend