Symbolic Computation and Theorem Proving in Program Analysis
Laura Kov´ acs
Chalmers
Symbolic Computation and Theorem Proving in Program Analysis Laura - - PowerPoint PPT Presentation
Symbolic Computation and Theorem Proving in Program Analysis Laura Kov acs Chalmers Specification Program Loop Assertions Verification Conditions Proving Proving Specification Program Loop Assertions Theorem Proving Computer Algebra
Laura Kov´ acs
Chalmers
Specification Program Loop Assertions Verification Conditions Proving Proving
Specification Program Loop Assertions Verification Conditions Proving
Computer Algebra Theorem Proving
Proving
Program Loop Assertions
Polynomial Equalities and Inequalities, Quantified FO properties
a := 0; b := 0; c := 0; while (a < N) do if A[a] ≥ 0 then B[b] := A[a]; b := b + 1 else C[c] := A[a]; c := c + 1; a := a + 1; end do a = b + c a ≥ 0 ∧ b ≥ 0 ∧ c ≥ 0 a ≤ N ∨ N ≤ 0 (∀p)(p ≥ b → B[p] = B0[p]) (∀p)(0 ≤ p < b → B[p] ≥ 0 ∧ (∃i)(0 ≤ i < a ∧ A[a] = B[p]))
Program Loop Assertions
Polynomial Equalities and Inequalities, Quantified FO properties
a := 0; b := 0; c := 0; while (a < N) do if A[a] ≥ 0 then B[b] := A[a]; b := b + 1 else C[c] := A[a]; c := c + 1; a := a + 1; end do a = b + c a ≥ 0 ∧ b ≥ 0 ∧ c ≥ 0 a ≤ N ∨ N ≤ 0 (∀p)(p ≥ b → B[p] = B0[p]) (∀p)(0 ≤ p < b → B[p] ≥ 0 ∧ (∃i)(0 ≤ i < a ∧ A[a] = B[p]))
Loop Assertions
Loop Assertions Loop Properties
Extend language with extra symbols: loop cnt, array update predicates
Loop Assertions Loop Properties
Extend language with extra symbols: loop cnt, array update predicates Eliminate symbols
Loop Assertions Loop Properties
Extend language with extra symbols: loop cnt, array update predicates Eliminate symbols
Recurrence Solving Monotonicity Properties of Scalars Array Update Properties Gr¨
Consequence Finding
Part 1: Weakest Precondition for Program Analysis and Verification Part 2: Polynomial Invariant Generation (TACAS’08, LPAR’10) Part 3: Quantified Invariant Generation (FASE’09, MICAI’11) Part 4: Invariants, Interpolants and Symbol Elimination
(CADE’09, POPL ’12, APLAS’12)
Symbol Elimination by First-Order Theorem Proving
Quantified Invariant Example Quantified Invariant Generation by Symbol Elimination Symbol Elimination in the Vampire First-Order Theorem Prover Conclusions
Quantified Invariant Example Quantified Invariant Generation by Symbol Elimination Symbol Elimination in the Vampire First-Order Theorem Prover Conclusions
partition.c
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do A :
a = 0 B :
b = 0 C :
c = 0
partition.c
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do A :
a = 7 B :
b = 4 C :
c = 3
partition.c
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do A :
a = 7 B :
b = 4 C :
c = 3
Invariants with ∀ ∃
◮ Each of B[0], . . . , B[b − 1] is non-negative and equal to one of
A[0], . . . , A[a − 1]. (∀p)(0 ≤ p < b → B[p] ≥ 0 ∧ (∃i)(0 ≤ i < a ∧ A[i] = B[p]))
partition.c
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do A :
a = 7 B :
b = 4 C :
c = 3
Invariants with ∀ ∃
◮ Each of B[0], . . . , B[b − 1] is non-negative and equal to one of
A[0], . . . , A[a − 1]. (∀p)(0 ≤ p < b → B[p] ≥ 0 ∧ (∃i)(0 ≤ i < a ∧ A[i] = B[p]))
partition.c
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do A :
a = 7 B :
b = 4 C :
c = 3
Invariants with ∀ ∃
◮ Each of B[0], . . . , B[b − 1] is non-negative and equal to one of
A[0], . . . , A[a − 1].
◮ Each of C[0], . . . , C[c − 1] is negative and equal to one of
A[0], . . . , A[a − 1].
Invariants with ∀
◮ For every p ≥ b, the value of B[p] is equal to its initial value. ◮ For every p ≥ c, the value of C[p] is equal to its initial value.
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
∀p(p ≥ b → B[p] = B0[p])
∀p(b > p ∧ p ≥ 0 → B[p] ≥ 0 ∧ ∃k(a > k ∧ k ≥ 0 ∧ A[k] = B[p])
Quantified Invariant Example Quantified Invariant Generation by Symbol Elimination Symbol Elimination in the Vampire First-Order Theorem Prover Conclusions
◮ Given loop L; ◮ Extend L to L′; ◮ Extract a set P of loop properties in L′; ◮ Generate loop property p in L s.t. P → p.
◮ Given loop L; ◮ Extend L to L′; ◮ Extract a set P of loop properties in L′; ◮ Generate loop property p in L s.t. P → p.
◮ Given loop L; ◮ Extend L to L′; ◮ Extract a set P of loop properties in L′; ◮ Generate loop property p in L s.t. P → p.
← Symbol elimination!
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x) (∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
at position p;
updated at position p by value x. (∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars
(∀i ∈ iter)(v (i+1) ≥ v (i))
(∀i ∈ iter)(v (i+1) = v (i)∨v (i+1) = v (i)+1) (∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars
(∀i ∈ iter)(v (i) = v (0) + i)
(∀j, k ∈ iter)(k ≥ j → v (k) ≥ v (j))
increasing: (∀j, k ∈ iter)(k ≥ j →v (j) + k ≥ v (k) + j)
v(k) ≥ v(j) − − → dense v(j) + k − j ≥ v(k)
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars
(∀p)(v (0) ≤ p < v (n) → (∃i ∈ iter)(
u∈U(i :: Gu) ∧ v (i) = p)
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars ◮ Update predicates of arrays
no array update at p → (final) value of V[p] is unchanged
V[p] updated at iteration i and no further → final value V[p]
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars ◮ Update predicates of arrays ◮ Translation of guarded assignments
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars ◮ Update predicates of arrays ◮ Translation of guarded assignments
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars ◮ Update predicates of arrays ◮ Translation of guarded assignments
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
◮ variables as functions of n:
v (i) with 0 ≤ i < n
◮ predicates as loop properties:
iter, updV(i, p), updV(i, p, x)
◮ Polynomial scalar properties ◮ Monotonicity properties of scalars ◮ Update predicates of arrays ◮ Translation of guarded assignments
→ Invariants (∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x)∧(∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
(∀i)(i ∈ iter ⇔ 0 ≤ i ∧ i < n) updB(i, p) ⇔ i ∈ iter ∧ p = b(i) ∧ A[a(i)] ≥ 0 updB(i, p, x) ⇔ updB(i, p) ∧ x = A[a(i)] a = b + c, a ≥ 0, b ≥ 0, c ≥ 0 (∀i ∈ iter)(a(i+1) > a(i)) (∀i ∈ iter)(b(i+1) = b(i) ∨ b(i+1) = b(i) + 1) (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j → b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j → b(j) + k ≥ b(k) + j) (∀p)(b(0) ≤ p < b(n)→(∃i ∈ iter)(b(i) = p∧ A[a(i)] ≥ 0)) (∀i)¬updB(i, p) → B(n)[p] = B(0)[p] updB(i, p, x) ∧ (∀j > i)¬updB(j, p)→B(n)[p]=x (∀i ∈ iter)(A[a(i)] ≥ 0 →B(i+1)[b(i)] = A[a(i)]∧ b(i+1) = b(i) + 1∧ c(i+1) = c(i) )
Saturation Theorem Proving
I1, I2, I3, I4, I5, . . .
Given a problem with axioms and assumptions F1, . . . , Fn and conjecture G,
Given a problem with axioms and assumptions F1, . . . , Fn and conjecture G,
Thus, we reduce the theorem proving problem to the problem of checking unsatisfiability.
Given a set S0 of clauses in an inference system I (e.g. binary
resolution or superposition)
Given a set S0 of clauses in an inference system I (e.g. binary
resolution or superposition)
Idea:
◮ Take a set of clauses S (the search space), initially S = S0.
Repeatedly apply inferences in I to clauses in S and add their conclusions to S, unless these conclusions are already in S.
◮ If, at any stage, we obtain ⊥, we terminate and report
unsatisfiability of S0.
When can we report satisfiability of S?
When can we report satisfiability of S? When we build a set S such that any inference applied to clauses in S is already a member of S. Any such set of clauses is called saturated (with respect to I).
When can we report satisfiability of S? When we build a set S such that any inference applied to clauses in S is already a member of S. Any such set of clauses is called saturated (with respect to I). In first-order logic it is often the case that all saturated sets are infinite (due to undecidability), so in practice we can never build a saturated set. The process of trying to build one is referred to as saturation.
search space
search space given clause
search space given clause candidate clauses
search space given clause candidate clauses children
search space children
search space children
search space
search space given clause
search space given clause candidate clauses
search space given clause candidate clauses children
search space children
search space children
search space
search space
search space
MEMORY
A saturation algorithm tries to saturate a set of clauses with respect to a given inference system. In theory there are three possible scenarios:
the input set of clauses is unsatisfiable.
the input set of clauses in satisfiable.
the input set of clauses is satisfiable.
In practice there are three possible scenarios:
the input set of clauses is unsatisfiable.
the input set of clauses in satisfiable.
generating ⊥. In this case it is unknown whether the input set is unsatisfiable.
x ≥ y ⇐ ⇒ x > y ∨ x = y x > y → x = y x ≥ y ∧ y ≥ z → x ≥ z x + 1 > x x ≥ y + 1 ⇐ ⇒ x > y
x ≥ y ⇐ ⇒ x > y ∨ x = y x > y → x = y x ≥ y ∧ y ≥ z → x ≥ z x + 1 > x x ≥ y + 1 ⇐ ⇒ x > y
◮ For every loop variable v → TARGET SYMBOLS v0 and v:
v(0)=v0 and v(n)=v
◮ USABLE symbols (logical variables are not symbols):
◮ USEFUL clauses:
◮ Reduction ordering ≻: useless symbols ≻ usable symbols.
x ≥ y ⇐ ⇒ x > y ∨ x = y x > y → x = y x ≥ y ∧ y ≥ z → x ≥ z x + 1 > x x ≥ y + 1 ⇐ ⇒ x > y
◮ For every loop variable v → TARGET SYMBOLS v0 and v:
v(0)=v0 and v(n)=v
◮ USABLE symbols (logical variables are not symbols):
◮ USEFUL clauses:
x + y = y + x
◮ Reduction ordering ≻: useless symbols ≻ usable symbols.
x ≥ y ⇐ ⇒ x > y ∨ x = y x > y → x = y x ≥ y ∧ y ≥ z → x ≥ z x + 1 > x x ≥ y + 1 ⇐ ⇒ x > y
◮ For every loop variable v → TARGET SYMBOLS v0 and v:
v(0)=v0 and v(n)=v
◮ USABLE symbols (logical variables are not symbols):
◮ USEFUL clauses:
x + y = y + x is not useful
◮ Reduction ordering ≻: useless symbols ≻ usable symbols.
x ≥ y ⇐ ⇒ x > y ∨ x = y x > y → x = y x ≥ y ∧ y ≥ z → x ≥ z x + 1 > x x ≥ y + 1 ⇐ ⇒ x > y
◮ For every loop variable v → TARGET SYMBOLS v0 and v:
v(0)=v0 and v(n)=v
◮ USABLE symbols (logical variables are not symbols):
◮ USEFUL clauses:
◮ Reduction ordering ≻: useless symbols ≻ usable symbols.
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
Loop
Poly Invariants S y m b
i c C
p . S t a t i c A n a l y s i s a = b + c b ≥ 0 c ≥ 0 a ≥ 0
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
Loop
Poly Invariants S y m b
i c C
p . S t a t i c A n a l y s i s a = b + c b ≥ 0 c ≥ 0 a ≥ 0 Scalar Props over Loop Cnt Symbolic Comp. Static Analysis (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j ⇒ b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j ⇒ b(j) + k ≥ b(k) + j)
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
Loop
Poly Invariants S y m b
i c C
p . S t a t i c A n a l y s i s a = b + c b ≥ 0 c ≥ 0 a ≥ 0 Scalar Props over Loop Cnt Symbolic Comp. Static Analysis (∀i ∈ iter)(a(i) = a(0) + i) (∀j, k ∈ iter)(k ≥ j ⇒ b(k) ≥ b(j)) (∀j, k ∈ iter)(k ≥ j ⇒ b(j) + k ≥ b(k) + j) Array Update Predicates Symbolic Comp. Static Analysis (∀i)¬updB(i, p) ⇒ B(n)[p] = B(0)[p] (∀v)(b(0) ≤ v < b(n) ⇒ b(i+1) = b(i) + 1 ∧ c(i+1) = c(i) + 1 (∀i ∈ iter)(A[a(i)] ≥ 0 ⇒ B(i+1)[b(i)] = A[a(i)] ∧ (∀v)(b(0) ≤ v < b(n) ⇒ (∃i ∈ iter)(b(i) = v ∧ (A[a(i)] ≥ 0))
a := 0; b := 0; c := 0; while (a ≤ k) do if A[a] ≥ 0 then B[b] := A[a];b := b + 1; else C[c] := A[a];c := c + 1; a := a + 1; end do
Loop
Poly Invariants Scalar Props over Loop Cnt Array Update Predicates S y m b
i c C
p . S t a t i c A n a l y s i s Symbolic Comp. Static Analysis Symbolic Comp. Static Analysis
Aligator Set of FO Loop Properties Vampire Quantified Invariant
Saturation Thm. Proving Symbol Elim.
Quantified Invariant Example Quantified Invariant Generation by Symbol Elimination Symbol Elimination in the Vampire First-Order Theorem Prover Conclusions
!"#$%&'(&)#)*+,)%* !"#$%&'$"( )*$+%*$&,-
1%+2)*3 .*$/01-*23#� )'*2*%0 1-*23#�
4,%0"*'/05*$/
40%30+#''5*+&"6/0 1%%*30 1-*23#� 6&%#$7,%("%0 2,,50 5%,5"%$&"# 1%%7 1%%7 8*9+0)+*,6 :%*6/;</*=/' >/#%9+&
?+#7)0/
vampire --mode program analysis
partition.c Loops found: 1 Analyzing loop...
{ if (A[a] >= 0) { B[b] = A[a]; b = b + 1; } else { C[c] = A[a]; c = c + 1; } a = a + 1; }
Variable: C: (updated) Variable: m: constant Variable: b: (updated) Variable: B: (updated) Variable: c: (updated) Variable: a: (updated) Counter: b Counter: c Counter: a Collecting paths...
false: A[a] >= 0 C[c] = A[a]; c = c + 1; a = a + 1; Path: true: A[a] >= 0 B[b] = A[a]; b = b + 1; a = a + 1; Counter a: 1 min, 1 max, 1 gcd Counter b: 0 min, 1 max, 1 gcd Counter c: 0 min, 1 max, 1 gcd ... Collected first-order loop properties...
...
?[X2]:(c(X2)=X3 & X2>X0 & X1>X2) [program analysis]
=> ?[X2]:(b(X2)=X3 & X2>X0 & X1>X2) [program analysis]
Figure : Partial output of Vampire’s program analyser on the Partition program.
A partial correctness statement: {∀X(p(X) => X ≥ 0)} {∀X(q(X) > 0)} {p(a)} if (r(a)) { a := a+1 } else { a := a + q(a). } {a > 0}
A partial correctness statement: {∀X(p(X) => X ≥ 0)} {∀X(q(X) > 0)} {p(a)} if (r(a)) { a := a+1 } else { a := a + q(a). } {a > 0} The next state function for a: a’ = if r(a) then let a=a+1 in a else let a=a+q(a) in a
A partial correctness statement: {∀X(p(X) => X ≥ 0)} {∀X(q(X) > 0)} {p(a)} if (r(a)) { a := a+1 } else { a := a + q(a). } {a > 0} The next state function for a: a’ = if r(a) then let a=a+1 in a else let a=a+q(a) in a In Vampire: tff(1,type,p : $int > $o). tff(2,type,q : $int > $int). tff(3,type,r : $int > $o). tff(4,type,a : $int). tff(5,hypothesis,! [X:$int] : (p(X) => $greatereq(X,0))). tff(6,hypothesis,! [X:$int] : ($greatereq(q(X),0))). tff(7,hypothesis,p(a)). tff(8,hypothesis, a0 = $ite t(r(a), $let tt(a,$sum(a,1),a), $let tt(a,$sum(a,q(a)),a) )). tff(9,conjecture,$greater(a0,0)).
We use incomplete but sound theory axiomatisation.
Example: Integers in Vampire
◮ 0, 1, 2, etc; ◮ Integer predicates/funcions:
◮ addition; ◮ subtraction; ◮ multiplication; ◮ successor; ◮ division; ◮ inequality relations;
tff(boolean type,type,b: $tType). % b is a sort tff(s is a type,type,s: $tType). % s is a sort tff(t has type b,type,t : b). % t has sort b tff(f has type b,type,f : b). % f has sort b tff(1,axiom,t != f & ! [X:b] : X = t | X = f). tff(1,axiom,? [X:s,Y:s,Z:s] : (X != Y & X != Z & Y != Z)). vampire --splitting off
◮ $i: sort of individuals. If is the default sort: if a symbol is not
declared, it has this sort.
◮ $o: sort of booleans. ◮ $int: sort of integers. ◮ $rat: sort of rationals. ◮ $real: sort of reals.
One can use concrete integers and some interpreted functions on them. fof(1,conjecture,$sum(2,2)=4). vampire --inequality splitting 0 int1.tptp
Functions:
◮ $sum: addition (x + y) ◮ $product: multiplication (x · y) ◮ $difference: difference (x − y) ◮ $uminus: unary minus (−x) ◮ $to rat: conversion to rationals. ◮ $to real: conversion to reals.
Predicates:
◮ $less: less than (x < y) ◮ $lesseq: less than or equal to (x ≤ y) ◮ $greater: greater than (x > y) ◮ $greatereq: greater than or equal to (x ≥ y)
◮ adding theory axioms; ◮ evaluating expressions, when possible; ◮ (future) SMT solving.
◮ adding theory axioms; ◮ evaluating expressions, when possible; ◮ (future) SMT solving.
Example: (x + y) + z = x + (z + y). fof(1,conjecture, ! [X:$int,Y:$int,Z:$int] : $sum($sum(X,Y),Z)=$sum(X,$sum(Z,Y))). vampire --inequality splitting 0 int2.tptp
◮ adding theory axioms; ◮ evaluating expressions, when possible; ◮ (future) SMT solving.
Example: (x + y) + z = x + (z + y). fof(1,conjecture, ! [X:$int,Y:$int,Z:$int] : $sum($sum(X,Y),Z)=$sum(X,$sum(Z,Y))). vampire --inequality splitting 0 int2.tptp
◮ You can add your own axioms; ◮ you can replace Vampire axioms by your own: use
vampire(option,show symbol elimination,on).
vampire(option,time limit,1). i ... tff(b type,type,a:$int). tff(b fcttype,type,a:$int>$int). tff(bb type,type,bb:$int>$int). tff(bb fct2type,type,bb:($int*$int)>$int). tff(iter fcttype,type,iter:$int>$o). tff(upd2 type,type,updbb:($int*$int)>$o). tff(upd3 type,type,updbb:($int*$int*$int)>$o). ... i vampire(symbol,function,n,0,left). vampire(symbol,function,a,1,left). vampire(symbol,function,b,1,left). vampire(symbol,function,c,1,left). vampire(symbol,function,bb,2,left). vampire(symbol,function,cc,2,left). vampire(symbol,predicate,updB,2,left). vampire(symbol,predicate,updB,3,left). vampire(symbol,predicate,updC,2,left). vampire(symbol,predicate,updC,3,left). vampire(symbol,predicate,iter,1,left). i vampire(symbol,function,a,0,skip). vampire(symbol,function,b,0,skip). vampire(symbol,function,c,0,skip). vampire(symbol,function,m,0,left). vampire(symbol,function,aa,1,skip). vampire(symbol,function,bb0,2,skip). vampire(symbol,function,bb0,1,skip). vampire(symbol,function,cc0,2,skip). vampire(symbol,function,cc0,1,skip).
Figure : Partial input for symbol elimination in Vampire.
./vampire array partition.tptp
Set of invariants: S
Minimal set S′ of invariants with S′ ⊂ S:
Remove C ∈ S iff S \ {C} ⇒ C
Compute S′ ⊂ S
Run Vampire on S within, e.g., 20s time limit
Experiments:
◮ consequence elimination ran in conjunction with 4 combination of
strategies
◮ eliminated ∼ 80% invariants
vampire --mode consequence elimination
Set of invariants: S
Minimal set S′ of invariants with S′ ⊂ S:
Remove C ∈ S iff S \ {C} ⇒ C
Compute S′ ⊂ S
Run Vampire on S within, e.g., 20s time limit
Experiments:
◮ consequence elimination ran in conjunction with 4 combination of
strategies
◮ eliminated ∼ 80% invariants
vampire --mode consequence elimination
Set of invariants: S
Minimal set S′ of invariants with S′ ⊂ S:
Remove C ∈ S iff S \ {C} ⇒ C
Compute S′ ⊂ S
Run Vampire on S within, e.g., 20s time limit
Experiments:
◮ consequence elimination ran in conjunction with 4 combination of
strategies
◮ eliminated ∼ 80% invariants
Loop ♯ SEI ♯ Min SEI Inv of interest Generated invariants implying Inv Copy a = 0; while (a < m) do B[a] = A[a]; a = a + 1 end do 24 5 ∀x : 0 ≤ x < a → B[x] = A[x] inv8: ∀x0, x1 : A[x0] = B[x1]∨ x0 = x1∨ ¬a > x0∨ ¬x0 ≥ 0 Find a = 0; spot = m while (a < m) do if (spot = m&&A[a] = 0) then spot = a end if; B[a] = (A[a] = 0); a = a + 1 end do 151 13 spot = m∨ A[spot] = 0 inv3: a ≥ spot inv39: spot = sk1 ∨ a = spot inv25: 0 ≥ sk1 ∨ a = spot inv5: ∀x1 : ¬a > x1∨ ¬x1 ≥ 0 ∨ a = spot∨ A(spot) = 0 Partition a = 0; b = 0; c = 0; while (a < m) do if (A[a] >= 0) then B[b] = A[a]; b = b + 1 else C[c] = A[a]; c = c + 1 end if; a = a + 1 end do 166 38 ∀x : 0 ≤ x < b → B[x] ≥ 0∧ ∃y : B[x] = A[y] inv1: ∀x0 : A(sk2(x0)) ≥ 0∨ ¬b > x0∨ ¬x0 ≥ 0 inv81: ∀x0 : ¬b > x0∨ ¬x0 ≥ 0∨ A(sk2(x0)) = B(x0) Partition Init a = 0; c = 0; while (a < m) do if (A[a] == B[a]) then C[c] = a; c = c + 1 end if; a = a + 1 end do 168 24 ∀x : 0 ≤ x < c → A[C[x]] = B[C[x]] inv0: ∀x0 : A(sk1(x0)) = B(sk1(x0))∨ ¬c > x0∨ ¬x0 ≥ 0 inv30: ∀x0, x1, x2 : sk1(x0) = x1∨ x0 = x2∨ ¬c > x0∨ ¬x0 ≥ 0∨ C(x2) = x1
Table : Vampire with 1 second time limit.
Quantified Invariant Example Quantified Invariant Generation by Symbol Elimination Symbol Elimination in the Vampire First-Order Theorem Prover Conclusions
Given a loop:
(loop counter, predicates expressing array updates, etc.);
but not an invariant;
SEI: premise contains extra symbols, conclusion is in the loop language.
Slides for session 3 ended here . . .