23static std::vector<double> partialPMF(
const std::vector<double> &p,
26 const std::size_t N = p.size();
27 jmax = std::min(jmax, N);
28 std::vector<double> dp(jmax + 1, 0.0);
30 for (std::size_t i = 0; i < N; ++i) {
31 const double pi = p[i];
32 const double qi = 1.0 - pi;
35 const std::size_t upper = std::min(jmax, i + 1);
36 for (std::size_t j = upper; j >= 1; --j) {
37 dp[j] = dp[j] * qi + dp[j - 1] * pi;
47static double probZero(
const std::vector<double> &p)
50 for (
double pi : p) q *= (1.0 - pi);
62static double probAtLeast(
const std::vector<double> &p,
int T)
64 const int N =
static_cast<int>(p.size());
65 if (T <= 0)
return 1.0;
66 if (T > N)
return 0.0;
69 auto dp = partialPMF(p,
static_cast<std::size_t
>(T - 1));
71 for (
int j = 0; j <= T - 1; ++j) sum += dp[j];
74 std::vector<double> q(N);
75 for (
int i = 0; i < N; ++i) q[i] = 1.0 - p[i];
76 auto dp = partialPMF(q,
static_cast<std::size_t
>(N - T));
78 for (
int j = 0; j <= N - T; ++j) sum += dp[j];
87static double probAtMost(
const std::vector<double> &p,
int T)
89 const int N =
static_cast<int>(p.size());
90 if (T < 0)
return 0.0;
91 if (T >= N)
return 1.0;
94 auto dp = partialPMF(p,
static_cast<std::size_t
>(T));
96 for (
int j = 0; j <= T; ++j) sum += dp[j];
99 std::vector<double> q(N);
100 for (
int i = 0; i < N; ++i) q[i] = 1.0 - p[i];
101 auto dp = partialPMF(q,
static_cast<std::size_t
>(N - 1 - T));
103 for (
int j = 0; j <= N - 1 - T; ++j) sum += dp[j];
112static double probEqual(
const std::vector<double> &p,
int T)
114 const int N =
static_cast<int>(p.size());
115 if (T < 0 || T > N)
return 0.0;
118 auto dp = partialPMF(p,
static_cast<std::size_t
>(T));
121 std::vector<double> q(N);
122 for (
int i = 0; i < N; ++i) q[i] = 1.0 - p[i];
123 auto dp = partialPMF(q,
static_cast<std::size_t
>(N - T));
158static double cdfForOperator(
const std::vector<double> &p,
160 int C,
bool is_scalar)
162 const int N =
static_cast<int>(p.size());
169 r = probAtLeast(p, std::max(C, 1));
173 r = probAtLeast(p, std::max(C + 1, 1));
178 const int T = std::min(C, N);
179 r = (T < 1) ? 0.0 : probAtMost(p, T) - probZero(p);
183 const int T = std::min(C - 1, N);
184 r = (T < 1) ? 0.0 : probAtMost(p, T) - probZero(p);
188 r = (C < 1 || C > N) ? 0.0 : probEqual(p, C);
193 const double nonempty = 1.0 - probZero(p);
194 const double eq = (C >= 1 && C <= N) ? probEqual(p, C) : 0.0;
199 if (is_scalar && zeroSatisfies(op, C))
208 unsigned resolved = 0;
213 std::vector<gate_t> cmps;
214 for (std::size_t i = 0; i < nb; ++i) {
215 auto g =
static_cast<gate_t>(i);
219 if (cmps.empty())
return 0;
244 for (
long m : match.
ms)
if (m != 1) { all_one =
false;
break; }
245 if (!all_one)
continue;
249 const auto &semimods = match.
semimods;
250 const auto &ks = match.
ks;
252 const int C =
static_cast<int>(match.
C);
286 if (ref[
static_cast<std::size_t
>(agg)] != 1)
continue;
288 std::vector<double> p;
289 p.reserve(ks.size());
290 for (std::size_t i = 0; i < ks.size(); ++i) {
291 if (ref[
static_cast<std::size_t
>(semimods[i])] != 1) { sound =
false;
break; }
296 if (!sound)
continue;
300 const bool is_scalar =
304 double pr = cdfForOperator(p, op, C, is_scalar);
307 if (pr < 0.0) pr = 0.0;
308 if (pr > 1.0) pr = 1.0;
Typed aggregation value, operator, and aggregator abstractions.
@ COUNT
COUNT(*) or COUNT(expr) → integer.
ComparisonOperator
SQL comparison operators used in gate_cmp circuit gates.
@ LE
Less than or equal (<=).
@ GE
Greater than or equal (>=).
gate_t
Strongly-typed gate identifier.
Shared machinery for the closed-form HAVING gate_cmp probability evaluators (Poisson-binomial COUNT,...
Closed-form Poisson-binomial CDF resolution for HAVING COUNT(*) op C gate_cmps.
gateType getGateType(gate_t g) const
Return the type of gate g.
std::vector< gate_t >::size_type getNbGates() const
Return the total number of gates in the circuit.
In-memory provenance circuit with semiring-generic evaluation.
void resolveCmpToBernoulli(gate_t g, double p)
Replace a gate_cmp by a constant Boolean leaf (gate_one for p == 1, gate_zero for p == 0) or by a Ber...
std::pair< unsigned, unsigned > getInfos(gate_t g) const
Return the integer annotation pair for gate g.
unsigned runCountCmpEvaluator(GenericCircuit &gc)
Run the Poisson-binomial pre-pass over gc.
std::vector< unsigned > computeRefCounts(const GenericCircuit &gc)
Reference count of every gate as a wire-target across the whole circuit.
bool matchAggCmp(GenericCircuit &gc, gate_t cmp, AggCmpMatch &out)
Try to match cmp against gate_cmp(gate_agg(α, semimod_i(K_i, m_i)*), gate_value(C)).
double contributorProb(const GenericCircuit &gc, gate_t g, const std::vector< unsigned > &ref, bool &ok)
Read-once marginal probability of a count/aggregate contributor (the K side of a semimod).
#define PROVSQL_AGG_SCALAR_FLAG
Scalar-aggregation flag, stored in the upper bit of a gate_agg's info2 (whose low 31 bits hold the ag...
Result of matching a gate_cmp against the canonical HAVING aggregate-comparison shape.
gate_t agg
the gate_agg operand of the cmp
long C
the constant threshold, on the same integer grid as ms
std::vector< gate_t > ks
the K side of each semimod (contributor root)
std::vector< gate_t > semimods
the per-child gate_semimod parents
std::vector< long > ms
the M side of each semimod (per-row value), scaled to a common integer grid (numeric / decimal-float ...
AggregationOperator agg_kind
effective aggregate (SUM-of-1s remapped to COUNT)
ComparisonOperator op
comparator, flipped if the agg sits on the right