ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
dDNNFTreeDecompositionBuilder.h
Go to the documentation of this file.
1/**
2 * @file dDNNFTreeDecompositionBuilder.h
3 * @brief Constructs a d-DNNF from a Boolean circuit and its tree decomposition.
4 *
5 * @c dDNNFTreeDecompositionBuilder implements the knowledge-compilation
6 * algorithm described in:
7 * > A. Amarilli, F. Capelli, M. Monet, P. Senellart,
8 * > "Connecting Knowledge Compilation Classes and Width Parameters".
9 * > Theory of Computing Systems 64(5):861–914, 2020.
10 * > https://doi.org/10.1007/s00224-019-09930-2
11 *
12 * The algorithm traverses the tree decomposition bottom-up. At each
13 * bag it enumerates *valuations* (assignments of Boolean values to the
14 * gates in the bag) that are consistent with the circuit's constraints.
15 * For each valuation it builds a d-DNNF AND gate whose children are the
16 * (negated) input gates for that valuation. The OR combination of all
17 * valid valuations at the root bag gives the final d-DNNF.
18 *
19 * ### Key types
20 * - @c valuation_t: a `flat_map<gate_t, bool>` (bounded by treewidth+1)
21 * mapping each in-bag gate to its truth value.
22 * - @c suspicious_t: a `flat_set<gate_t>` of gates whose values have not
23 * yet been "confirmed" by their responsible bag.
24 * - @c dDNNFGate: an intermediate gate in the constructed d-DNNF, bundling
25 * a gate ID with a valuation and a suspicious set.
26 * - @c gates_to_or_t: the main DP table mapping (valuation, suspicious)
27 * pairs to lists of @c dDNNFGate children to be OR'd.
28 *
29 * ### Usage
30 * ```cpp
31 * dDNNFTreeDecompositionBuilder builder(circuit, root_gate, td);
32 * dDNNF dd = std::move(builder).build();
33 * ```
34 */
35#ifndef dDNNF_TREE_DECOMPOSITION_BUILDER_H
36#define dDNNF_TREE_DECOMPOSITION_BUILDER_H
37
38#include <cassert>
39#include <unordered_map>
40#include <map>
41
42#include <boost/container/static_vector.hpp>
43
44#include "flat_map.hpp"
45#include "flat_set.hpp"
46#include "TreeDecomposition.h"
47#include "dDNNF.h"
48#include "BooleanCircuit.h"
49
50/**
51 * @brief Builds a d-DNNF from a Boolean circuit using a tree decomposition.
52 *
53 * This class is a one-shot builder: construct it, call @c build(), and
54 * the object is consumed (move-only).
55 */
57{
58public:
59/** @brief Stack-allocated vector bounded by the maximum treewidth + 1. */
60template<class T>
61using small_vector = boost::container::static_vector<T, TreeDecomposition::MAX_TREEWIDTH+1>;
62
63/** @brief Partial assignment of truth values to the gates of a bag. */
65
66/** @brief Set of gates whose truth-value assignments are not yet confirmed. */
68
69/** @brief Generic bounded-capacity vector for intermediate d-DNNF gates. */
70template<class T>
71using gate_vector_t = std::vector<T>;
72
73/** @brief Dynamic-programming table: (valuation, suspicious) → list of children. */
75 std::unordered_map<valuation_t, std::map<suspicious_t, gate_vector_t<gate_t> > >;
76
77private:
78const BooleanCircuit &c; ///< Source circuit
79gate_t root_id; ///< Root gate of the source circuit
80TreeDecomposition &td; ///< Tree decomposition of the circuit's primal graph
81dDNNF d; ///< The d-DNNF being constructed
82std::unordered_map<gate_t, bag_t> responsible_bag; ///< Maps each gate to its "responsible" bag
83std::unordered_map<gate_t, gate_t> input_gate; ///< Maps original IN gates to d-DNNF IN gates
84std::unordered_map<gate_t, gate_t> negated_input_gate; ///< Maps original IN gates to their negations
85std::set<std::pair<gate_t, gate_t> > wiresSet; ///< Set of all wires in the source circuit
86
87/**
88 * @brief Intermediate representation of a partially built d-DNNF gate.
89 *
90 * Each @c dDNNFGate carries a d-DNNF gate ID together with the current
91 * bag's valuation and the set of suspicious gates, allowing the DP
92 * algorithm to combine compatible gates across bags.
93 */
94struct dDNNFGate {
95 gate_t id; ///< Gate ID in the target d-DNNF
96 valuation_t valuation; ///< Current bag's truth-value assignment
97 suspicious_t suspicious;///< Gates whose assignments are unconfirmed
98
99 /**
100 * @brief Construct a @c dDNNFGate.
101 * @param i Gate ID in the target d-DNNF.
102 * @param v Current bag's truth-value assignment.
103 * @param s Set of suspicious (unconfirmed) gates.
104 */
106 id{i}, valuation{std::move(v)}, suspicious{std::move(s)} {
107 }
108};
109
110/**
111 * @brief Group a list of @c dDNNFGate entries by (valuation, suspicious) pairs.
112 *
113 * Used when processing a bag's children to identify which sub-results
114 * can be OR'd together.
115 *
116 * @param bag Current bag being processed.
117 * @param gates List of d-DNNF gates from child bags.
118 * @param partial Partially accumulated DP table from previous children.
119 * @return Updated DP table.
120 */
121[[nodiscard]] gates_to_or_t collectGatesToOr(
122 bag_t bag,
123 const gate_vector_t<dDNNFGate> &gates,
124 const gates_to_or_t &partial);
125
126/**
127 * @brief Build the d-DNNF contributions for a leaf bag.
128 *
129 * Enumerates all consistent valuations for the gates in the leaf bag
130 * and creates the corresponding d-DNNF AND gates.
131 *
132 * @param bag The leaf bag to process.
133 * @return List of @c dDNNFGate entries, one per consistent valuation.
134 */
136
137/**
138 * @brief Main recursive procedure: build the d-DNNF bottom-up.
139 *
140 * @return List of @c dDNNFGate entries at the root bag.
141 */
143
144/**
145 * @brief Return @c true if there is a wire from gate @p u to gate @p v.
146 * @param u Source gate.
147 * @param v Target gate.
148 * @return @c true if a wire from @p u to @p v exists in the source circuit.
149 */
150[[nodiscard]] bool circuitHasWire(gate_t u, gate_t v) const;
151
152/**
153 * @brief Return @c true if @p valuation is a "almost valuation".
154 *
155 * A valuation is "almost" if every gate in it that must have its value
156 * confirmed by the current bag has indeed been assigned a value.
157 *
158 * @param valuation The valuation to test.
159 * @return @c true if the valuation is consistent with circuit constraints.
160 */
161[[nodiscard]] bool isAlmostValuation(
162 const valuation_t &valuation) const;
163
164/**
165 * @brief Compute the subset of @p innocent that remains innocent.
166 *
167 * Returns the gates in @p innocent whose suspicious status is not
168 * overridden by @p valuation.
169 *
170 * @param valuation Current bag's valuation.
171 * @param innocent Candidate innocent set.
172 * @return The actually innocent gates.
173 */
174[[nodiscard]] suspicious_t getInnocent(
175 const valuation_t &valuation,
176 const suspicious_t &innocent) const;
177
178public:
179/**
180 * @brief Construct the builder for a specific circuit and tree decomposition.
181 *
182 * Pre-computes the wire set for fast @c circuitHasWire() queries.
183 *
184 * @param circuit Source Boolean circuit.
185 * @param gate Root gate of @p circuit to compile.
186 * @param tree_decomposition Tree decomposition of @p circuit's primal graph.
187 */
189 const BooleanCircuit &circuit,
190 gate_t gate,
191 TreeDecomposition &tree_decomposition) : c{circuit}, td{tree_decomposition}
192{
193 root_id = gate;
194
195 for(gate_t i{0}; i<c.getNbGates(); ++i)
196 for(auto g: c.getWires(i))
197 wiresSet.emplace(i,g);
198};
199
200/**
201 * @brief Execute the compilation and return the resulting d-DNNF.
202 *
203 * This is a move-only operation: the builder object is consumed.
204 *
205 * @return The compiled @c dDNNF (as an rvalue).
206 */
207[[nodiscard]] dDNNF&& build() &&;
208
209friend std::ostream &operator<<(std::ostream &o, const dDNNFGate &g);
210};
211
212/**
213 * @brief Debug output for a @c dDNNFTreeDecompositionBuilder::dDNNFGate.
214 * @param o Output stream.
215 * @param g Gate to display.
216 * @return Reference to @p o.
217 */
218std::ostream &operator<<(std::ostream &o, const dDNNFTreeDecompositionBuilder::dDNNFGate &g);
219
220#endif /* dDNNF_TREE_DECOMPOSITION_BUILDER_H */
Boolean provenance circuit with support for knowledge compilation.
gate_t
Strongly-typed gate identifier.
Definition Circuit.h:49
Tree decomposition of a Boolean circuit for knowledge compilation.
bag_t
Strongly-typed bag identifier for a tree decomposition.
Boolean circuit for provenance formula evaluation.
Tree decomposition of a Boolean circuit's primal graph.
std::unordered_map< gate_t, bag_t > responsible_bag
Maps each gate to its "responsible" bag.
bool circuitHasWire(gate_t u, gate_t v) const
Return true if there is a wire from gate u to gate v.
std::vector< T > gate_vector_t
Generic bounded-capacity vector for intermediate d-DNNF gates.
gate_vector_t< dDNNFGate > builddDNNF()
Main recursive procedure: build the d-DNNF bottom-up.
std::set< std::pair< gate_t, gate_t > > wiresSet
Set of all wires in the source circuit.
flat_map< gate_t, bool, small_vector > valuation_t
Partial assignment of truth values to the gates of a bag.
std::unordered_map< gate_t, gate_t > negated_input_gate
Maps original IN gates to their negations.
dDNNF && build() &&
Execute the compilation and return the resulting d-DNNF.
flat_set< gate_t, small_vector > suspicious_t
Set of gates whose truth-value assignments are not yet confirmed.
std::unordered_map< gate_t, gate_t > input_gate
Maps original IN gates to d-DNNF IN gates.
gates_to_or_t collectGatesToOr(bag_t bag, const gate_vector_t< dDNNFGate > &gates, const gates_to_or_t &partial)
Group a list of dDNNFGate entries by (valuation, suspicious) pairs.
gate_t root_id
Root gate of the source circuit.
boost::container::static_vector< T, TreeDecomposition::MAX_TREEWIDTH+1 > small_vector
Stack-allocated vector bounded by the maximum treewidth + 1.
dDNNF d
The d-DNNF being constructed.
const BooleanCircuit & c
Source circuit.
friend std::ostream & operator<<(std::ostream &o, const dDNNFGate &g)
Debug output for a dDNNFTreeDecompositionBuilder::dDNNFGate.
dDNNFTreeDecompositionBuilder(const BooleanCircuit &circuit, gate_t gate, TreeDecomposition &tree_decomposition)
Construct the builder for a specific circuit and tree decomposition.
std::unordered_map< valuation_t, std::map< suspicious_t, gate_vector_t< gate_t > > > gates_to_or_t
Dynamic-programming table: (valuation, suspicious) → list of children.
TreeDecomposition & td
Tree decomposition of the circuit's primal graph.
bool isAlmostValuation(const valuation_t &valuation) const
Return true if valuation is a "almost valuation".
suspicious_t getInnocent(const valuation_t &valuation, const suspicious_t &innocent) const
Compute the subset of innocent that remains innocent.
gate_vector_t< dDNNFGate > builddDNNFLeaf(bag_t bag)
Build the d-DNNF contributions for a leaf bag.
A d-DNNF circuit supporting exact probabilistic and game-theoretic evaluation.
Definition dDNNF.h:69
std::ostream & operator<<(std::ostream &o, const dDNNFTreeDecompositionBuilder::dDNNFGate &g)
Debug output for a dDNNFTreeDecompositionBuilder::dDNNFGate.
Decomposable Deterministic Negation Normal Form circuit.
Flat (unsorted, contiguous-storage) associative map template.
Flat (unsorted, contiguous-storage) set template.
Intermediate representation of a partially built d-DNNF gate.
suspicious_t suspicious
Gates whose assignments are unconfirmed.
valuation_t valuation
Current bag's truth-value assignment.
dDNNFGate(gate_t i, valuation_t v, suspicious_t s)
Construct a dDNNFGate.
Flat associative map with pluggable storage.
Definition flat_map.hpp:49
Flat set with pluggable storage.
Definition flat_set.hpp:41