Skip to main content
The array theory in Z3 provides reasoning about arrays with arbitrary index and element types. Arrays follow the theory of extensionality: two arrays are equal if they have the same values at all indices.

Array Sorts

Create an array sort with index and element types:
C API: Z3_mk_array_sort(c, domain, range) (api_array.cpp:26)

Multi-Dimensional Arrays

Create arrays with multiple indices:
C API: Z3_mk_array_sort_n(c, n, domain, range) (api_array.cpp:37)

Basic Operations

Select

Read a value from an array at a given index:
C API: Z3_mk_select(c, a, i) (api_array.cpp:51) Multi-index: Z3_mk_select_n(c, a, n, idxs) (api_array.cpp:76)

Store

Write a value to an array at a given index:
C API: Z3_mk_store(c, a, i, v) (api_array.cpp:106) Multi-index: Z3_mk_store_n(c, a, n, idxs, v) (api_array.cpp:134)

Array Properties

Extensionality

Arrays are equal if they have the same values at all indices:

Default Values

Arrays can have default values for uninitialized indices:
C API: Z3_mk_const_array(c, domain, v) creates array where all elements equal v (api_array.cpp:191)

Array Default Accessor

Get the default value of an array: C API: Z3_mk_array_default(c, array) (api_array.cpp:210)

Advanced Operations

Map

Apply a function to every element of arrays:
C API: Z3_mk_map(c, f, n, args) (api_array.cpp:166)

Array Extensionality

Find an index where two arrays differ:
C API: Z3_mk_array_ext(c, arg1, arg2) returns an index where arrays differ if they’re not equal (api_array.cpp:270)

Set Operations

Z3 implements sets as arrays from elements to booleans:

Empty and Full Sets

C API: Z3_mk_empty_set, Z3_mk_full_set (api_array.cpp:247, 256)

Set Membership

C API: Z3_mk_set_member(c, elem, set) (api_array.cpp:284)

Set Operations

C API:
  • Z3_mk_set_union (api_array.cpp:265)
  • Z3_mk_set_intersect (api_array.cpp:266)
  • Z3_mk_set_difference (api_array.cpp:267)
  • Z3_mk_set_complement (api_array.cpp:268)
  • Z3_mk_set_subset (api_array.cpp:269)

Add/Remove Elements

C API: Z3_mk_set_add, Z3_mk_set_del (api_array.cpp:288, 292)

Complete Examples

Example 1: Array Update Sequence

Example 2: Array Equality

Example 3: Sparse Array Initialization

Example 4: Multi-Dimensional Array

Example 5: Set Operations

Example 6: As-Array Construction

Create an array from a function:
C API: Z3_mk_as_array(c, f) (api_array.cpp:272)

Query Functions

Get Array Sort Information

C API:
  • Z3_get_array_arity(c, s) - number of indices (api_array.cpp:302)
  • Z3_get_array_sort_domain(c, t) - domain sort (api_array.cpp:315)
  • Z3_get_array_sort_domain_n(c, t, idx) - nth domain sort (api_array.cpp:329)
  • Z3_get_array_sort_range(c, t) - range sort (api_array.cpp:343)

Theory Axioms

The array theory is defined by two key axioms:
  1. Read-over-Write (same index): Select(Store(A, i, v), i) = v
  2. Read-over-Write (different index): i ≠ j ⟹ Select(Store(A, i, v), j) = Select(A, j)
  3. Extensionality: (∀i. Select(A, i) = Select(B, i)) ⟹ A = B

Implementation Notes

  • Arrays are functional and immutable (Store creates a new array)
  • The theory is decidable for quantifier-free formulas
  • Array values are represented symbolically (not stored explicitly)
  • Efficient for sparse updates and reads
  • No built-in bounds checking (arrays are infinite)

References

  • Implementation: src/api/api_array.cpp
  • Theory plugin: src/ast/array_decl_plugin.h
  • Solver: src/smt/theory_array.h