CNF preprocessing and vtree (variable tree) construction for circuit compilation and model counting.
vitri is a Rust library with a command-line front end. Given a DIMACS CNF it
produces:
- a reduced CNF, renumbered and self-describing;
- a vtree over it, one per independent component;
- a preprocessing record: the arithmetic that lifts a count over the reduced formula back to the original.
The output does not depend on a back end. It can be used with d-DNNF, SDD and tree decision diagram (TDD) compilers, or with any model counter that takes a vtree.
cargo build --release # ./target/release/vitri
cargo install --path . # or put `vitri` on your PATH, as the examples below assumePrerequisites and the vendored C++ build: docs/building.md.
$ vitri docs/example.cnf --out-dir bundle/ --budget-ms 60000
[simplify] 0 clauses removed, 0 literals shortened, 0 forced vars
[dve-round 1] 0 equiv + 3 dve eliminated, 13 clauses
[dve-total] 3 defined + 0 equiv + 0 free eliminated, 12 → 9 vars, 13 clauses
[portfolio] selected: flowcutter-incidence (metric=stddev, stddev=0.52, cost=41)
input: docs/example.cnf (12 vars, 25 clauses, mode mc)
reduced: 9 vars, 13 clauses (count(original) = count(reduced) * 2^0)
vtree: portfolio (9 leaves, 17 nodes)
components: 1 (0 free variables)
wrote: bundle/reduced.cnf
bundle/preprocess.json
bundle/vtree.vtree
bundle/components.json
elapsed: 20 msCompile bundle/reduced.cnf under bundle/vtree.vtree to get a count over the
reduced formula. The count of the original is
count(original) == count(reduced) * 2^count_lift_pow2 * weight_lift
with both lift values in preprocess.json. Components can also be compiled
separately, each under its own vtree, and the results multiplied.
--dot writes a Graphviz file next to every .vtree a run emits. For
docs/example.cnf, twelve variables in three groups of
four:
vitri docs/example.cnf --out-dir bundle/ --mode compile --vtree force --dot
dot -Tpng -Gbgcolor=white -Gsplines=ortho -Nwidth=0.75 -Gnodesep=0.5 \
bundle/vtree.dot -o bundle/vtree.pngNode fill is clause load. docs/vtrees.md describes the
constructions and how the portfolio selects among them.
--mode states what preprocessing must preserve. Without it the mode is read
from the instance's headers (c t <track>, c p show, c p weight).
| task | --mode |
|---|---|
| model counting | mc |
| weighted model counting | wmc |
| projected counting | pmc |
| projected weighted counting | pwmc |
| compilation (function-preserving) | compile |
The stages each mode permits are listed in
docs/preprocessing.md.
| file | contents |
|---|---|
reduced.cnf |
the formula to compile, renumbered and self-describing |
preprocess.json |
the lift, the variable map, the forced and free variables |
vtree.vtree |
the selected vtree |
components.json |
the connected-component split and how the component counts compose |
components/, candidates/ |
one .cnf + .vtree per component; runner-up vtrees under --candidates |
The show set and the weight table in the bundle come from preprocessing, not
from the input; read both from the bundle. docs/bundle.md
documents every field.
vitri --help lists every flag with its default. The binary is a thin shell
over the library: CnfFormula::from_dimacs → vitri::run →
VitriRun::write_to_dir, configured by one RunConfig whose Default is the
production configuration. API reference:
tractables.github.io/vitri.
docs/bundle.md— the output files, field by field.docs/preprocessing.md— what each stage removes and how the record restores the count.docs/vtrees.md— the vtree constructions, the portfolio, bringing your own decomposition.docs/showcase.md— every--vtreespec on one CNF.docs/env.md— theVITRI_*environment variables, all optional.docs/sat.md— the SAT solver vitri links and exposes.docs/building.md— toolchain, prerequisites, the vendored C++ build.
Apache License 2.0 (LICENSE). Third-party components and their
licences: THIRD-PARTY.md. The algorithms this tool builds
on: ACKNOWLEDGEMENTS.md. Contributing:
CONTRIBUTING.md.

