I’m pleased to announce the first release of Theo, an OCaml library for Binary Decision Diagrams (BDDs).
BDDs give you a canonical representation of boolean functions: two logically equivalent formulas always produce the exact same structure, so checking equivalence becomes a pointer comparison, O(1). Theo’s key extension is theory support: atoms aren’t just boolean variables but constraints like ocaml >= 4.14 or name = "foo", and the engine understands their semantics. This makes it practical for real-world constraint problems.
For example, a package manager can ask whether (ocaml >= 4.14 AND dune >= 3.0) OR (ocaml >= 5.0) is compatible with ocaml < 5.0. Theo reasons about the version constraints directly: it knows ocaml >= 4.14 is redundant when ocaml >= 5.0 holds, detects that the second disjunct contradicts ocaml < 5.0, and can extract the simplest satisfying assignment (ocaml >= 4.14, dune >= 3.0).
Highlights of the 0.1.0 release:
- Core BDD engine with hash-consing (via weak tables) and a canonical negative-edge form
- Boolean operations: AND, OR, NOT, IMPLIES, EQUIV, XOR, plus
exists/forallquantifiers - Pluggable theory support over linear orders and equality (booleans, strings, integers, semantic versions), with a
Combinefunctor to mix theories in the same BDD restrictfor partial evaluation under a set of external constraints, and constraint introspection via pattern matching- Minimal-witness extraction (shortest satisfying assignment) and zero-allocation entailment checks (implication, disjointness, exhaustiveness)
- Irredundant sum-of-products (Minato–Morreale) computation
- A property-based test suite
Some implementation details that may be of interest: memoization caches are built on ephemerons, so cache entries are reclaimed automatically once the BDD nodes they depend on become unreachable, with no manual cache invalidation and no leaks. Theory-aware simplification happens during BDD construction, using atom ordering to prune redundant bounds. The theory interface is a small functor-based API, and the same Syntax functor produces both BDD formulas and constraint lists.
I’ve written a companion blog post that walks through the main ideas: hash-consing and ephemeron caches, theory-aware simplification, and the algorithmic techniques behind restrict, minimal witnesses, and zero-allocation queries.
- Source: GitHub - vouillon/theo: A BDD library with theory support · GitHub
- API docs: Theo (theo.Theo)
- Install:
opam install theo
Feedback and contributions welcome!