ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
ComparatorResolution.cpp
Go to the documentation of this file.
1/**
2 * @file ComparatorResolution.cpp
3 * @brief Definition of @c resolveComparators (the shared comparator-
4 * resolution pipeline). @c booleanSubcircuitProbability is defined
5 * in @c probability_evaluate.cpp, where the method-dispatch
6 * machinery (@c EvalContext / @c MethodCatalog) lives.
7 */
9
11#include "AnalyticEvaluator.h"
12#include "CountCmpEvaluator.h"
13#include "HybridEvaluator.h"
14#include "MinMaxCmpEvaluator.h"
15#include "RangeCheck.h"
16#include "SumCmpEvaluator.h"
17
18#include <set>
19#include <stack>
20#include <string>
21#include <vector>
22
23extern "C" {
24#include "provsql_utils.h"
25#include "provsql_error.h"
26}
27
28namespace provsql {
29
30namespace {
31/// Gates reachable from @p r (for the pre-pass reduction NOTICE).
32std::size_t count_reachable(const GenericCircuit &gc, gate_t r)
33{
34 std::set<gate_t> seen;
35 std::stack<gate_t> stk;
36 stk.push(r);
37 while (!stk.empty()) {
38 gate_t g = stk.top(); stk.pop();
39 if (!seen.insert(g).second) continue;
40 for (gate_t c : gc.getWires(g)) stk.push(c);
41 }
42 return seen.size();
43}
44} // namespace
45
47 bool simplify, bool decompose)
48{
49 // Hybrid-evaluator value simplifier: constant-fold gate_arith, drop
50 // identity wires, collapse PLUS over independent RVs into a closed-form
51 // gate_rv. Runs before AnalyticEvaluator so newly-bare leaves unlock the
52 // closed-form CDF on the surrounding cmp, and before a re-pass of
53 // RangeCheck so the joint-conjunction pass benefits from constant folding.
54 // See the header for why the moment path passes simplify == false.
55 if (simplify && provsql_hybrid_evaluation) {
57 runRangeCheck(gc);
58 }
59
60 // Island decomposer: group continuous-island comparators by base-RV
61 // footprint overlap and inline a joint-distribution table (a gate_plus
62 // over gate_mulinputs) for each shared group, so correlated comparators
63 // stay correlation-aware through the Boolean translation. Runs before
64 // AnalyticEvaluator, which would otherwise resolve each shared comparator
65 // into an independent marginal Bernoulli. See the header for why the
66 // moment path passes decompose == false.
67 if (decompose && provsql_hybrid_evaluation)
68 runHybridDecomposer(gc, static_cast<unsigned>(provsql_rv_mc_samples));
69
70 const std::size_t gates_before = count_reachable(gc, root);
71
72 // AnalyticEvaluator decides residual continuous-RV comparators (singleton
73 // bare gate_rv vs gate_value, or two bare normals) by closed-form CDF,
74 // replacing each with a Bernoulli gate_input carrying the probability.
75 const unsigned analytic = runAnalyticEvaluator(gc);
76
77 // Closed-form HAVING cmp-probability evaluators: Poisson-binomial for
78 // COUNT(*) op C, the MIN / MAX closed forms, the weighted-sum DP for
79 // SUM(a) op C, and the hierarchical marginal-vector engine for the safe
80 // join shapes the flat pre-passes cannot certify independent.
81 unsigned count_cmp = 0, minmax = 0, sum = 0, agg_marginal = 0;
83 count_cmp = runCountCmpEvaluator(gc);
84 minmax = runMinMaxCmpEvaluator(gc);
85 sum = runSumCmpEvaluator(gc);
86 agg_marginal = runAggMarginalEvaluator(gc);
87 }
88
89 // Always-true HAVING rewrite (COUNT <= K with K >= N and duals): the sound
90 // TRUE-decision arm RangeCheck deliberately leaves undone.
91 const unsigned always_true = runHavingAlwaysTrueRewriter(gc);
92
93 const unsigned total =
94 analytic + count_cmp + minmax + sum + agg_marginal + always_true;
95 if (total > 0 && provsql_verbose >= 5) {
96 const std::size_t gates_after = count_reachable(gc, root);
97 std::vector<std::string> parts;
98 if (analytic > 0) parts.push_back(std::to_string(analytic) + " analytic");
99 if (count_cmp > 0) parts.push_back(std::to_string(count_cmp) + " Poisson-binomial");
100 if (minmax > 0) parts.push_back(std::to_string(minmax) + " min/max");
101 if (sum > 0) parts.push_back(std::to_string(sum) + " weighted-sum");
102 if (agg_marginal > 0) parts.push_back(std::to_string(agg_marginal) + " safe-join aggregate");
103 if (always_true > 0) parts.push_back(std::to_string(always_true) + " always-true");
104 std::string breakdown;
105 for (std::size_t i = 0; i < parts.size(); ++i) {
106 if (i > 0) breakdown += " + ";
107 breakdown += parts[i];
108 }
110 "gate_cmp expression was shortcut by probability-side pre-pass "
111 "(%s): provenance circuit reduced from %zu to %zu gates",
112 breakdown.c_str(), gates_before, gates_after);
113 }
114}
115
116} // namespace provsql
Exact closed-form HAVING COUNT(*) op C probability over safe-join lineage – the recursive marginal-ve...
Closed-form CDF resolution for trivial gate_cmp shapes.
gate_t
Strongly-typed gate identifier.
Definition Circuit.h:49
The single comparator-resolution pipeline and the single Boolean-subcircuit probability entry point,...
Closed-form Poisson-binomial CDF resolution for HAVING COUNT(*) op C gate_cmps.
Peephole simplifier for continuous gate_arith sub-circuits.
Closed-form probability resolution for HAVING MIN(a) op C and MAX(a) op C gate_cmps.
Support-based bound check for continuous-RV comparators.
Closed-form probability resolution for HAVING SUM(a) op C gate_cmps via a weighted-sum DP.
std::vector< gate_t > & getWires(gate_t g)
Return a mutable reference to the child-wire list of gate g.
Definition Circuit.h:140
In-memory provenance circuit with semiring-generic evaluation.
unsigned runAggMarginalEvaluator(GenericCircuit &gc)
Run the safe-join aggregate marginal-vector pre-pass over gc.
unsigned runCountCmpEvaluator(GenericCircuit &gc)
Run the Poisson-binomial pre-pass over gc.
unsigned runRangeCheck(GenericCircuit &gc)
Run the support-based pruning pass over gc.
unsigned runHybridSimplifier(GenericCircuit &gc)
Run the peephole simplifier over gc.
unsigned runMinMaxCmpEvaluator(GenericCircuit &gc)
Run the MIN / MAX closed-form pre-pass over gc.
unsigned runSumCmpEvaluator(GenericCircuit &gc)
Run the weighted-sum DP pre-pass over gc.
unsigned runHybridDecomposer(GenericCircuit &gc, unsigned samples)
Marginalise unresolved continuous-island gate_cmp gates into Bernoulli gate_input leaves.
unsigned runAnalyticEvaluator(GenericCircuit &gc)
Run the closed-form CDF resolution pass over gc.
unsigned runHavingAlwaysTrueRewriter(GenericCircuit &gc)
Probability-side pre-pass: rewrite HAVING-style gate_cmp gates that are provably TRUE on the agg's va...
void resolveComparators(GenericCircuit &gc, gate_t root, bool simplify, bool decompose)
Run the comparator-resolution pipeline on gc, rewriting every gate_cmp (RV comparison,...
int provsql_verbose
Verbosity level; controlled by the provsql.verbose_level GUC.
Definition provsql.c:93
int provsql_rv_mc_samples
Default sample count for analytical-evaluator MC fallbacks; 0 disables fallback (callers raise instea...
Definition provsql.c:100
bool provsql_cmp_probability_evaluation
Run closed-form / analytic probability evaluators for gate_cmps inside probability_evaluate (currentl...
Definition provsql.c:110
bool provsql_hybrid_evaluation
Run the hybrid-evaluator simplifier inside probability_evaluate; controlled by the provsql....
Definition provsql.c:109
Uniform error-reporting macros for ProvSQL.
#define provsql_notice(fmt,...)
Emit a ProvSQL informational notice (execution continues).
Core types, constants, and utilities shared across ProvSQL.