ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
SumCmpEvaluator.h
Go to the documentation of this file.
1/**
2 * @file SumCmpEvaluator.h
3 * @brief Closed-form probability resolution for HAVING
4 * @c SUM(a) @c op @c C @c gate_cmps via a weighted-sum DP.
5 *
6 * For comparators that reduce to
7 * @c gate_cmp(gate_agg(SUM, semimod_i(K_i, m_i)*), gate_value(C)) where
8 * the contributors are mutually independent Bernoulli trials (each K_i a
9 * private read-once sub-circuit, the same soundness contract as
10 * @c CountCmpEvaluator), the running sum @c S = sum of the present rows'
11 * integer weights @c m_i is a weighted Poisson-binomial. Its full
12 * distribution @c dp[s] = Pr(S = s) is computed by a subset-sum
13 * convolution -- @c dp'[s] = dp[s](1 - p_i) + dp[s - m_i] p_i per child --
14 * over the reachable range @c [sum of negative m_i, sum of positive m_i].
15 * The comparator's probability is then @c sum_{s : s op C} dp[s], with the
16 * empty-group world subtracted (see below). Cost @c O(N x R) where
17 * @c R is the reachable-sum range.
18 *
19 * **Pseudo-polynomial caveat.** @c R is linear in the magnitude of the
20 * weights and the threshold, i.e. exponential in their bit-length, so
21 * this DP is only pseudo-polynomial (unlike COUNT, where the analogous
22 * range is bounded by @c N). The pass therefore declines (leaving the
23 * cmp for @c provsql_having) when @c R exceeds @c kMaxSumRange, falling
24 * back to the general enumeration path.
25 *
26 * Soundness condition (checked per cmp gate, identical to
27 * @c CountCmpEvaluator) :
28 * - shape matches `gate_cmp(gate_agg(SUM, semimod_i(K_i, m_i)*), gate_value(C))`
29 * in either order ;
30 * - the aggregate is consumed by this cmp alone, each semimod by the
31 * aggregate alone, and every randomness-bearing gate inside each K_i
32 * has reference count 1 -- so the contributors are pairwise
33 * leaf-disjoint, private to the cmp, and individually read-once.
34 *
35 * Empty-group semantics mirror @c count_enum / @c CountCmpEvaluator : the
36 * all-absent world (the only world with no present row) never satisfies
37 * HAVING. Its sum is the empty sum @c 0, so when @c 0 @c op @c C holds
38 * its mass @c prod_i (1 - p_i) is subtracted from the answer. Worlds
39 * that are non-empty but happen to sum to @c 0 (a present @c m_i = 0, or
40 * cancelling signed weights) are legitimately kept.
41 *
42 * After replacement the cmp is a Bernoulli @c gate_input carrying the
43 * numeric probability, semantically meaningful only on the probability
44 * path. Like @c runCountCmpEvaluator, the pass runs inside
45 * @c probability_evaluate.cpp, gated on
46 * @c provsql.cmp_probability_evaluation, not at load time.
47 */
48#ifndef PROVSQL_SUM_CMP_EVALUATOR_H
49#define PROVSQL_SUM_CMP_EVALUATOR_H
50
51#include "GenericCircuit.h"
52
53namespace provsql {
54
55/**
56 * @brief Run the weighted-sum DP pre-pass over @p gc.
57 *
58 * For every @c gate_cmp whose shape matches a SUM(a) op C HAVING
59 * predicate over independent private contributors and whose reachable-sum
60 * range is within @c kMaxSumRange, computes the comparator's probability
61 * by the subset-sum DP and replaces the cmp by a Bernoulli @c gate_input
62 * via @c GenericCircuit::resolveCmpToBernoulli.
63 *
64 * @param gc Circuit to mutate in place.
65 * @return Number of comparators resolved by this pass.
66 */
67unsigned runSumCmpEvaluator(GenericCircuit &gc);
68
69} // namespace provsql
70
71#endif // PROVSQL_SUM_CMP_EVALUATOR_H
Semiring-agnostic in-memory provenance circuit.
unsigned runSumCmpEvaluator(GenericCircuit &gc)
Run the weighted-sum DP pre-pass over gc.