Skip to main content
Model checking uses Z3 to verify that a system satisfies specified properties across all possible states and executions. This is essential for verifying hardware designs, protocols, and software systems.

When to Use Model Checking

Use Z3 for model checking when you need to:
  • Verify invariants: Prove properties hold in all reachable states
  • Check temporal properties: Verify safety and liveness properties
  • Validate protocols: Ensure communication protocols are correct
  • Verify hardware: Check circuit designs and RTL implementations
  • Prove program properties: Verify loop invariants and procedure contracts

Core Concepts

Transition Systems

A transition system consists of:
  1. State variables: Represent system state at a point in time
  2. Initial conditions: Constraints on starting states
  3. Transition relation: How states evolve
  4. Properties: Safety/liveness conditions to verify

Verification Approaches

  • Bounded Model Checking (BMC): Check properties up to depth k
  • Inductive reasoning: Prove properties by induction
  • IC3/PDR: Incremental construction of inductive invariants
  • Fixed-point computation: Using Datalog-style Horn clauses

Example: Traffic Light Controller

Verify a simple traffic light system using fixed-point computation:

Example: Rush Hour Puzzle Solver

Model the Rush Hour game as a transition system and find a solution path:

Example: IC3 Model Checker

Implement a simplified IC3/PDR algorithm for invariant checking:

Bounded Model Checking

Check properties up to a specific depth:

Verifying Algorithms

Verify sorting algorithm correctness:

Theory Solvers for Model Checking

Further Reading

  • examples/python/mini_ic3.py: Complete IC3 implementation
  • examples/python/trafficjam.py: Datalog-based model checking
  • examples/python/bounded model checking/: BMC examples