Skip to main content
The Z3 .NET API provides a modern, object-oriented interface to Z3 for C#, F#, and other .NET languages.

Basic Workflow

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

Hello Z3

Let’s start with a minimal example:
The Context class implements IDisposable. Always use using statements or manually call Dispose() to prevent memory leaks.

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

F# Example

Z3 works beautifully with F#:

Printing and Debugging

Using LINQ with Z3

You can use LINQ for cleaner code:

Best Practices

  1. Always use using statements for Context to ensure proper disposal
  2. Enable model generation if you need solutions: cfg["model"] = "true"
  3. Use typed expressions (IntExpr, BoolExpr, etc.) for type safety
  4. Check solver status before accessing Model property
  5. Use Push/Pop for incremental solving to avoid recreating contexts
  6. Handle Z3Exception in production code
  7. Set timeouts for potentially long-running queries
Always check the solver status before accessing the Model property. Accessing it when the result is not SATISFIABLE will throw an exception.

Next Steps

API Reference

Explore the complete .NET API

.NET Examples

View more examples on GitHub

Z3 Guide

Interactive Z3 tutorial

NuGet Package

Official NuGet package