SLIDE 1 Non-Linear Reasoning for Invariant Synthesis
Zachary Kincaid1 John Cyphert2 Jason Breck2 Thomas Reps2,3
1Princeton University 2University of Wisconsin-Madison 3GrammaTech, Inc
January 12, 2018 @ 15:50
SLIDE 2 The problem: generating non-linear numerical loop invariants
- Resource-bound analysis
- Side channel analysis
- Secure information flow
- ...
SLIDE 3 Loop analyzer Recurrence solver while(i < n): x = x + i i = i + 1
i(k) = i(0) + k x(k) = x(0) + k(k − 1) 2 + ki(0) i(k) = i(k−1) + 1 x(k) = x(k−1) + i(k−1) ∃k.k ≥ 0 ∧ ( i′ = i + k x′ = x + k(k − 1) 2 + ki )
- branching
- nested loops
- non-determinism
algebraic numbers
SLIDE 4 Loop analyzer Recurrence solver while(i < n): x = x + i i = i + 1
i(k) = i(0) + k x(k) = x(0) + k(k − 1) 2 + ki(0) i(k) = i(k−1) + 1 x(k) = x(k−1) + i(k−1) ∃k.k ≥ 0 ∧ ( i′ = i + k x′ = x + k(k − 1) 2 + ki )
- branching
- nested loops
- non-determinism
algebraic numbers
SLIDE 5 Loop analyzer Recurrence solver while(i < n): x = x + i i = i + 1
i(k) = i(0) + k x(k) = x(0) + k(k − 1) 2 + ki(0) i(k) = i(k−1) + 1 x(k) = x(k−1) + i(k−1) ∃k.k ≥ 0 ∧ ( i′ = i + k x′ = x + k(k − 1) 2 + ki )
- branching
- nested loops
- non-determinism
algebraic numbers
SLIDE 6 binary-search(A,target): lo = 1, hi = size(A), ticks = 0 while (lo <= hi): ticks++; mid = lo + (hi-lo)/2 if A[mid] == target: return mid else if A[mid] < target: lo = mid+1 else : hi = mid-1 log(A) times
ticks ticks mid lo hi lo A mid target lo mid hi hi A mid target lo lo hi mid
ticks k ticks k hi lo
k
hi lo
k
ticks k ticks k hi lo
k k
hi lo
k k ticks ticks k hi lo
k
hi lo
SLIDE 7 binary-search(A,target): lo = 1, hi = size(A), ticks = 0 while (lo <= hi): ticks++; mid = lo + (hi-lo)/2 if A[mid] == target: return mid else if A[mid] < target: lo = mid+1 else : hi = mid-1 log(A) times
ticks′ = ticks + 1 ∧mid′ = lo + (hi − lo)/2 ∧((A[mid] < target ∧lo′ = mid + 1 ∧hi′ = hi) ∨(A[mid] > target ∧lo′ = lo ∧hi′ = mid − 1))
ticks k ticks k hi lo
k
hi lo
k
ticks k ticks k hi lo
k k
hi lo
k k ticks ticks k hi lo
k
hi lo
SLIDE 8 binary-search(A,target): lo = 1, hi = size(A), ticks = 0 while (lo <= hi): ticks++; mid = lo + (hi-lo)/2 if A[mid] == target: return mid else if A[mid] < target: lo = mid+1 else : hi = mid-1 log(A) times
ticks′ = ticks + 1 ∧mid′ = lo + (hi − lo)/2 ∧((A[mid] < target ∧lo′ = mid + 1 ∧hi′ = hi) ∨(A[mid] > target ∧lo′ = lo ∧hi′ = mid − 1))
ticks(k+1) = ticks(k) + 1 (hi′ − lo′)(k+1) ≤ (hi − lo)(k)/2 − 1 ticks k ticks k hi lo
k k
hi lo
k k ticks ticks k hi lo
k
hi lo
SLIDE 9 binary-search(A,target): lo = 1, hi = size(A), ticks = 0 while (lo <= hi): ticks++; mid = lo + (hi-lo)/2 if A[mid] == target: return mid else if A[mid] < target: lo = mid+1 else : hi = mid-1 log(A) times
ticks′ = ticks + 1 ∧mid′ = lo + (hi − lo)/2 ∧((A[mid] < target ∧lo′ = mid + 1 ∧hi′ = hi) ∨(A[mid] > target ∧lo′ = lo ∧hi′ = mid − 1))
ticks k ticks k hi lo
k
hi lo
k
ticks(k) = ticks(0) + k (hi′−lo′)(k) ≤ (1 2 )k (hi−lo+2)(0)−2
k k ticks ticks k hi lo
k
hi lo
SLIDE 10
binary-search(A,target): lo = 1, hi = size(A), ticks = 0 while (lo <= hi): ticks++; mid = lo + (hi-lo)/2 if A[mid] == target: return mid else if A[mid] < target: lo = mid+1 else : hi = mid-1 log(A) times
ticks ticks mid lo hi lo A mid target lo mid hi hi A mid target lo lo hi mid
ticks k ticks k hi lo
k
hi lo
k
ticks k ticks k hi lo
k k
hi lo
∃k.k ≥ 0 ticks′ = ticks + k (hi′−lo′) ≤ (1 2 )k (hi−lo+2)−2
SLIDE 11
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j i j j ticks ticks i i n n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i n i i n n j i k k ticks ticks k j k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 12
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j < i ∧j′ = j + 1 ∧ticks′ = ticks + 1 ∧i′ = i ∧n′ = n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i n i i n n j i k k ticks ticks k j k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 13
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j < i ∧j′ = j + 1 ∧ticks′ = ticks + 1 ∧i′ = i ∧n′ = n
ticks(k+1) = ticks(k) + 1 j(k+1) = j(k) + 1 i(k+1) = i(k) n(k+1) = n(k) ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i n i i n n j i k k ticks ticks k j k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 14
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j < i ∧j′ = j + 1 ∧ticks′ = ticks + 1 ∧i′ = i ∧n′ = n
ticks k ticks k j k j k i k i k n k n k ticks(k) = ticks(0) + k j(k) = j(0) + k i(k) = i(0) n(k) = n(0)
i i n n j i k k ticks ticks k j j k i n i i n n j i k k ticks ticks k j k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 15
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j i j j ticks ticks i i n n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i′ = i ∧ n′ = n ∧ j′ ≤ i ∧ ∃k. k ≥ 0 ∧ ticks′ = ticks + k ∧ j′ = j + k i n i i n n j i k k ticks ticks k j k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 16
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j i j j ticks ticks i i n n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i < n ∧ i′ = i + 1 ∧ n′ = n ∧ j′ = i ∧ ∃k. k ≥ 0 ∧ticks′ = ticks + k ∧j′ = k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 17
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j i j j ticks ticks i i n n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i < n ∧ i′ = i + 1 ∧ n′ = n ∧ j′ = i ∧ ∃k. k ≥ 0 ∧ticks′ = ticks + k ∧j′ = k
ticks(k+1) = ticks(k)+i(k) i(k+1) = i(k) + 1 n(k+1) = n(k) ticks k ticks k k ki i k i k n k n
i n n n j i k k ticks ticks k k ki i i k
SLIDE 18
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j i j j ticks ticks i i n n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i < n ∧ i′ = i + 1 ∧ n′ = n ∧ j′ = i ∧ ∃k. k ≥ 0 ∧ticks′ = ticks + k ∧j′ = k
ticks k ticks k i k i k i k n k n k ticks(k) = ticks(0) + k(k + 1)/2 + ki(0) i(k) = i(0) + k n(k) = n(0)
i n n n j i k k ticks ticks k k ki i i k
SLIDE 19
for (i = 0; i < n; i++): for (j = 0; j < i; j++): ticks++
j i j j ticks ticks i i n n
ticks k ticks k j k j k i k i k n k n k ticks k ticks k j k j k i k i n k n
i i n n j i k k ticks ticks k j j k i n i i n n j i k k ticks ticks k j k
ticks k ticks k i k i k i k n k n k ticks k ticks k k ki i k i k n k n
i′ = n ∧n′ = n ∧j′ = i ∧ ∃k.k ≥ 0 ∧ticks′ = ticks + k(k + 1) 2 + ki ∧i′ = i + k
SLIDE 20
Warm up: the linear case
Suppose loop body formula F(x, x′) is linear. Goal: find a linear system y′ = Ay + b + linear transformation T s.t F(x, x′) | = (Tx′) = A(Tx) + b
Binary search: project onto ticks, hi lo
Algorithm:
1 Compute the affine hull of F by sampling linearly independent
models of F using an SMT solver. Result is system of (all) equations Ax Bx c entailed by F x x
2 Fixpoint computation:
We have: Ax Bx c We need: y By c Linear transformation T
T x T Bx T c T x T Bx T c . . .
computes best abstraction
SLIDE 21
Warm up: the linear case
Suppose loop body formula F(x, x′) is linear. Goal: find a linear system y′ = Ay + b + linear transformation T s.t F(x, x′) | = (Tx′) = A(Tx) + b
Binary search: project onto ticks, (hi − lo)
Algorithm:
1 Compute the affine hull of F by sampling linearly independent
models of F using an SMT solver. Result is system of (all) equations Ax Bx c entailed by F x x
2 Fixpoint computation:
We have: Ax Bx c We need: y By c Linear transformation T
T x T Bx T c T x T Bx T c . . .
computes best abstraction
SLIDE 22
Warm up: the linear case
Suppose loop body formula F(x, x′) is linear. Goal: find a linear system y′ = Ay + b + linear transformation T s.t F(x, x′) | = (Tx′) = A(Tx) + b
Binary search: project onto ticks, hi lo
Algorithm:
1 Compute the affine hull of F by sampling linearly independent
models of F using an SMT solver. Result is system of (all) equations Ax′ = Bx + c entailed by F(x, x′)
2 Fixpoint computation:
We have: Ax Bx c We need: y By c Linear transformation T
T x T Bx T c T x T Bx T c . . .
computes best abstraction
SLIDE 23
Warm up: the linear case
Suppose loop body formula F(x, x′) is linear. Goal: find a linear system y′ = Ay + b + linear transformation T s.t F(x, x′) | = (Tx′) = A(Tx) + b
Binary search: project onto ticks, hi lo
Algorithm:
1 Compute the affine hull of F by sampling linearly independent
models of F using an SMT solver. Result is system of (all) equations Ax′ = Bx + c entailed by F(x, x′)
2 Fixpoint computation:
We have: Ax′ = Bx + c We need: y′ = By + c Linear transformation T
T x T Bx T c T x T Bx T c . . .
computes best abstraction
SLIDE 24
Warm up: the linear case
Suppose loop body formula F(x, x′) is linear. Goal: find a linear system y′ = Ay + b + linear transformation T s.t F(x, x′) | = (Tx′) = A(Tx) + b
Binary search: project onto ticks, hi lo
Algorithm:
1 Compute the affine hull of F by sampling linearly independent
models of F using an SMT solver. Result is system of (all) equations Ax′ = Bx + c entailed by F(x, x′)
2 Fixpoint computation:
We have: Ax′ = Bx + c We need: y′ = By + c Linear transformation T
T0x′ = T0Bx + T0c T x T Bx T c . . .
computes best abstraction
SLIDE 25
Warm up: the linear case
Suppose loop body formula F(x, x′) is linear. Goal: find a linear system y′ = Ay + b + linear transformation T s.t F(x, x′) | = (Tx′) = A(Tx) + b
Binary search: project onto ticks, hi lo
Algorithm:
1 Compute the affine hull of F by sampling linearly independent
models of F using an SMT solver. Result is system of (all) equations Ax′ = Bx + c entailed by F(x, x′)
2 Fixpoint computation:
We have: Ax′ = Bx + c We need: y′ = By + c Linear transformation T
T0x′ = T0Bx + T0c T1x′ = T1Bx + T1c . . .
computes best abstraction
SLIDE 26
Reasoning about non-linear arithmetic
SLIDE 27
for (i = 0; i < n; i++): if (*): continue for (j = 0; j < n; j++): for (k = 0; k < n; k++): ticks++
i′ = i + 1 ∧i < n ∧n′ = n ∧ ticks′ = ticks ∧j′ = j ∧k′ = k ∨ ∃y ≥ 0. ticks′ = ticks + y × n ∧j′ = y = n ∧k′ = n
SLIDE 28
for (i = 0; i < n; i++): if (*): continue for (j = 0; j < n; j++): for (k = 0; k < n; k++): ticks++
i′ = i + 1 ∧i < n ∧n′ = n ∧ ticks′ = ticks ∧j′ = j ∧k′ = k ∨ ∃y ≥ 0. ticks′ = ticks + y × n ∧j′ = y = n ∧k′ = n
ticks′ ≤ ticks + n2
SLIDE 29 The wedge abstract domain
- The wedge domain is an abstract domain for reasoning about
non-linear integer/rational arithmetic
- The properties expressible by wedges correspond to the conjunctive
fragment of non-linear arithmetic (x × y, x/y, xy, logx(y), x mod y, ...)
Wedge Polyhedron Algebraic variety
treat non-linear terms as independent dimensions ignore , treat non-polynomial terms as independent dimensions
linear equations Inference rules Congruence closure
SLIDE 30 The wedge abstract domain
- The wedge domain is an abstract domain for reasoning about
non-linear integer/rational arithmetic
- The properties expressible by wedges correspond to the conjunctive
fragment of non-linear arithmetic (x × y, x/y, xy, logx(y), x mod y, ...)
Wedge Polyhedron Algebraic variety
treat non-linear terms as independent dimensions ignore ≤, treat non-polynomial terms as independent dimensions
linear equations Inference rules Congruence closure
SLIDE 31 The wedge abstract domain
- The wedge domain is an abstract domain for reasoning about
non-linear integer/rational arithmetic
- The properties expressible by wedges correspond to the conjunctive
fragment of non-linear arithmetic (x × y, x/y, xy, logx(y), x mod y, ...)
Wedge Polyhedron Algebraic variety
treat non-linear terms as independent dimensions ignore ≤, treat non-polynomial terms as independent dimensions
linear equations Inference rules Congruence closure
SLIDE 32 The wedge abstract domain
- The wedge domain is an abstract domain for reasoning about
non-linear integer/rational arithmetic
- The properties expressible by wedges correspond to the conjunctive
fragment of non-linear arithmetic (x × y, x/y, xy, logx(y), x mod y, ...)
Wedge Polyhedron Algebraic variety
treat non-linear terms as independent dimensions ignore ≤, treat non-polynomial terms as independent dimensions
linear equations Inference rules Congruence closure
SLIDE 33
Symbolic abstraction
i′ = i + 1 ∧i < n ∧n′ = n ∧ ticks′ = ticks ∧j′ = j ∧k′ = k ∨ ∃y ≥ 0. ticks′ = ticks + y × n ∧j′ = y = n ∧k′ = n
SLIDE 34
Symbolic abstraction
i′ = i + 1 ∧i < n ∧n′ = n ∧ticks′ = ticks ∧j′ = j ∨ i′ = i + 1 ∧i < n ∧n′ = n ∧ticks′ = ticks + sky × n ∧j′ = sky = n ∧k′ = n
SLIDE 35
Symbolic abstraction
i′ = i + 1 ∧i < n ∧n′ = n ∧ticks′ = ticks ∧j′ = j ∧0 ≤ n × n ∨ i′ = i + 1 ∧i < n ∧n′ = n ∧ticks′ = ticks + n × n ∧j′ = n ∧k′ = n ∧0 ≤ n × n
SLIDE 36
Symbolic abstraction
i′ = i + 1 ∧i < n ∧n′ = n ∧ticks ≤ ticks′ ≤ ticks + n × n ∧j′ = j ∧0 ≤ n × n
SLIDE 37
Extracting recurrences
Given: non-linear transition formula F(x, x′)
1 Compute wedge w that over-approximates F 2 Extract recurrences from w
Class of extractable recurrences: Tx A Tx t Additive term t involves polynomials & exponentials.
SLIDE 38
Extracting recurrences
Given: non-linear transition formula F(x, x′)
1 Compute wedge w that over-approximates F 2 Extract recurrences from w
Class of extractable recurrences: (Tx′) = A(Tx) + t Additive term t involves polynomials & exponentials.
SLIDE 39
How can we solve recurrence equations?
SLIDE 40 Operational Calculus Recurrence Solver [Berg 1967]
Operational calculus is an algebra of infinite sequences. Idea:
1 Translate recurrence into equation in operational calculus
- x(k+1) = x(k) + 1 ⇝ qx − (q − 1)x0 = x + 1
2 Solve the equation
1 q − 1
3 Translate solution back
SLIDE 41 Operational Calculus
Field of operators:
- Operator is a sequence with finitely many negative positions
a = (a−2, a−1 ∥ a0, a1, a2, ...) b = (∥ b0, b1, b2, ...)
- Addition is pointwise: (a + b)i ≜ ai + bi
- Multiplication is convolution difference:
(ab)n =
n
∑
i=−∞
aibn−i +
n−1
∑
i=−∞
aibn−i−1
qa a a a a a a
SLIDE 42 Operational Calculus
Field of operators:
- Operator is a sequence with finitely many negative positions
a = (a−2, a−1 ∥ a0, a1, a2, ...) b = (∥ b0, b1, b2, ...)
- Addition is pointwise: (a + b)i ≜ ai + bi
- Multiplication is convolution difference:
(ab)n =
n
∑
i=−∞
aibn−i +
n−1
∑
i=−∞
aibn−i−1
- Left shift operator q = (1 ∥ 1, 1, 1, ...)
qa = (a−2a−1a0 ∥ a1, a2, a3, ...)
SLIDE 43 Recurrence → operational calculus
Recurrences are equations in operational calculus x(k+1) = xk + t ⇝ qx − (q − 1)x0 = x + Tk(t)
- Think of x as an sequence (∥ x0, x1, x2, ...)
- Use left-shift operator to write recurrence as an equation
qx x x x x q x x qx q x x x x Can translate any expression in the grammar s t Expr k c k ck s t st
k c
c
k ct
c k t . . .
k s
t
k s k t k k
q . . .
SLIDE 44 Recurrence → operational calculus
Recurrences are equations in operational calculus x(k+1) = xk + t ⇝ qx − (q − 1)x0 = x + Tk(t)
- Think of x as an sequence (∥ x0, x1, x2, ...)
- Use left-shift operator to write recurrence as an equation
qx = (x0 ∥ x1, x2, x3, ...) (q − 1)x0 = (x0 ∥ 0, 0, 0, ...) qx − (q − 1)x0 = (∥ x1, x2, x3, ...) Can translate any expression in the grammar s t Expr k c k ck s t st
k c
c
k ct
c k t . . .
k s
t
k s k t k k
q . . .
SLIDE 45 Recurrence → operational calculus
Recurrences are equations in operational calculus x(k+1) = xk + t ⇝ qx − (q − 1)x0 = x + Tk(t)
- Think of x as an sequence (∥ x0, x1, x2, ...)
- Use left-shift operator to write recurrence as an equation
qx = (x0 ∥ x1, x2, x3, ...) (q − 1)x0 = (x0 ∥ 0, 0, 0, ...) qx − (q − 1)x0 = (∥ x1, x2, x3, ...) Can translate any expression in the grammar s, t ∈ Expr(k) ::= c ∈ Q | k | ck | s + t | st
Tk(c) = c Tk(ct) = cTk(t) . . . Tk(s + t) = Tk(s) + Tk(t) Tk(k) = 1 q − 1 . . .
SLIDE 46
Operational Calculus → classical algebra
Tk(c) = c Tk(ct) = cTk(t) Tk(s + t) = Tk(s) + Tk(t) Tk(k) = 1 q − 1 . . .
k ft k
t T −1
k
(c) = c T −1
k
(ct) = cT −1
k
(t) T −1
k
(s + t) = T −1
k
(s) + T −1
k
(t) T −1
k
( 1 q − 1) = k . . .
k
t Operational Calculus classical algebra translation is not complete!
SLIDE 47
Operational Calculus → classical algebra
Tk(c) = c Tk(ct) = cTk(t) Tk(s + t) = Tk(s) + Tk(t) Tk(k) = 1 q − 1 . . .
k ft k
t T −1
k
(c) = c T −1
k
(ct) = cT −1
k
(t) T −1
k
(s + t) = T −1
k
(s) + T −1
k
(t) T −1
k
( 1 q − 1) = k . . . T −1
k
(t) = ? Operational Calculus → classical algebra translation is not complete!
SLIDE 48
Operational Calculus → classical algebra
Tk(c) = c Tk(ct) = cTk(t) Tk(s + t) = Tk(s) + Tk(t) Tk(k) = 1 q − 1 . . .
k ft k
t T −1
k
(c) = c T −1
k
(ct) = cT −1
k
(t) T −1
k
(s + t) = T −1
k
(s) + T −1
k
(t) T −1
k
( 1 q − 1) = k . . . T −1
k
(t) = ft(k) Operational Calculus → classical algebra translation is not complete! Implicitly interpreted function
SLIDE 49
Operational Calculus → classical algebra
Tk(c) = c Tk(ct) = cTk(t) Tk(s + t) = Tk(s) + Tk(t) Tk(k) = 1 q − 1 . . . Tk(ft(k)) = t T −1
k
(c) = c T −1
k
(ct) = cT −1
k
(t) T −1
k
(s + t) = T −1
k
(s) + T −1
k
(t) T −1
k
( 1 q − 1) = k . . . T −1
k
(t) = ft(k) Operational Calculus → classical algebra translation is not complete! Implicitly interpreted function
SLIDE 50
Experiments
ICRA: built on top of Z3, Apron. Analyzes recursive procedures via [Kincaid, Breck, Boroujeni, Reps PLDI 2017] Benchmark Total ICRA UAut. CPA SEA Suite #A Time #A Time #A Time #A Time #A HOLA 46 123.5 33 1571.9 20 2004.1 11 259.5 38 functional 21 77.9 11 732.8 0 1155.7 0 722.3 2 relational 10 8.1 10 473 0 603.0 0 121.8 4 Total 77 209.5 54 2777.7 20 3762.8 11 1103.6 44
SLIDE 51 Contributions:
- Wedge abstract domain
- Algorithm for extracting recurrences from loop bodies with control
flow & non-determinism
- Recurrence solver that avoids algebraic numbers
Result: non-linear invariant generation for arbitrary loops