Skip to main content

Getting Started with Z3 Python

This guide introduces the Z3 Python API through practical examples.

Your First Z3 Program

Let’s start with a simple constraint solving example:
Output:

Basic Concepts

Variables and Sorts

Z3 supports multiple data types (called “sorts”):

The Solver

The Solver class is the main interface for checking satisfiability:

Building Constraints

Z3 supports standard mathematical and logical operators:

Common Patterns

Working with Models

When a formula is satisfiable, you can extract a model:

Checking Multiple Constraints

You can check constraints incrementally:

Push and Pop (Backtracking)

Solvers support backtracking with push() and pop():

Real-World Examples

Example 1: Solving Equations

Solve for x and y in a system of equations:

Example 2: Boolean Logic (Socrates)

A classic logical reasoning example:

Example 3: Bitvector Arithmetic

Working with fixed-width integers:

Example 4: Formula Simplification

Z3 can simplify complex formulas:

Working with Different Types

Arrays

Z3 supports arrays (maps from indices to values):

Strings

String constraints and operations:

Unsat Cores

When constraints are unsatisfiable, identify the conflicting subset:

Best Practices

  1. Use appropriate sorts: Choose Int, Real, or BitVec based on your needs
  2. Leverage push/pop: For incremental solving and backtracking
  3. Simplify formulas: Use simplify() to reduce complexity
  4. Set timeouts: Use s.set('timeout', milliseconds) for long-running queries
  5. Check return values: Always check if check() returns sat, unsat, or unknown

Configuration and Parameters

Customize solver behavior:

Next Steps