48 std::vector<gate_t> stack{g};
50 while(!stack.empty()) {
51 const gate_t u = stack.back();
68 "The requested semiring does not admit a homomorphism "
69 "from Boolean functions; this gate's wires were rewritten "
70 "under a Boolean-only rule (times-idempotence or "
71 "times-absorbs-plus, applied under the 'boolean' "
72 "provenance class) and the evaluation is unsound under "
73 "this semiring. Re-run under a more general provenance "
74 "class, or pick a Boolean-compatible semiring (boolean, "
75 "boolexpr, formula, ...).");
83 && !
semiring.compatibleWithBooleanRewrite())
85 "The requested semiring is not absorptive; this gate's "
86 "wires were rewritten under an absorptive rule "
87 "(plus-idempotence, plus-with-one absorber or "
88 "plus-absorbs-times, applied under the 'absorptive' or "
89 "'boolean' provenance class) and the evaluation is "
90 "unsound under this semiring. Re-run under the "
91 "'semiring' provenance class, or pick an absorptive "
92 "semiring (probability, boolean, nonnegative "
95 if(provenance_mapping.find(u) != provenance_mapping.end()) {
109 provenance_mapping.emplace(u,
semiring.one());
113 provenance_mapping.emplace(u,
semiring.zero());
145 const std::string assumption =
getExtra(u);
146 if(assumption.empty() || assumption ==
"boolean") {
147 if(!
semiring.compatibleWithBooleanRewrite())
149 "The requested semiring does not admit a homomorphism "
150 "from Boolean functions; the wrapped sub-circuit was "
151 "computed under a Boolean-provenance assumption "
152 "(typically by the safe-query rewrite, "
153 "provenance class 'boolean') and the evaluation is "
154 "unsound under this semiring. Re-run the query under "
155 "a more general provenance class, or pick a "
156 "Boolean-compatible semiring (boolean, boolexpr, "
158 }
else if(assumption ==
"absorptive") {
161 "The requested semiring is not absorptive; the "
162 "wrapped sub-circuit only represents the absorptive "
163 "quotient of a recursive query's provenance "
164 "(fixpoint truncation or compiled reachability "
165 "circuit), so its value is only defined for "
166 "absorptive semirings (probability, boolean, "
167 "formula-with-absorption, nonnegative tropical, "
168 "...). Counting and why-provenance of cyclic "
169 "recursion are genuinely infinite; on acyclic "
170 "data, re-run under the 'semiring' provenance "
196 "Unknown assumption marker '" + assumption +
"'");
205 "Comparison operator OID " +
218 if(provenance_mapping.find(c) == provenance_mapping.end()) {
226 const auto childValue = [&](
int i) ->
const typename S::value_type & {
227 return provenance_mapping.at(
getWires(u)[i]);
234 std::vector<typename S::value_type> childrenResult;
236 childrenResult.push_back(provenance_mapping.at(c));
238 childrenResult.erase(std::remove(std::begin(childrenResult), std::end(childrenResult),
semiring.zero()),
239 childrenResult.end());
240 provenance_mapping.emplace(u,
semiring.plus(childrenResult));
243 for(
const auto &c: childrenResult) {
250 provenance_mapping.emplace(u,
semiring.zero());
252 childrenResult.erase(std::remove(std::begin(childrenResult), std::end(childrenResult),
semiring.one()),
253 childrenResult.end());
254 provenance_mapping.emplace(u,
semiring.times(childrenResult));
257 if(childrenResult[0]==
semiring.zero() || childrenResult[0]==childrenResult[1])
258 provenance_mapping.emplace(u,
semiring.zero());
260 provenance_mapping.emplace(u,
semiring.monus(childrenResult[0], childrenResult[1]));
266 provenance_mapping.emplace(u,
semiring.delta(childValue(0)));
277 provenance_mapping.emplace(u, childValue(0));
284 provenance_mapping.emplace(u,
semiring.cmp(childValue(0), op, childValue(1)));
289 provenance_mapping.emplace(u,
semiring.semimod(childValue(0), childValue(1)));
298 std::vector<typename S::value_type> vec;
300 vec.push_back(provenance_mapping.at(c));
301 provenance_mapping.emplace(u,
semiring.agg(op, vec));
313 "The requested semiring does not support conditioning: "
314 "P(·|C) = P(·∧C)/P(C) needs a normalising division "
315 "no general semiring provides. A conditioned token is "
316 "evaluable only in the measure interpretation "
317 "(probability_evaluate, or the random-variable / agg_token "
318 "distribution evaluators).");
332 const std::string key =
"L:";
333 std::size_t p = ex.find(key);
334 if(p != std::string::npos) {
335 std::size_t e = ex.find(
' ', p);
336 const std::string luid =
337 ex.substr(p + key.size(),
338 e == std::string::npos ? std::string::npos : e - p - key.size());
340 if(
getUUID(c) == luid) { lineage = c;
break; }
343 provenance_mapping.emplace(u, provenance_mapping.at(lineage));
345 provenance_mapping.emplace(u, childValue(0));
356 return provenance_mapping.at(g);