ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
Expectation.h
Go to the documentation of this file.
1/**
2 * @file Expectation.h
3 * @brief Analytical expectation / variance / moment evaluator over RV circuits.
4 *
5 * Computes E[X], Var[X], raw moments E[X^k] and central moments
6 * E[(X - E[X])^k] over a sub-circuit rooted at a scalar gate
7 * (@c gate_value, @c gate_rv, or @c gate_arith), using closed-form
8 * formulas wherever the sub-DAG decomposes structurally and falling
9 * back to Monte Carlo (via @c monteCarloScalarSamples) when
10 * structural shortcuts cannot decide a sub-expression.
11 *
12 * Decomposition rules:
13 * - @c gate_value: literal, constant moments.
14 * - @c gate_rv: closed-form moments per @c RandomVariable.h.
15 * - @c gate_arith PLUS / MINUS / NEG: linearity of expectation always
16 * applies; variance and higher moments require structural
17 * independence of the children (their reachable @c gate_rv
18 * footprints must be pairwise disjoint).
19 * - @c gate_arith TIMES: requires structural independence; otherwise
20 * MC fallback.
21 * - @c gate_arith DIV: closed form when the divisor is a deterministic
22 * constant (@c gate_value), otherwise MC fallback.
23 *
24 * MC fallback is governed by the @c provsql.rv_mc_samples GUC:
25 * non-zero values pick the sample count; zero disables the fallback,
26 * causing the evaluator to throw rather than sample. This keeps a
27 * single knob shared with future RV-MC fallback paths (Priority 7's
28 * island decomposer).
29 */
30#ifndef PROVSQL_EXPECTATION_H
31#define PROVSQL_EXPECTATION_H
32
33#include <optional>
34
35#include "GenericCircuit.h"
36
37namespace provsql {
38
39/**
40 * @brief Compute @f$E[X]@f$ (or @f$E[X \mid A]@f$ if @p event_root is set)
41 * over the scalar sub-circuit rooted at @p root.
42 *
43 * The conditional path requires that @p event_root be a @c gate_t in
44 * the same @c GenericCircuit as @p root -- typically the circuit was
45 * loaded via @c getJointCircuit so a shared @c gate_rv between root
46 * and event has one @c gate_t, which is what couples the MC sampler.
47 * When @p event_root is @c std::nullopt the unconditional path
48 * (existing analytical decomposition with MC fallback) is taken
49 * unchanged.
50 *
51 * @throws CircuitException on malformed circuits, unknown
52 * distribution kinds, when @c provsql.rv_mc_samples is 0
53 * and a sub-expression cannot be decomposed analytically,
54 * or when the conditional MC pass accepts too few samples
55 * (suggesting @c P(A) is very small or zero).
56 */
57double compute_expectation(const GenericCircuit &gc, gate_t root,
58 std::optional<gate_t> event_root = std::nullopt);
59
60/**
61 * @brief Compute the raw moment @f$E[X^k]@f$ (or @f$E[X^k \mid A]@f$
62 * if @p event_root is set) for @c k >= 0.
63 *
64 * @c k = 0 returns 1; @c k = 1 delegates to @c compute_expectation.
65 */
66double compute_raw_moment(const GenericCircuit &gc, gate_t root, unsigned k,
67 std::optional<gate_t> event_root = std::nullopt);
68
69/**
70 * @brief Compute the central moment @f$E[(X - E[X])^k]@f$
71 * (or @f$E[(X - E[X \mid A])^k \mid A]@f$ if @p event_root is set).
72 *
73 * @c k = 0 returns 1; @c k = 1 returns 0; @c k = 2 returns the
74 * variance. Higher orders are obtained by binomial
75 * expansion in terms of the raw moments returned by
76 * @c compute_raw_moment, which inherits the analytical / MC dispatch
77 * described above.
78 */
79double compute_central_moment(const GenericCircuit &gc, gate_t root, unsigned k,
80 std::optional<gate_t> event_root = std::nullopt);
81
82/**
83 * @brief Compute the p-quantile @f$F^{-1}(p)@f$ of the scalar rooted at
84 * @p root (of the truncated distribution if @p event_root is set).
85 *
86 * Requires @f$p \in [0, 1]@f$ (the caller validates); @c p = 0 / 1
87 * return the (truncated) support edges. Analytic for a bare
88 * @c gate_rv -- the family's elementary inverse CDF where one exists,
89 * the generic monotone-CDF bisection (@c numericQuantile) otherwise --
90 * and exact for a categorical mixture; compound scalar circuits fall
91 * back to the empirical Monte Carlo quantile (linear interpolation,
92 * the @c percentile_cont convention) at the @c provsql.rv_mc_samples
93 * budget, with the same conditional-acceptance guards as the moment
94 * estimators.
95 */
96double compute_quantile(const GenericCircuit &gc, gate_t root, double p,
97 std::optional<gate_t> event_root = std::nullopt);
98
99/**
100 * @brief Probability that the Boolean subcircuit rooted at @p boolRoot
101 * evaluates to @c true under the tuple-independent
102 * probabilistic-database model.
103 *
104 * Tries @c BooleanCircuit::independentEvaluation first; if that throws
105 * (e.g. the subcircuit is not disconnected for that method), falls
106 * back to Monte Carlo with @c provsql.rv_mc_samples samples. Used by
107 * the mixture moment evaluators for compound Boolean Bernoulli wires.
108 */
109double evaluateBooleanProbability(const GenericCircuit &gc, gate_t boolRoot);
110
111/**
112 * @brief Normalise conditioning in a scalar sub-circuit before evaluation.
113 *
114 * Peels a conditioned ROOT to its bare target and rewrites every buried
115 * @c gate_conditioned into a transparent passthrough, folding all collected
116 * evidence (and any pre-existing @p event_opt) into a single conditioning
117 * event left in @p event_opt. Returns the (possibly new) root so a stored
118 * "X | C" reaching a low-level RV entry point evaluates as the bare scalar
119 * conditioned on the folded event -- keeping the closed-form path available.
120 * No-op (returns @p root, leaves @p event_opt untouched) when there is no
121 * conditioning.
122 */
123gate_t lift_conditioning(GenericCircuit &gc, gate_t root,
124 std::optional<gate_t> &event_opt);
125
126} // namespace provsql
127
128#endif // PROVSQL_EXPECTATION_H
gate_t
Strongly-typed gate identifier.
Definition Circuit.h:49
Semiring-agnostic in-memory provenance circuit.
double compute_raw_moment(const GenericCircuit &gc, gate_t root, unsigned k, std::optional< gate_t > event_root)
Compute the raw moment (or if event_root is set) for k >= 0.
double compute_quantile(const GenericCircuit &gc, gate_t root, double p, std::optional< gate_t > event_root)
Compute the p-quantile of the scalar rooted at root (of the truncated distribution if event_root is ...
gate_t lift_conditioning(GenericCircuit &gc, gate_t root, std::optional< gate_t > &event_opt)
Lift conditioning out of a scalar arithmetic expression.
double compute_central_moment(const GenericCircuit &gc, gate_t root, unsigned k, std::optional< gate_t > event_root)
Compute the central moment (or if event_root is set).
double evaluateBooleanProbability(const GenericCircuit &gc, gate_t boolRoot)
Probability that the Boolean subcircuit rooted at boolRoot evaluates to true under the tuple-independ...
double compute_expectation(const GenericCircuit &gc, gate_t root, std::optional< gate_t > event_root)
Compute (or if event_root is set) over the scalar sub-circuit rooted at root.