|
| 1 | +//! # Bottom-up compiler for Sentential Decision Diagrams. |
| 2 | +//! |
| 3 | +//! Incrementally build, manipualate, and optimize |
| 4 | +//! [Sentential Decision Diagrams (SDD)](https://en.wikipedia.org/wiki/Sentential_decision_diagram): |
| 5 | +//! a succinct representation of Boolean functions. |
| 6 | +//! |
| 7 | +//! The compiler currently supports: |
| 8 | +//! * incremental compilation of Boolean functions (knowledge bases) to *compressed* and *trimmed* SDDs, |
| 9 | +//! * efficient querying of model count, model enumeration, and equivalence of SDDs, |
| 10 | +//! * dynamic minimization of SDDs via *vtree fragments*, |
| 11 | +//! * garbage collection of dead nodes, |
| 12 | +//! * SDD compilation from CNF in |
| 13 | +//! [DIMACS](https://www21.in.tum.de/~lammich/2015_SS_Seminar_SAT/resources/dimacs-cnf.pdf) format. |
| 14 | +//! |
| 15 | +//! |
| 16 | +//! |
| 17 | +//! |
| 18 | +//! |
| 19 | +//! |
| 20 | +//! The following snippet compiles the function `(A ∧ B) ∨ C` to SDD, |
| 21 | +//! computes number of its models, enumerates and prints them to the stdout, |
| 22 | +//! and renders the compiled SDD and its vtree to the DOT format. |
| 23 | +//! |
| 24 | +//! ```rust |
| 25 | +//! use sddrs::manager::{options, GCStatistics, SddManager}; |
| 26 | +//! use sddrs::literal::literal::Polarity; |
| 27 | +//! use bon::arr; |
| 28 | +//! |
| 29 | +//! fn main() { |
| 30 | +//! let options = options::SddOptions::builder() |
| 31 | +//! // Create right-linear vtree. |
| 32 | +//! .vtree_strategy(options::VTreeStragey::RightLinear) |
| 33 | +//! // Initialize the manager with variables A, B, and C. |
| 34 | +//! .variables(["A".to_string(), "B".to_string(), "C".to_string()]) |
| 35 | +//! .build(); |
| 36 | +//! let manager = SddManager::new(options); |
| 37 | +//! |
| 38 | +//! // Retrieve SDDs for literals A, B, and C. |
| 39 | +//! let a = manager.literal("A", Polarity::Positive).unwrap(); |
| 40 | +//! let b = manager.literal("B", Polarity::Positive).unwrap(); |
| 41 | +//! let c = manager.literal("C", Polarity::Positive).unwrap(); |
| 42 | +//! |
| 43 | +//! // Compute "A ∧ B" |
| 44 | +//! let a_and_b = manager.conjoin(&a, &b); |
| 45 | +//! // Compute "(A ∧ B) ∨ C" |
| 46 | +//! let a_and_b_or_c = manager.disjoin(&a_and_b, &c); |
| 47 | +//! |
| 48 | +//! let model_count = manager.model_count(&a_and_b_or_c); |
| 49 | +//! let models = manager.model_enumeration(&a_and_b_or_c); |
| 50 | +//! |
| 51 | +//! println!("'(A ∧ B) ∨ C' has {model_count} models."); |
| 52 | +//! println!("They are:\n{models}"); |
| 53 | +//! |
| 54 | +//! let sdd_path = "my_formula.dot" |
| 55 | +//! let f = File::create(sdd_path).unwrap(); |
| 56 | +//! let mut b = BufWriter::new(f); |
| 57 | +//! manager |
| 58 | +//! .draw_sdd(&mut b as &mut dyn std::io::Write, &sdd) |
| 59 | +//! .unwrap(); |
| 60 | +//! |
| 61 | +//! let vtree_path = "my_vtree.dot" |
| 62 | +//! let f = File::create(vtree_path).unwrap(); |
| 63 | +//! let mut b = BufWriter::new(f); |
| 64 | +//! manager |
| 65 | +//! .draw_vtree(&mut b as &mut dyn std::io::Write) |
| 66 | +//! .unwrap(); |
| 67 | +//! |
| 68 | +//! println!("Rendered SDD to '{sdd_path}' and vtree to '{vtree_path}'"); |
| 69 | +//! } |
| 70 | +//! ``` |
| 71 | +//! |
| 72 | +//! --- |
| 73 | +//! |
| 74 | +//! Main methods to compile SDDs are: |
| 75 | +//! |
| 76 | +//! * [`crate::manager::SddManager::conjoin`] -- compute AND of two SDDs |
| 77 | +//! * [`crate::manager::SddManager::disjoin`] -- compute OR of two SDDs |
| 78 | +//! * [`crate::manager::SddManager::imply`] -- compute implication of two SDDs |
| 79 | +//! * [`crate::manager::SddManager::equiv`] -- compute equivalence of two SDDs |
| 80 | +//! * [`crate::manager::SddManager::negate`] -- compute negation of SDD |
| 81 | +//! |
| 82 | +//! Main methods to query SDDs are: |
| 83 | +//! |
| 84 | +//! * [`crate::manager::SddManager::model_count`] -- count the number of models of an SDD |
| 85 | +//! * [`crate::manager::SddManager::model_enumeration`] -- enumerate models of an SDD |
| 86 | +//! * [`crate::sdd::SddRef::size`] -- get size of the SDD |
| 87 | +//! |
| 88 | +//! SDDs can be also minimized after compilation by appropriately manipulating the vtree: |
| 89 | +//! |
| 90 | +//! * [`crate::manager::SddManager::swap`] -- swap children of a vtree and adjust SDDs |
| 91 | +//! * [`crate::manager::SddManager::rotate_right`] -- rotate vtree node to the right and adjust SDDs |
| 92 | +//! * [`crate::manager::SddManager::rotate_left`] -- rotate vtree node to the left and adjust SDDs |
| 93 | +//! |
| 94 | +//! These transformations do not guarantee that the SDD will decrease in size. In fact, it may grow. |
| 95 | +//! For this purpose, dynamic minimization via [`crate::vtree::fragment::Fragment`] tries to find |
| 96 | +//! the vtree that actually minimizes the SDD the most [`crate::manager::SddManager::minimize`]. |
| 97 | +//! |
| 98 | +//! There are also additional helper functions: |
| 99 | +//! |
| 100 | +//! * [`crate::manager::SddManager::from_dimacs`] -- compile SDD based on a DIMACS CNF file |
| 101 | +//! * [`crate::manager::SddManager::draw_sdd`] -- draw a particular SDD to a DOT Graphviz format |
| 102 | +//! * [`crate::manager::SddManager::draw_all_sdds`] -- draw every SDDs to a DOT Graphviz format |
| 103 | +//! * [`crate::manager::SddManager::draw_vtree`] -- draw vtree a DOT Graphviz format |
| 104 | +//! |
| 105 | +//! |
| 106 | +//! Additional resources: |
| 107 | +//! |
| 108 | +//! * [SDD: A New Canonical Representation of Propositional Knowledge Bases - Adnad Darwiche](http://reasoning.cs.ucla.edu/fetch.php?id=121&type=pdf): |
| 109 | +//! paper introducing SDDs |
| 110 | +//! * [Dynamic Minimization of Sentential Decision Diagrams - Arthur Choi and Adnan Darwiche](http://reasoning.cs.ucla.edu/fetch.php?id=128&type=pdf): |
| 111 | +//! paper describing dynamic minimization of SDDs |
| 112 | +//! * [SDD: A New Canonical Representation of Propositional Knowledge Bases – Adnan Darwiche](https://www.youtube.com/watch?v=_5Estmve91o): YouTube tutorial |
| 113 | +
|
| 114 | +/// Variables, polarities, and literals. |
1 | 115 | pub mod literal;
|
2 | 116 | pub mod manager;
|
3 | 117 | pub mod sdd;
|
4 | 118 | #[macro_use]
|
5 |
| -pub mod util; |
6 |
| -pub mod dot_writer; |
| 119 | +pub(crate) mod util; |
| 120 | +pub(crate) mod dot_writer; |
7 | 121 | pub mod vtree;
|
0 commit comments