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