Lifting Abstract Interpreters to Quantified Logical Domains

Lifting Abstract Interpreters to
Quantified Logical Domains
Sumit Gulwani, MSR
Bill McCloskey, UCB
Ashish Tiwari, SRI
1
Motivating Example
a[0] = 0;
for (i=1; i<n; i++) a[i] = 0;
Postcondition:
i  n  a[0] = 0
 k (0 ≤ k < i  a[k] = 0)
2
How Are Quantifiers Useful?
• Reasoning about arrays
– k (0 ≤ k < STRLEN(s)  s[k]  '!')
– j, k (0 ≤ j < k < n  a[j] ≤ a[k])
Security properties
Sorting
• Reasoning about pointer-based data structures
u
R(u, v)
v
– u (R(hd, u)  R(u, tl)  udata = 0) means list is
initialized from hd to tl
3
What Do Quantifiers Look Like?
k ( 0 ≤ k < n  a[k] = 0 )
Typically see
only universal
quantifiers
Comes from
Belongs to another
some domain,
domain, e.g. equality of
e.g. linear arithmetic uninterpreted functions
• Goal: Create a universally quantified domain
parameterized by base domains
– Take advantage of existing domains, transfer functions
Quantifier-Free Domain
Quantified Domain
4
Universally Quantified Domain
Domain Element Definition
A  V1.(B1  C1)  ...  Vn.(Bn  Cn)
Partial Order Definition
A  V.(B  C) v A'  V.(B'  C')
if 1. A v A'
A  C v C'
2.
V.(B  C)
V. (B'  C')
A  B' v B
5
Transfer Function Example
true
A[0] := 0; i := 1
i?= 1  A[0] = 0
i = 2  A[0] = ?
0  A[1] = 0
i?= 1  A[0] = 0
i<n
T
F
i = 1  A[0] =?0
?
A[i] := 0; i := i+1
6
Transfer Function Example
true
A[0]
:= 0; i := 1
Join Algorithm
i = 2  A[0] = 0  A[1] = 0
i =i =1 1 A[0]
A[0]= =0 0
A[0]
A[0]
i i==i2=11A[0]
==0=00 A[1] = 0
i = 1  A[0] = 0
i = 1  A[0] = 0
i <i <nn
TT
FF
1  i  2  A[0] = 0
i = 1  A[0] = 0
?
A[i] := 0; i := i+1
7
Transfer Function Example
true
A[0]
:= 0; i := 1
Join Algorithm
i =i =11A[0]
A[0]==00
i = 2 i =A[0]
0  =A[1]
1  =A[0]
0 = 0 i = 2  A[0] = 0  A[1] = 0
i =i =11A[0]
A[0]==00
1 = 0
i=2
i = 1 i =A[0]
k(k = 0  A[k] = 0) i <
i <k(0
nn  k  1  A[k] = 0)
TT
FF
i = 1  A[0] = 0
1  i  2  k(0  k < i  A[k] = 0)
?
A[i] := 0; i := i+1
8
Transfer Function Example
true
A[0] := 0; i := 1
2in 
k(0  k < i  A[k] = 0)
i = 1  k(k = 0  A[k] = 0)
1  i  k(0  k < i  A[k] = 0)
i<n
T
1i<n
k(0  k < i  A[k] = 0)
F
in 
k(0  k < i  A[k] = 0)
A[i] := 0; i := i+1
9
Outline
• Join Algorithm
– Quantifier introduction
– Joining quantifiers
• Experiments
• Conclusion
10
Quantifier Introduction
• Quantified facts are drawn from standard facts in A
b[0] = 0
k (k = 0  b[k] = 0)
b[0] ≤ b[1]
j, k (j = 0  k = 1  b[j] ≤ b[k])
• User gives set of templates to guide quantification
Env fact
b[0] = 0
b[0] ≤ b[1]
Template
Quantified fact (result)
A[*] = c
k(k = 0  b[k] = 0)
A[*] ≤ A[*]
j, k (j = 0  k = 1  b[j] ≤ b[k])
• Experiments show that few templates are needed
11
Outline
• Join Algorithm
– Quantifier introduction
– Joining quantifiers
• Experiments
• Conclusion
12
Transfer Function Example
true
A[0]
:= 0; i := 1
Join Algorithm
i =i =11A[0]
A[0]==00
i = 2 i =A[0]
0  =A[1]
1  =A[0]
0 = 0 i = 2  A[0] = 0  A[1] = 0
i =i =11A[0]
A[0]==00
1 = 0
i=2
i = 1 i =A[0]
k(k = 0  A[k] = 0) i <
i <k(0
nn  k  1  A[k] = 0)
TT
FF
i = 1  A[0] = 0
1  i  2  k(0  k < i  A[k] = 0)
?
A[i] := 0; i := i+1
13
Joining Quantifiers
• Goal: (AL  V.(BL  CL)) t (AR  V. (BR  CR))
• Result must be above both inputs in v, so:
– AL  V.(BL  CL) v A  V.(B  C)
– AR  V. (BR  CR) v A  V.(B  C)
• Based on v definition:
1. AL v A and AR v A so A = AL t AR
2.
AL  C L v C
V.(BL  CL)
AR  C R v C
V. (B  C)
AL  B v BL
V.(BR  CR)
AR  B v BR
14
Joining Quantifiers
AL  C L v C
V.(BL  CL)
AR  C R v C
V. (B  C)
AL  B v B L
V.(BR  CR)
AR  B v BR
• C = (AL  CL) t (AR  CR)
• Rewriting for B:
B v AL  BL and B v AR  BR
or, B v AL  BL and B v AR  BR
• Best solution for B = (AL  BL)  (AR  BR)
• If it's not in domain, pick best under-approximation
15
Under-Approximation Example
• Compute (i = 1  k = 0)  (i = 2  0  k  1) in LA
• 1st step: guess an over-approximation of the answer
(i = 1  k = 0) t (i = 2  0  k  1)
= (1  i  2  0  k < i)
Many details skipped.
See paper!
• 2nd step: Check if (0  k < i) is correct; refine if not
(0  k < i) 
(i = 1  k = 0)  (i = 2  0  k  1)
?
YES
16
Outline
• Join Algorithm
– Quantifier introduction
– Joining quantifiers
• Experiments
• Conclusion
17
Experiments
 Time (s)
Ratio to base
# Tmpls
Invariant: a[k] = b[k]
Array initialization
3.2 s
2.1x
1
all k
C main() argumentfor
scan
4.1 s
2.1x
1
Array copy
5.5 s
2.5x
1
Array copy (start with non-zero elements)
11.3 s
1.7x
1
Array copy (only copy positive elements)
12.0 s
2.0x
1
Find element in array
24.6 s
3.0x
1
Partition array into zero/non-zero parts
73.0 s
3.2x
2
Insertion sort inner loop
35.9 s
18x
3
Quicksort inner loop
42.2 s
9.4x
3
Selection sort inner loop
59.2 s
7.3x
3
334.1 s
4.5x
3
Linked list remove
20.5 s
14.6x
1
Linked list insert
23.9 s
17.1x
1
Linked list initialization
24.5 s
12.9x
1
Linked list creation
42.0 s
12.4x
1
Procedure
Invariant: All data
fields of list are zero
Merge sort inner loop
Quantified Domain Construction Works!
Base domain D
• partial order
• transfer functions
Under-approximation operators
for D (optional)
Underapproximation
Quantified domain Q
• 3x slowdown relative to D
• transfer functions relatively complete
19