package theo
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=bdaa3e26ec5ab84a6a378693cdc4d5ca3470b52c9a36715e7ccb6543100281ed
sha512=9d3ac06b7dc9f154ac987cc376af5725bdbce326f245d5036ff54412eeae9edbca7cbeec60dbec3451122396a74699c9befcd238b47d4492334b86730e178e76
doc/theo/Theo/index.html
Module TheoSource
Theory-Augmented Binary Decision Diagrams (BDDs)
This module provides an efficient implementation of Binary Decision Diagrams with support for theory reasoning over linear orders and equality (including booleans, strings, integers, semantic versions).
BDDs are canonical representations of boolean functions that enable efficient logical operations and satisfiability checking through hash-consing and memoization.
Features:
- Automatic node sharing via hash-consing
- Memoized operations for performance
- Theory atoms: boolean tests, string equality, version comparisons
- Type-safe variable system using GADTs
Example usage:
module Theo = Theo.Make(Theo.Void)
let open Theo.Syntax in
let b1 = Theo.var Boolean in
let b2 = Theo.var Boolean in
let expr = Theo.atom b1 && not (Theo.atom b2) in
if Theo.is_tautology expr then Printf.printf "Always true\n"
else Printf.printf "Depends on variables\n"Architecture: The library is built around a few core concepts:
Make: The core BDD engine. It takes aTheoryas input and produces a BDD module.Theory: An interface for values that can be part of the BDD (e.g., integers, strings).Combine: A functor to combine two theories into one (sum type).Primitive_theory: Standard theories likeLeq(linear order) andEq(equality).
Example: Combining Theories To use multiple theories (e.g., String equality and Version comparisons) in the same BDD:
(* 1. Define your atomic types *)
module StringAtom = struct ... end (* implements Comparable *)
module VersionAtom = struct ... end (* implements Comparable *)
(* 2. Instantiate primitive theories *)
module StringEq = Theo.Eq(StringAtom)
module VersionLeq = Theo.Leq(VersionAtom)
(* 3. Combine them into a single theory *)
module MyTheory = Theo.Combine(VersionLeq)(StringEq)
(* 4. Create the BDD module *)
module MyBDD = Theo.Make(MyTheory)
(* 5. Instantiate syntax helpers for convenient construction *)
(* Notice we pass parts of the sum theory to the helpers *)
module V = VersionLeq.Syntax(MyTheory.Left(MyBDD))
module S = StringEq.Syntax(MyTheory.Right(MyBDD))
(* 6. Now you can mix them! *)
let v_var = MyBDD.var ()
let s_var = MyBDD.var ()
let expr = MyBDD.and_ V.(v_var < v) S.(s_var = s)Example: Working with Constraints You can also use the syntax modules to build restrict constraints, and pattern match on constraints using view_constraint.
(* 1. Build constraint syntax helpers *)
(* Instead of MyBDD, we pass MyBDD.Constraint to the syntax functors *)
module V_cstr = VersionLeq.Syntax (MyTheory.Left (MyBDD.Constraint))
module S_cstr = StringEq.Syntax (MyTheory.Right (MyBDD.Constraint))
(* 2. Create constraints *)
(* Note: These return atomic_constraint list, NOT a BDD *)
let c1 = V_cstr.(v_var < v)
let c2 = S_cstr.(s_var = s)
(* 3. Combine constraints *)
let constraints = MyBDD.Constraint.and_ c1 c2
(* 4. Restrict a BDD *)
let restricted_expr = MyBDD.restrict expr constraints
(* 5. Introspection (Pattern Matching) *)
let match_constraint (c : MyBDD.atomic_constraint) =
match MyBDD.view_constraint c with
| MyBDD.Constraint { var; payload = Bool; value } ->
Printf.printf "Bool var %d = %b" var value
| MyBDD.Constraint { var; payload = Theory desc; value } -> (
(* 'desc' is a 'desc MyTheory.t' (the sum type) *)
match desc with
| MyTheory.Left (VersionLeq.Bound { limit; inclusive }) ->
Printf.printf "Version <= %s is %b"
(VersionAtom.to_string limit)
value
| MyTheory.Right (StringEq.Const s) ->
Printf.printf "String = %s is %b" (StringAtom.to_string s) value
)Variables
The Core BDD Engine
Functor to create a BDD implementation for a specific theory.
The abstract interface for "formulas". This abstraction allows syntax helpers (like Leq.Syntax) to be reused with any BDD implementation that contains the appropriate theory.
Theory Composition
Combine(A)(B) creates a new theory that is the sum of A and B. This allows a single BDD to reason about multiple types of atoms simultaneously.
Primitive theories
Input signature for primitive theories.
Augmented theory interface for primitive theories.
The theory of linear order (<=, <, =, <>).
The theory of equality (=, <>).