Reasoning about Arrays

Reasoning about Arrays
Aaron R. Bradley
CU Boulder
max := a[l];
for(i := l+1; i <= u; i++)
if (a[i] > max) max := a[i];
Establish postcondition:
∀j. l ≤ j ≤ u → a[j] ≤ max
Loop invariant:
∀j. l ≤ j < i → a[j] ≤ max
Also establish postcondition:
∀j. a[j] = a0 [j]
for(i := 0; i < length(sets); i++)
u := union(u, sets[i]);
Given postcondition of union(u,
v):
rv = u ∪ v
Establish postcondition:
∀j. 0 ≤ j ≤ |sets| → sets[j] ⊆ u
Loop invariant:
∀j. 0 ≤ j < i → sets[j] ⊆ u
Loop invariant:
∀j. 0 ≤ j < i → sets[j] ⊆ u
Translation:
∀j. 0 ≤ j < i → ∀e. sets[j][e] → u[e]
Sets
• e∈s:
s[e]
• s⊆t
∀e. s[e] → t[e]
• s⊂t
(∀e. s[e] → t[e]) ∧ (∃e1 . ¬s[e1 ] ∧ t[e1 ])
• s = t ∩ u ∀e. s[e] ↔ t[e] ∧ u[e]
• s=t
∀e. s[e] ↔ ¬t[e]
Multisets (bags)
• C(s, e)
s[e]
• s = t ⊎ u ∀e. s[e] = t[e] + u[e]
• ...
assert(v >= 0);
ht := put(ht, k, v);
Precondition:
∀j ∈ keys(ht). get(ht, j) ≥ 0
Establish postcondition:
∀j ∈ keys(ht). get(ht, j) ≥ 0
Verification condition:
(∀j ∈ keys(ht). get(ht, j) ≥ 0)
∧ v ≥ 0 ∧ h′ = put(ht, k, v)
→ (∀j ∈ keys(h′ ). get(h′ , j) ≥ 0)
Flat data structures
• Integer-indexed arrays
• Collections: sets, multisets (bags)
• Hashtables
Model and reason about them as arrays (uninterpreted functions).
First-Order Theory
T : (Σ, A)
• Signature Σ: non-logical symbols (a, b, +, <, . . . )
• Axioms A: formulae interpreting symbols
T -Interpretation I : (D, α)
• Domain D: set of objects
• Assignment α: assigns Σ-symbols to domain elements,
functions, predicates
• for each F ∈ A, I |= F
Σ-formula F is T -valid iff for every T -interpretation I , I |= F .
F is T -valid
iff
¬F is T -unsatisfiable
Decision Problem for T
Decide if Σ-formula F is T -valid.
T is set of T -valid Σ-formulae.
TA : First-Order Theory of Arrays
Signature:
ΣA : {a[i], ahi ⊳ vi, =}
Axioms:
• Equality axioms
• Infinite domain axiom schema: for all n > 0
n
^
j 6= ik
∀i1 , . . . , in . ∃j.
k=1
• Read-over-write
∀a, i, j, v. i = j → ahi ⊳ vi[j] = v
∀a, i, j, v. i 6= j → ahi ⊳ vi[j] = a[j]
TAZ : First-Order Theory of Integer-Indexed Arrays
Signature:
ΣZA : ΣA ∪ ΣZ = {a[i], ahi ⊳ vi, =, 0, 1, +, ≥}
Axioms:
• Axioms of integer arithmetic
• Equality axioms
• Read-over-write
∀a, i, j, v. i = j → ahi ⊳ vi[j] = v
∀a, i, j, v. i 6= j → ahi ⊳ vi[j] = a[j]
Fragment of T
Subset of T given by syntactic restriction.
Example: “quantifier-free” fragment (QFF) of TA
Is
a[i] = e1 ∧ e1 6= e2 → ahi ⊳ e2 i[i] 6= a[i]
TA -valid?
Alternately, is
a[i] = e1 ∧ e1 6= e2 ∧ ahi ⊳ e2 i[i] = a[i]
TA -unsatisfiable?
Nelson-Oppen Combination Method
Given:
• Theories T1 , . . . , Tk that share only = (and are stably infinite)
• Decision procedures P1 , . . . , Pk
• Quantifier-free (Σ1 ∪ · · · ∪ Σk )-formula F
Decide if F is (T1
∪ · · · ∪ Tk )-satisfiable using P1 , . . . , Pk .
Think about arrays in context of Nelson-Oppen.
History
• 1962: John McCarthy formalizes arrays as first-order theory TA .
• 1969: James King describes and implements DP for QFF of TA .
• 1979: Nelson & Oppen describe combination method for QF
theories sharing =.
• 1980s: Suzuki, Jefferson; Jaffar; Mateti describe DPs for QFF of
theories of arrays with predicates for sorted, partitioned, etc.
• 1997: Levitt describes DP for QFF of extensional theory of
arrays in thesis.
• 2001: Stump, Barrett, Dill, Levitt describe DP for QFF of
extensional theory of arrays.
• 2006: Bradley, Manna, Sipma describe DP for array property
fragment of TA , TAZ .
• Other recent references:
– Sofronie-Stokkermans et al.: local theory extensions
– Ghilardi, Nicolini, Ranise, Zucchelli
– Iosef, Habermehl, Vojnar: use flat counter automata
– Fontaine: Combinations with Bernays-Schonfinkel-Ramsey
class
Array Property Fragment of TA
Array property:
∀i. F [i] → G[a[i]]
• F : index guard
iguard := iguard ∧ iguard | iguard ∨ iguard | atom
atom := var = var | evar 6= var | var 6= evar | ⊤
var := evar | uvar
• G: value constraint
i only appears in a[i] (possibly within nested array properties)
Array property fragment: Boolean combination of array properties
and QF formulae.
Array Property Fragment of TA
∪T
Same definition when T is a Nelson-Oppen theory.
Decision Procedure
Given: Array property formula F
1.
F1 : push negations to atoms
2.
F2 : Eliminate writes
G[ahi ⊳ vi]
G[a′ ] ∧ a′ [i] = v ∧ (∀j. j 6= i → a[j] = a′ [j])
3. Construct index set
I : {t : t is symbolic index} ∪ {κ}
4.
F4 : κ is unique
F2 ∧
^
κ 6= t
t∈I\κ
5.
F5 : Instantiate quantifiers
H[∀i. G[i]]
6.
=⇒
H
"
^
t∈I
#
G[t]
F5 is QF. Decide satisfiability using Nelson-Oppen DP.
Example: Extensional theory (Stump et al., 2001)
a = bhi ⊳ vi ∧ a[i] 6= v
In array property fragment:
(∀j. a[j] = bhi ⊳ vi[j]) ∧ a[i] 6= v
Eliminate write:
(∀j. a[j] = b′ [j]) ∧ a[i] 6= v
∧ b′ [i] = v ∧ (∀j. j 6= i → b′ [j] = b[j])
Index set:
I : {i, κ}
QF formula:
a[i] = b′ [i] ∧ a[κ] = b′ [κ]
∧ a[i] 6= v ∧ b′ [i] = v
∧ (i 6= i → b′ [i] = b[i]) ∧ (κ 6= i → b′ [κ] = b[κ])
∧ κ 6= i
Simplified:
a[i] = b′ [i] ∧ a[κ] = b′ [κ]
∧ a[i] 6= v ∧ b′ [i] = v
∧ b′ [κ] = b[κ]
∧ κ 6= i
Why κ?
(∀i. a[i] > 0) ∧ (∀i. a[i] < 0)
But requires infinite domain for indices. Recall axiom schema:
For all n
>0
∀i1 , . . . , in . ∃j.
n
^
k=1
j 6= ik
Correctness
• Sound? It’s just quantifier elimination (except for κ).
• Complete?
Assume I |= F5 . Construct J such that J |= F .

 i if α [t] = v for some i ∈ I
I
i
proj(t) =
 κ otherwise
F [proj(i)]
K |=
G[a[proj(i)]]
(1)
F [i]
(2)
?
G[a[i]]
Array Property Fragment of TAZ
Array property:
∀i. F [i] → G[a[i]]
• F : index guard
iguard := iguard ∧ iguard | iguard ∨ iguard | atom
atom := expr ≤ expr | expr = expr
expr := uvar | pexpr
pexpr := pexpr′
pexpr′ := Z | Z · evar | pexpr′ + pexpr′
• G: value constraint
i only appears in a[i] (possibly within nested array properties)
Array property fragment: Boolean combination of array properties
and QF formulae.
Decision Procedure
Given: Array property formula F
1.
F1 : push negations to atoms
2.
F2 : Eliminate writes
G[ahi ⊳ vi]
G[a′ ] ∧ a′ [i] = v
∧ (∀j. j ≤ i − 1 ∨ i + 1 ≤ j → a[j] = a′ [j])
3. Construct index set
I : {t : t is symbolic index} ({0} if empty)
4.
F4 : Instantiate quantifiers
H[∀i. G[i]]
5.
=⇒
H
"
^
t∈I
#
G[t]
F4 is QF. Decide satisfiability using Nelson-Oppen DP.
Example
sorted(a, ℓ, u) : ∀i, j. ℓ ≤ i ≤ j ≤ u → a[i] ≤ a[j]
Is
sorted(ah0 ⊳ 0ih5 ⊳ 1i, 0, 5) ∧ sorted(ah0 ⊳ 10ih5 ⊳ 11i, 0, 5)
(TAZ ∪ TZ )-satisfiable?
0 w x y z 1
10 w x y z 11
Example
sorted(ah0 ⊳ 0ih5 ⊳ 1i, 0, 5) ∧ sorted(ah0 ⊳ 10ih5 ⊳ 11i, 0, 5)
Index set:
{−1, 0, 1, 4, 5, 6}
• {0, 5} from 0 ≤ i ≤ j ≤ 5
• {−1, 1} from ·h0 ⊳ ·i
• {4, 6} from ·h5 ⊳ ·i
Contradiction:
0 ≤ a[1] ≤ 1 ∧ 10 ≤ a[1] ≤ 11
Need 1 or 4 in index set.
Complexity
Quantifier elimination is in NEXP for Nelson-Oppen theories:
1.
|I| is linear in size of F , so linear-time quantifier instantiation.
2.
NP DPs applied to QF formula at most exponentially larger than
F.
3. Exponential in largest stack of universal quantifiers.
Fixing stack height (“extensional”, “sorting” fragment) gives NP
procedure.
Complexity
NEXP-hard even for uninterpreted domain and range.
• Bernays-Schonfinkel-Ramsey (BSR) class: ∃∗ ∀∗ , only
predicates
• Deciding satisfiability is NEXP-complete
• Reduction:
∃x. F [x] =⇒ ∃x. d(x) ∧ F [x]
∀x. F [x] =⇒ ∀x. d(x) → F [x]
Why d? Only infinite TA -interpretations, but possible finite
BSR-interpretations.
Thanks to De Moura, Bjorner, Kuncak for mentioning BSR.
Undecidable Extensions
• Extra quantifier alternation
• Nested reads under ∀i: a[a[i]]
• No separation: ∀i. F [a[i], i]
• Arithmetic: a[i + 1] when i is universal
• Strict comparison: i < j when i, j are universal
• Permutation predicate
Reduce from undecidability of Diophantine equations:
p(x1 , . . . , xn ) = 0
(over nonnegative x)
“Walk”:
• Begin at origin.
• At each step, increment one xi .
• End at solution.
A walk exists iff p(x)
= 0 has a solution.
1.
q(x) = p(x)2
q(x) > 0 on walk, except at solution
2. Difference tree:
a : x2 − 2xy + y 2
b : 2x − 2y + 1
2
−2
c : −2x + 2y + 1
−2
2
3. Walk arithmetic is linear arithmetic:
Initially
(a, b, c) = (0, 1, 1)
x := x + 1 (a, b, c) := (a + b, b + 2, c − 2)
y := y + 1 (a, b, c) := (a + c, b − 2, c + 2)
Initial condition:
θ(i) :
^
ap [i] = p(0)
p
Transition relation for variable x:
ρx (i, j) :
^
ap [j] = ap [i] + a∆x p [i]
p
Idle transition:
ρ0 (i, j) : a[i] = a[j]
Easy: extra quantifier alternation

θ(0)
Ã
!

_

 ∧ ρ0 (i, j) ∨
ρx (i, j)

∃a, s. ∀i. ∃j. 
x

 ∧ s[j] = s[i] − aq [i]

∧ s[i] > 0









Tricky: permutation predicate perm(a, b)
Define identifiers:
perm(a, b) ∧ ∀i. b[i] = a[i] + 1
Bounded case for integer-indexed arrays:
n identifiers
a[0] = n ∧ b[0] = 0 ∧ perm(a, b, 0, n)
∧ ∀i. 0 < i ≤ n → 0 ≤ a[i], b[i] ≤ n ∧ b[i] = a[i] + 1
Unbounded case:
∃a, d, e, z, n. ∀i, j.

θ(z)
 
 


(d[j] > 0 ∧ d[j] = d[i] + 1)



 




∨
(d[j]
<
0
∧
d[j]
=
d[i]
−
1)


 ∧ 

_




→
ρ
(i,
j)
x


x

 ∧ a [n] = 0
q

∧ d[z] = 0 ∧ perm(d, e) ∧ ∀i. e[i] = d[i] + 1














Open:
∀i, j. i 6= j → a[i] 6= a[j]
• For integer-indexed arrays: undecidable
• Otherwise: ?
Incremental Instantiation
1. Instantiate F to F ′
2. Find I
|= F ′ (otherwise, F is unsatisfiable)
3. Construct G
4. Find J
: ¬F [I]
|= G (otherwise, F is satisfiable)
5. Enlarge instantiation set (according to I and J ) and repeat
May avoid full instantiation (whether satisfiable or unsatisfiable)
Summary
• Array property fragments allow encoding
– properties of arrays and array segments
– operations on sets, multisets, and hashtables
• Simple decision procedure: quantifier instantiation
• Larger natural fragments are undecidable