16#include <unordered_set>
43#include <unordered_map>
71 for (std::size_t i = 0; i < n; ++i) {
72 auto g =
static_cast<gate_t>(i);
77 std::vector<gate_t> kept;
78 kept.reserve(
wires.size());
80 if (gc.
getGateType(c) != identity) kept.push_back(c);
82 if (kept.size() !=
wires.size()) {
83 wires = std::move(kept);
103 std::unordered_map<gate_t, gate_t> subst;
104 for (std::size_t i = 0; i < n; ++i) {
105 auto g =
static_cast<gate_t>(i);
110 bool absorbed =
false;
118 if (absorbed)
continue;
124 for (
auto &kv : subst) {
126 while (subst.count(cur)) cur = subst[cur];
139 for (
const auto &kv : subst) {
141 gate_t target = kv.second;
142 if (g == target)
continue;
146 auto [ti1, ti2] = gc.
getInfos(target);
147 const unsigned NO_INFO =
static_cast<unsigned>(-1);
148 if (ti1 != NO_INFO || ti2 != NO_INFO) {
152 const std::string e = gc.
getExtra(target);
184 for (std::size_t i = 0; i < n; ++i) {
185 auto g =
static_cast<gate_t>(i);
189 bool any_rule_fired =
false;
196 std::unordered_set<gate_t> seen;
197 std::vector<gate_t> deduped;
198 deduped.reserve(
wires.size());
200 if (seen.insert(c).second) deduped.push_back(c);
202 if (deduped.size() !=
wires.size()) {
203 wires = std::move(deduped);
204 any_rule_fired =
true;
215 bool has_one =
false;
221 gc.
setWires(g, std::vector<gate_t>{});
224 any_rule_fired =
true;
241 const auto &wires_now = gc.
getWires(g);
242 if (wires_now.size() >= 2) {
243 std::unordered_set<gate_t> sibling_set(wires_now.begin(),
245 std::vector<gate_t> kept;
246 kept.reserve(wires_now.size());
247 bool dropped =
false;
248 for (
gate_t c : wires_now) {
252 if (w != c && sibling_set.count(w)) {
257 if (absorb) { dropped =
true;
continue; }
263 any_rule_fired =
true;
268 if (any_rule_fired) {
gate_t
Strongly-typed gate identifier.
Semiring-agnostic in-memory provenance circuit.
Exception type thrown by circuit operations on invalid input.
std::vector< gate_t > & getWires(gate_t g)
Return a mutable reference to the child-wire list of gate g.
gateType getGateType(gate_t g) const
Return the type of gate g.
virtual gate_t setGate(const uuid &u, gateType type)
Create or update the gate associated with UUID u.
void setGateType(gate_t g, gateType t)
Update the type of an existing gate.
std::vector< std::vector< gate_t > > wires
std::vector< gate_t >::size_type getNbGates() const
Return the total number of gates in the circuit.
virtual gate_t addGate()
Allocate a new gate with a default-initialised type.
In-memory provenance circuit with semiring-generic evaluation.
void setWires(gate_t g, std::vector< gate_t > w)
Replace the wires of g with w.
std::map< gate_t, std::pair< unsigned, unsigned > > infos
Per-gate (info1, info2) annotations.
std::map< gate_t, std::string > extra
Per-gate string extras.
gate_t addGate() override
Allocate a new gate with a default-initialised type.
std::set< gate_t > inputs
Set of input (leaf) gate IDs.
void foldSemiringIdentities()
Drop semiring identity wires and collapse single-wire gate_times / gate_plus to their lone non-identi...
std::vector< double > prob
Per-gate probability values.
void setInfos(gate_t g, unsigned info1, unsigned info2)
Set the integer annotation pair for gate g.
std::string getExtra(gate_t g) const
Return the string extra for gate g.
gate_t setGate(gate_type type) override
Allocate a new gate with type type and no UUID.
void markBooleanAssumed(gate_t g)
Mark gate g as Boolean-assumed (in-memory side band).
double getProb(gate_t g) const
Return the probability for gate g.
std::pair< unsigned, unsigned > getInfos(gate_t g) const
Return the integer annotation pair for gate g.
void setExtra(gate_t g, const std::string &ex)
Attach a string extra to gate g.
void foldBooleanIdentities()
Apply Boolean-only simplification rules to gate_plus and gate_times.
void setProb(gate_t g, double p)
Set the probability for gate g.