A BDD-based symbolic model checking framework implementing classic algorithms from "Symbolic Model Checking: 10^20 States and Beyond" (Burch et al., 1990).
This library verifies finite-state systems using Binary Decision Diagrams, handling systems with millions to billions of states by representing state sets symbolically rather than explicitly enumerating them.
- Transition Systems: Symbolic Kripke structures with present/next-state variables
- CTL Model Checking: Full Computation Tree Logic (EX, AX, EF, AF, EG, AG, EU, AU)
- LTL Model Checking: Linear Temporal Logic via BΓΌchi automata
- Fairness Constraints: Strong and weak fairness for realistic liveness properties
- Counterexample Generation: Linear traces (safety) and lasso traces (liveness)
image(S, T): Forward reachability β βs. S(s) β§ T(s, s')preimage(S, T): Backward reachability β βs'. T(s, s') β§ S(s')- Existential quantification and variable renaming
examples/model-checking/
βββ Cargo.toml
βββ README.md
βββ guide/
β βββ main.typ # Typst documentation
βββ src/
β βββ lib.rs # Public API
β βββ transition.rs # Transition systems
β βββ ctl.rs # CTL model checking
β βββ ltl.rs # LTL model checking
β βββ fairness.rs # Fairness constraints
β βββ counterexample.rs # Counterexample generation
βββ examples/
βββ abp.rs # Alternating Bit Protocol
βββ hanoi.rs # Towers of Hanoi (planning)
βββ tictactoe.rs # Game solving (attractors)
βββ mutex.rs # Peterson's mutual exclusion
βββ philosophers.rs # Dining philosophers
βββ counter.rs # N-bit counter (scalability)
βββ traffic_light.rs # Traffic light controller
Demonstrates reliable communication over a lossy channel:
- Fairness: Shows why liveness requires fairness constraints
- Safety vs Liveness: AF fails without fairness, holds with fairness
- Key insight: Adversarial schedulers can always prevent progress
cargo run --example abp --releaseBDD-based symbolic planning for the classic puzzle:
- State space: 3^N configurations for N disks
- Optimal solution: Symbolic BFS finds 2^N-1 minimum moves
- Solution extraction: Displays step-by-step solution with visual diagrams
cargo run --example hanoi --releaseTwo-player game solving with attractor computation:
- Winning regions: Computes states where each player can force a win
- Drawing analysis: Confirms empty board is a draw with perfect play
- Attractor algorithm: Backward fixpoint for game-theoretic analysis
cargo run --example tictactoe --releasemutex.rs: Peterson's algorithm for mutual exclusionphilosophers.rs: Dining philosophers deadlock analysiscounter.rs: N-bit counter demonstrating BDD scalabilitytraffic_light.rs: Simple traffic light controller
Branching-time logic with path quantifiers (A/E) and temporal operators:
| Formula | Meaning |
|---|---|
EX Ο |
There exists a next state satisfying Ο |
AX Ο |
All next states satisfy Ο |
EF Ο |
There exists a path where Ο eventually holds |
AF Ο |
On all paths, Ο eventually holds |
EG Ο |
There exists a path where Ο always holds |
AG Ο |
On all paths, Ο always holds |
E[Ο U Ο] |
There exists a path where Ο holds until Ο |
A[Ο U Ο] |
On all paths, Ο holds until Ο |
Linear-time logic for reasoning about individual execution paths:
| Formula | Meaning |
|---|---|
X Ο |
Ο holds in the next state |
F Ο |
Ο eventually holds (Future) |
G Ο |
Ο always holds (Globally) |
Ο U Ο |
Ο holds until Ο becomes true |
Ο R Ο |
Ο holds until (and including when) Ο becomes true |
Fairness assumptions exclude unrealistic infinite behaviors:
- Strong fairness: If enabled infinitely often, happens infinitely often
- Weak fairness: If continuously enabled, eventually happens
// Without fairness: AF delivered FAILS (adversarial channel)
// With fairness: AF delivered HOLDS (realistic behavior)CTL operators are computed via least (ΞΌ) and greatest (Ξ½) fixpoints:
EF Ο = ΞΌZ. Ο β¨ EX Z [least fixpoint - start from β
]
EG Ο = Ξ½Z. Ο β§ EX Z [greatest fixpoint - start from all states]
When properties fail, counterexamples explain why:
-
Linear traces: Path from initial state to violation (safety)
-
Lasso traces: Stem + loop structure (liveness)
Linear: sβ β sβ β sβ β ... β sβ (bad) Lasso: [ sβ β sβ β ... β sβ ] β [ sβββ β ... β sβ β sβ ] β________________|Here, the loop from sβ to sβ demonstrates infinite violation.
use model_checking::*;
use bdd_rs::bdd::Bdd;
use std::rc::Rc;
// Create transition system
let bdd = Rc::new(Bdd::default());
let mut ts = TransitionSystem::new(bdd.clone());
// Declare state variable
let x = Var::new("x");
ts.declare_var(x.clone());
// Set initial state and transitions
let x_pres = ts.var_manager().get_present(&x).unwrap();
let initial = ts.bdd().apply_not(ts.bdd().mk_var(x_pres));
ts.set_initial(initial);
let x_trans = ts.assign_var(&x, ts.bdd().apply_not(ts.bdd().mk_var(x_pres)));
ts.set_transition(x_trans);
// Add labels and check properties
ts.add_label("on".to_string(), ts.bdd().mk_var(x_pres));
let ts = Rc::new(ts);
let checker = CtlChecker::new(ts.clone());
let property = CtlFormula::atom("on").ef(); // EF on
assert!(checker.holds_initially(&property));cargo test --libAll tests passing β
- Symbolic Model Checking: 10^20 States and Beyond β Burch et al. (1990)
- Model Checking β Clarke, Grumberg, Peled (1999)
- Principles of Model Checking β Baier & Katoen (2008)
- NuSMV 2.0 User Manual β Cimatti et al. (2002)