Skip to main content

Overview

Quantifiers allow expressing properties over infinite domains. Z3 supports:
  • Universal quantification (∀): “for all”
  • Existential quantification (∃): “there exists”
  • Lambda expressions: anonymous functions

Basic Quantifiers

Multiple Variables

Quantifier Example

From examples/c++/example.cpp:368:

Quantifier Instantiation

Z3 handles quantifiers through instantiation: replacing bound variables with concrete terms.

Instantiation Strategies

E-matching

Pattern-based instantiation using triggers

MBQI

Model-Based Quantifier Instantiation

QSAT

Quantified SAT encoding

QE

Quantifier Elimination (when applicable)

Patterns (Triggers)

Patterns guide when quantifiers should be instantiated:

Why Patterns Matter

Without patterns, Z3 may:
  • Instantiate too frequently (performance issues)
  • Instantiate too rarely (incompleteness)
  • Make poor instantiation choices
Good patterns balance coverage and efficiency.

Multi-Patterns

No Patterns

Explicitly exclude terms from triggering:

Quantifier Weights

Control instantiation priority:

Quantifier IDs and Skolem IDs

From src/api/api_quant.cpp:27:

Lambda Expressions

From src/api/api_quant.cpp:144:

Lambda with Arrays

Existential Quantifiers

Eliminating Existentials

Existential quantifiers can often be eliminated by Skolemization or quantifier elimination tactics.

Quantifier Alternation

Model-Based Quantifier Instantiation (MBQI)

Quantifier Elimination

From examples/c++/example.cpp:784:

Quantified Bit-Vectors

Quantified Arrays

Nested Quantifiers with Functions

Quantifier Debugging

Common Patterns

Axiomatizing Functions

Universal Constraints

Quantifier-Free Fragments

Whenever possible, use quantifier-free formulas. They’re much more efficient:
  • QF_LIA: Quantifier-Free Linear Integer Arithmetic
  • QF_BV: Quantifier-Free Bit-Vectors
  • QF_UFLIA: QF Linear Integer Arithmetic with Uninterpreted Functions

Performance Tips

Choose patterns that:
  • Cover all relevant terms
  • Avoid overly general triggers
  • Balance between too few and too many instantiations
Higher weights for less important quantifiers:
MBQI works well when the domain is effectively finite:
For linear arithmetic, quantifier elimination is often complete:
Prevent runaway instantiation:

Known Limitations

  • Quantifiers make satisfiability undecidable in general
  • Z3 may return unknown for complex quantified formulas
  • Poor patterns can cause non-termination or performance issues
  • Not all theories support effective quantifier reasoning

Expressions

Building quantified formulas

Solvers

Solving quantified formulas

Tactics

Quantifier elimination tactics

References

  • Quantifier API: src/api/api_quant.cpp
  • Quantifier theory: src/smt/smt_quantifier.cpp
  • Examples: examples/c++/example.cpp:368-392
  • Pattern matching: parsers/util/pattern_validation.h