Skip to main content
The Z3 Java API provides an object-oriented interface to Z3, making it easy to use from Java applications.

Basic Workflow

A typical Z3 Java program follows this pattern:
  1. Create a Context (manages all Z3 objects)
  2. Create expressions and constraints
  3. Create a Solver and add assertions
  4. Check satisfiability
  5. Extract results (models, proofs, etc.)
  6. Dispose the context

Hello Z3

Let’s start with a minimal example:
The Context implements AutoCloseable, so use try-with-resources to ensure proper cleanup.

Creating a Context

The Context is the central object that manages all Z3 operations:

Creating Expressions

Boolean Expressions

Integer Expressions

Real Expressions

Using Solvers

Basic Solving

Incremental Solving with Push/Pop

Complete Example: Proving De Morgan’s Law

Prove that ¬(x ∧ y) ⟺ (¬x ∨ ¬y):

Complete Example: Solving Equations

Find values satisfying a system of equations:

Working with Arrays

Working with Quantifiers

Exception Handling

Printing and Debugging

Best Practices

  1. Always use try-with-resources for Context to ensure proper cleanup
  2. Enable model generation if you need to extract solutions: cfg.put("model", "true")
  3. Use typed expressions (IntExpr, BoolExpr, etc.) for type safety
  4. Check solver status before accessing models or proofs
  5. Use push/pop for incremental solving to avoid recreating contexts
  6. Handle Z3Exception in production code
Always check the solver status before calling getModel(). Calling it on an unsatisfiable result will throw an exception.

Next Steps

API Reference

Explore the complete Java API

Java Examples

View more examples on GitHub

Z3 Guide

Interactive Z3 tutorial