![]() |
ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
Classes | |
| struct | AggCmpMatch |
Result of matching a gate_cmp against the canonical HAVING aggregate-comparison shape. More... | |
| struct | DistSupport |
| A closed support interval [lo, hi] (±infinity for unbounded). More... | |
| class | Distribution |
| Abstract per-family continuous distribution. More... | |
| struct | DistributionFamily |
| A registered family's descriptor: its complete identity. More... | |
| struct | DistributionFamilyRegistrar |
| Static-initialisation helper: one per family implementation. More... | |
| struct | ComparatorRuleRegistrar |
| Static-initialisation helper: one per registered family pair. More... | |
| struct | ClosureTerm |
One wire of a PLUS under closure: a·Z + b for a base RV Z (dist non-null), or a pure additive constant b (dist null, a == 0). More... | |
| struct | ClosureRuleRegistrar |
| Static-initialisation helper: one per registered family pair. More... | |
| struct | ProductRuleRegistrar |
| Static-initialisation helper: one per registered family pair. More... | |
| struct | TransformRuleRegistrar |
| Static-initialisation helper: one per registered transform. More... | |
| struct | ConjugateRule |
| The conjugate update for one observation of a given likelihood family against the running posterior (= prior) family. More... | |
| struct | ConjugateRuleRegistrar |
| Static-initialisation helper: one per registered pair. More... | |
| class | BaseDistribution |
| Base holding the two parameters; subclasses add closed forms. More... | |
| struct | DTreeInterval |
A certified probability interval lower <= Pr <= upper. More... | |
| struct | ConditionalScalarSamples |
| Outcome of a conditional Monte Carlo sampling pass. More... | |
| struct | ConditionalScalarPairSamples |
Outcome of a conditional coupled-pair Monte Carlo pass: xs[i] / ys[i] are the two roots' values from the same accepted iteration. More... | |
| struct | WeightedPosterior |
| Outcome of a likelihood-weighting (importance-sampling) pass. More... | |
| struct | EvalContext |
| Per-evaluation circuit state threaded to a method's evaluate(). More... | |
| struct | Tolerance |
| class | ProbabilityMethod |
| Strategy interface: one concrete subclass per probability method. More... | |
| class | MethodCatalog |
Registry of ProbabilityMethod objects. More... | |
| struct | DistributionSpec |
| Parsed distribution spec (family + up to two parameters). More... | |
| struct | DistributionParam |
One parameter slot of a gate_rv, either a literal or a wire. More... | |
| struct | DistributionTemplate |
A gate_rv distribution spec that may carry wired (token) parameters – the parse-time counterpart of DistributionSpec. More... | |
| struct | TruncatedSingleRv |
| Detection result for a closed-form, optionally-truncated single-RV shape. More... | |
| struct | DiracShape |
Point mass at a finite scalar value (a gate_value root, or an as_random(c) leaf surfaced as a gate_value). More... | |
| struct | CategoricalShape |
| Categorical distribution over a finite outcome set. More... | |
| struct | BernoulliMixtureShape |
Bernoulli mixture (gate_mixture with the [p_token, x_token, y_token] shape). More... | |
| class | ScopedTempDir |
| RAII guard around a freshly mkdtemp'd /tmp directory. More... | |
| struct | ToolRecord |
| One registered external tool. More... | |
| class | ToolRegistry |
| The process-local registry singleton. More... | |
Typedefs | |
| using | ClosedFormShape |
| One of the closed-form shapes the analytical-curves payload can render: bare RV (continuous PDF/CDF), Dirac (point mass), categorical (multiple point masses), or Bernoulli mixture of any two of the above. | |
Enumerations | |
| enum class | ToleranceKind { Exact , Relative , Additive } |
| The contract the user grants – the "path". More... | |
| enum class | Feature { DnfShape , TreewidthProxy } |
| A circuit feature a method's cost/applicability estimate depends on, but that is not free to acquire. More... | |
Functions | |
| unsigned | runAggMarginalEvaluator (GenericCircuit &gc) |
Run the safe-join aggregate marginal-vector pre-pass over gc. | |
| double | aggAvgRawMomentExact (GenericCircuit &gc, gate_t agg_gate, unsigned k, bool &ok) |
| Exact k-th raw moment of AVG = SUM/COUNT over independent rows, conditional on COUNT >= 1. | |
| double | pdfAt (const DistributionSpec &d, double c) |
| Closed-form probability density \(f(c)\) for a basic distribution. | |
| double | cdfAt (const DistributionSpec &d, double c) |
| Closed-form CDF \(F_X(c) = P(X \le c)\) for a basic continuous distribution. | |
| unsigned | runAnalyticEvaluator (GenericCircuit &gc) |
Run the closed-form CDF resolution pass over gc. | |
| 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)). | |
| std::vector< unsigned > | computeRefCounts (const GenericCircuit &gc) |
| Reference count of every gate as a wire-target across the whole circuit. | |
| 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). | |
| std::optional< std::pair< double, double > > | aggCollapsedRawMoments (const GenericCircuit &gc, gate_t agg) |
| std::optional< double > | aggCollapsedRawMoment (const GenericCircuit &gc, gate_t agg, unsigned k) |
Collapsed raw moment E[C^k] of a correlated COUNT / SUM agg, or std::nullopt when the circuit does not match the shared-latent shape. | |
| std::optional< double > | collapsedConditionalMoment (const GenericCircuit &gc, gate_t target, gate_t event, unsigned k) |
Collapsed exact posterior raw moment E[R^k | Y = C] for a latent target R conditioned (through the equality event event) on a discrete rv Y – parametrised by target – equalling a correlated COUNT C. | |
| void | resolveComparators (GenericCircuit &gc, gate_t root, bool simplify, bool decompose) |
Run the comparator-resolution pipeline on gc, rewriting every gate_cmp (RV comparison, HAVING aggregate comparison) into Boolean structure so the downstream getBooleanCircuit / BoolExpr translation never meets a raw comparator. | |
| std::optional< DistributionSpec > | conjugatePosterior (const GenericCircuit &gc, gate_t target, gate_t evidence) |
The exact posterior of target given evidence, as a resolved distribution spec, when the circuit matches the conjugate shape; std::nullopt on any mismatch (the caller falls back to importance sampling). | |
| std::optional< double > | conjugateLogEvidence (const GenericCircuit &gc, gate_t evidence) |
The exact log marginal likelihood \(\ln P(\mathrm{data})\) of a conjugate-shaped evidence circuit; std::nullopt on any shape mismatch or when a rule in the fold has no predictive density (the caller keeps the Monte Carlo mean-weight path). | |
| unsigned | runCountCmpEvaluator (GenericCircuit &gc) |
Run the Poisson-binomial pre-pass over gc. | |
| double | numericQuantile (const Distribution &d, double p) |
Numeric inverse CDF: monotone bisection of cdf() over the family's integration window. | |
| std::unique_ptr< Distribution > | makeDistribution (const DistributionSpec &spec) |
Construct the per-family Distribution for a parsed spec. | |
| double | binomial_coeff (unsigned n, unsigned k) |
| C(n, k) as a double (exact for the small moment orders used here). | |
| double | lbeta (double a, double b) |
| ln B(a, b) = lnΓ(a) + lnΓ(b) − lnΓ(a+b), for a, b > 0. | |
| double | phi (double z) |
| Standard normal pdf φ(z) = exp(-z²/2)/√(2π). | |
| double | Phi (double z) |
| Standard normal CDF Φ(z) = ½(1 + erf(z/√2)). | |
| double | inv_phi (double p) |
| Inverse standard-normal CDF, Beasley-Springer-Moro (1995). | |
| double | gammaP (double a, double x) |
Regularised lower incomplete gamma \(P(a, x) = \gamma(a, x) /
\Gamma(a)\) for a > 0, x >= 0. | |
| DTreeInterval | dtreeBounds (const BooleanCircuit &c, Clauses clauses, double max_width, unsigned long budget, unsigned long *steps_out) |
| DTreeInterval | dtreeBoundsCircuit (const BooleanCircuit &c, gate_t root, double max_width, unsigned long budget=0, unsigned long *steps_out=nullptr) |
| Certified probability interval of an arbitrary Boolean circuit, refined to a target width (the d-tree generalised off monotone DNF). | |
| DTreeInterval | dtreeBounds (const BooleanCircuit &c, std::vector< std::set< gate_t > > clauses, double max_width, unsigned long budget=0, unsigned long *steps_out=nullptr) |
| Certified probability interval of a monotone DNF, refined to a target width (Olteanu-Huang-Koch d-tree). | |
| double | evaluateBooleanProbability (const GenericCircuit &gc, gate_t boolRoot) |
Probability that the Boolean subcircuit rooted at boolRoot evaluates to true under the tuple-independent probabilistic-database model. | |
| double | compute_expectation (const GenericCircuit &gc, gate_t root, std::optional< gate_t > event_root=std::nullopt) |
Compute \(E[X]\) (or \(E[X \mid A]\) if event_root is set) over the scalar sub-circuit rooted at root. | |
| double | compute_raw_moment (const GenericCircuit &gc, gate_t root, unsigned k, std::optional< gate_t > event_root=std::nullopt) |
Compute the raw moment \(E[X^k]\) (or \(E[X^k \mid A]\) if event_root is set) for k >= 0. | |
| double | compute_central_moment (const GenericCircuit &gc, gate_t root, unsigned k, std::optional< gate_t > event_root=std::nullopt) |
Compute the central moment \(E[(X - E[X])^k]\) (or \(E[(X - E[X \mid A])^k \mid A]\) if event_root is set). | |
| double | compute_quantile (const GenericCircuit &gc, gate_t root, double p, std::optional< gate_t > event_root=std::nullopt) |
Compute the p-quantile \(F^{-1}(p)\) of the scalar rooted at root (of the truncated distribution if event_root is set). | |
| gate_t | lift_conditioning (GenericCircuit &gc, gate_t root, std::optional< gate_t > &event_opt) |
| Lift conditioning out of a scalar arithmetic expression. | |
| unsigned | runConstantFold (GenericCircuit &gc) |
Constant-fold pass over every gate_arith in gc. | |
| unsigned | foldDegenerateMixtures (GenericCircuit &gc) |
Collapse degenerate Bernoulli gate_mixture gates whose selector is certainly true (pi = 1) or certainly false (pi = 0) to the corresponding arm. | |
| unsigned | runHybridSimplifier (GenericCircuit &gc) |
Run the peephole simplifier over gc. | |
| unsigned | runHybridDecomposer (GenericCircuit &gc, unsigned samples) |
Marginalise unresolved continuous-island gate_cmp gates into Bernoulli gate_input leaves. | |
| double | computeEntropy (const GenericCircuit &gc, gate_t root, std::optional< gate_t > event) |
Entropy of root in nats: Shannon for a discrete view, differential for a continuous one. | |
| double | computeKL (const GenericCircuit &gc, gate_t p_root, gate_t q_root) |
| Kullback-Leibler divergence KL(P || Q) in nats. | |
| double | computeMutualInformation (const GenericCircuit &gc, gate_t x_root, gate_t y_root) |
Mutual information I(X; Y) in nats: exactly 0 for structurally independent roots, H(X) / Infinity for identical discrete / continuous roots, and the 2-D histogram plug-in estimate over coupled joint draws otherwise. | |
| std::string | kcmcp_compile (const std::string &endpoint, uint8_t input_format, const std::string &problem) |
Compile problem on a KCMCP server and return its d-DNNF NNF text. | |
| unsigned | runMinMaxCmpEvaluator (GenericCircuit &gc) |
Run the MIN / MAX closed-form pre-pass over gc. | |
| std::mt19937_64 | seedRng () |
The shared Monte Carlo generator, seeded from the provsql.monte_carlo_seed GUC (-1 = non-deterministic from std::random_device). | |
| double | monteCarloRV (const GenericCircuit &gc, gate_t root, unsigned samples) |
Run Monte Carlo on a circuit that may contain gate_rv leaves. | |
| double | monteCarloRVStopping (const GenericCircuit &gc, gate_t root, double eps, double delta, unsigned long max_samples, unsigned long &samples_used, bool &reached_target) |
Whole-circuit (eps,delta)-relative probability via the Dagum-Karp-Luby-Ross stopping rule. | |
| std::vector< double > | monteCarloJointDistribution (const GenericCircuit &gc, const std::vector< gate_t > &cmps, unsigned samples) |
Estimate the joint distribution of cmps via Monte Carlo. | |
| std::vector< double > | monteCarloScalarSamples (const GenericCircuit &gc, gate_t root, unsigned samples) |
Sample a scalar sub-circuit samples times and return the draws. | |
| std::pair< std::vector< double >, std::vector< double > > | monteCarloScalarPairSamples (const GenericCircuit &gc, gate_t root_a, gate_t root_b, unsigned samples) |
| Coupled per-iteration draws of two scalar roots. | |
| ConditionalScalarSamples | monteCarloConditionalScalarSamples (const GenericCircuit &gc, gate_t root, gate_t event_root, unsigned samples) |
Rejection-sample root conditioned on event_root. | |
| ConditionalScalarPairSamples | monteCarloConditionalScalarPairSamples (const GenericCircuit &gc, gate_t root_a, gate_t root_b, gate_t event_root, unsigned samples) |
Rejection-sample the PAIR (root_a, root_b) conditioned on event_root. | |
| std::optional< std::vector< double > > | try_truncated_closed_form_sample (const GenericCircuit &gc, gate_t root, gate_t event_root, unsigned n) |
Try to draw n exact samples from the conditional distribution of root given event_root via closed-form truncation, bypassing MC rejection. | |
| WeightedPosterior | importanceSampleConditional (const GenericCircuit &gc, gate_t root, gate_t evidence, unsigned samples) |
Self-normalised importance sampling of root given evidence. | |
| double | importanceEvidence (const GenericCircuit &gc, gate_t evidence, unsigned samples) |
Marginal likelihood P(data) of evidence: the mean raw importance weight over samples prior draws. | |
| std::vector< double > | posteriorResample (const WeightedPosterior &post, unsigned n) |
Sampling-importance-resampling: draw n posterior samples from a weighted particle set (proportional to weight, with replacement). | |
| bool | circuitHasObserve (const GenericCircuit &gc, gate_t root) |
Whether the circuit reachable from root contains a gate_observe – the signal that a conditioning event is continuous-density evidence and must be evaluated by importance sampling rather than the analytic / rejection conditional paths. | |
| bool | circuitHasRV (const GenericCircuit &gc, gate_t root) |
Walk the circuit reachable from root looking for any gate_rv. | |
| bool | circuitHasUnresolvedSampleableAgg (const GenericCircuit &gc, gate_t root) |
Whether a surviving gate_agg exists and every one is sample-faithful (SUM / AVG / MIN / MAX / COUNT – every aggregate the sampler reproduces exactly). | |
| template<typename F> | |
| double | simpsonIntegrate (double lo, double hi, int N, F &&f) |
Composite-Simpson \(\int_{lo}^{hi} f(x)\,dx\) with N panels. | |
| double | binomial (unsigned n, unsigned k) |
| Binomial coefficient \(\binom{n}{k}\) as a double (exact for the small orders the moment expansions use). | |
| template<typename Raw> | |
| std::optional< double > | centralFromRaw (unsigned k, Raw &&raw) |
Central moment of order k from a raw-moment closure: \(E[(X-\mu)^k] = \sum_{i=0}^{k} \binom{k}{i} (-\mu)^{k-i} E[X^i]\). | |
| static double | pow2_clamped (size_t k) |
| 2^k with the exponent clamped to keep the cost finite (a clamped exponent still sorts the method dead last – it is then a guaranteed fall-through). | |
| dDNNF | makeDDAuto (BooleanCircuit &c, gate_t g) |
Cost-select a d-DNNF construction route for gate g of Boolean circuit c and build it – the default makeDD route. | |
| static bool | toleranceAdmits (ToleranceKind request, ToleranceKind method) |
| Admissibility of a method's guarantee under a requested tolerance. | |
| double | booleanSubcircuitProbability (GenericCircuit &gc, gate_t root, const std::string &method="", const std::string &args="", bool inv_free_cert=false, const Tolerance &tol=Tolerance{}, bool mc_fallback=true, std::string *actual_method_out=nullptr) |
Probability of the Boolean function rooted at root in gc – THE single entry point over the method portfolio. | |
| double | parseDoubleStrict (const std::string &s) |
Strictly parse s as a double. | |
| std::string | double_to_text (double v) |
Format a double back into the canonical text form used by gate_value extras and gate_rv distribution parameters (the serialisation counterpart of parseDoubleStrict). | |
| std::optional< DistributionTemplate > | parse_distribution_template (const std::string &s) |
Parse the on-disk text encoding of a gate_rv distribution, keeping wired (token) parameters as wire references. | |
| std::optional< DistributionSpec > | parse_distribution_spec (const std::string &s) |
Parse the on-disk text encoding of a gate_rv distribution. | |
| double | analytical_mean (const DistributionSpec &d) |
| Closed-form expectation E[X] for a basic distribution. | |
| double | analytical_variance (const DistributionSpec &d) |
| Closed-form variance Var(X) for a basic distribution. | |
| double | analytical_raw_moment (const DistributionSpec &d, unsigned k) |
| Closed-form raw moment \(E[X^k]\) for a basic distribution. | |
| unsigned | runRangeCheck (GenericCircuit &gc) |
Run the support-based pruning 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 value-interval into an OR over the agg's per-row K-gates. | |
| std::pair< double, double > | compute_support (const GenericCircuit &gc, gate_t root, std::optional< gate_t > event_root=std::nullopt) |
Compute the [lo, hi] support interval of a scalar sub-circuit rooted at root. | |
| std::optional< std::pair< double, double > > | collectRvConstraints (const GenericCircuit &gc, gate_t event_root, gate_t target_rv) |
Walk event_root collecting rv op c constraints on target_rv. | |
| static bool | extract_finite_double (const GenericCircuit &gc, gate_t x, double &out) |
Parse a gate_value's extra as a finite float8. | |
| static bool | extract_mulinput_value (const GenericCircuit &gc, gate_t mul, double &out) |
| Same parsing applied to a mulinput's outcome label (categorical). | |
| std::optional< TruncatedSingleRv > | matchTruncatedSingleRv (const GenericCircuit &gc, gate_t root, std::optional< gate_t > event_root) |
| Detect a closed-form, optionally-truncated single-RV shape. | |
| bool | eventIsProvablyInfeasible (const GenericCircuit &gc, gate_t root, std::optional< gate_t > event_root) |
True iff the conditioning event is provably infeasible for a bare gate_rv root. | |
| static std::optional< double > | shape_mass (const ClosedFormShape &s, double lo, double hi) |
Unconditional probability mass of a shape over the interval [lo, hi]. | |
| static std::optional< ClosedFormShape > | truncateShape (const ClosedFormShape &s, double lo, double hi) |
Conditional shape after truncating the underlying variable to [lo, hi]. | |
| std::optional< ClosedFormShape > | matchClosedFormDistribution (const GenericCircuit &gc, gate_t root, std::optional< gate_t > event_root) |
Detect any of the closed-form shapes supported by rv_analytical_curves. | |
| std::optional< std::vector< std::tuple< double, double, double > > > | analyticalHistogram (const ClosedFormShape &shape, int bins) |
Exact histogram (bin_lo, bin_hi, probability mass) of a closed-form shape, in bins equal-width bins over its natural range. | |
| double | computeCovariance (GenericCircuit &gc, gate_t x, gate_t y, std::optional< gate_t > event) |
| \(Cov(X, Y)\) (or \(Cov(X, Y \mid E)\)) over a joint circuit. | |
| std::optional< double > | computeCorrelation (GenericCircuit &gc, gate_t x, gate_t y, std::optional< gate_t > event) |
Pearson \(\rho(X, Y) = Cov(X, Y) / (\sigma_X \sigma_Y)\) (conditioned on event when set). | |
| unsigned | runSumCmpEvaluator (GenericCircuit &gc) |
Run the weighted-sum DP pre-pass over gc. | |
| std::string | expandCommandTemplate (const std::string &tpl, const std::string &binary, const std::string &in, const std::string &out, const std::vector< std::pair< std::string, std::string > > &extra={}) |
| Expand a command template into a runnable shell command line. | |
| ToolRegistry & | tool_registry () |
Shorthand for ToolRegistry::instance(). | |
ConjugateRuleRegistry – exact conjugate-prior posterior updates | |
One-observation Bayesian updates for conjugate prior/likelihood pairs: the exact posterior of a latent, wired into one parameter slot of an observed leaf, stays in the prior's family with updated parameters. The conjugate-posterior recogniser ( Like the comparator / closure registries, the rules stay out of the | |
| void | registerConjugateRule (const char *likelihood_family, int wired_param, const char *prior_family, const ConjugateRule &rule) |
Register the conjugate update for observations of likelihood_family whose parameter wired_param (0 = p1, 1 = p2) is the latent, against a prior of prior_family. | |
| const ConjugateRule * | lookupConjugateRule (const std::string &likelihood_family, int wired_param, const std::string &prior_family) |
Look up the conjugate rule for (likelihood family, wired parameter position, prior family); nullptr on a miss. | |
Variables | |
| constexpr double | kNaN = std::numeric_limits<double>::quiet_NaN() |
| constexpr double | kInf = std::numeric_limits<double>::infinity() |
| constexpr int | kSimpsonPanels = 4000 |
| Panel count shared by every composite-Simpson quadrature over a distribution's integration range: exact for the low-degree polynomial integrands of the Uniform cases, high-accuracy otherwise. | |
| static const size_t | kPossibleWorldsSanityMax = 30 |
| Sanity bound on the reachable-input count for the auto-chosen 2^N possible-worlds enumeration: above it the method drops out of the portfolio so it is never attempted (its 2^N cost already deprioritises it, but this guards against a catastrophic last-resort attempt if every cheaper method failed). | |
| static const size_t | kSieveSanityMaxClauses = 24 |
| Largest clause count for which the auto-chosen sieve (2^m inclusion-exclusion) is admitted (matches BooleanCircuit::sieve's internal cap). | |
| static const double | kCostIndependent = 5e-5 |
| static const double | kCostInversionFree = 5e-5 |
| static const double | kCostPossibleWorlds = 3e-6 |
| static const double | kCostSieve = 1e-5 |
| static const double | kCostTreeDecomp = 7e-4 |
| static const double | kCostCompilation = 2e-3 |
| static const double | kCostCompilationFloor = 40.0 |
| static const double | kCostDnfShapeFeature = 2e-6 |
| static const double | kCostTwProxyFeature = 3e-4 |
| static const double | kCostMonteCarlo = 1e-5 |
| static const double | kCostStoppingRule = 1e-3 |
| static const double | kCostKarpLuby = 3e-6 |
| static const double | kCostDTreeExact = 3e-4 |
| static const double | kCostDTreeApprox = 4e-4 |
| static const double | kCostDTreeMsPerStepDnf = 1.4e-3 |
| static const double | kCostDTreeMsPerStepGeneral = 5e-4 |
DistributionRegistry – family descriptor table | |
Family implementations self-register their descriptor at static initialisation: the on-disk name token (the part before the colon in a
| |
| using | DistributionFactory |
| Construct a family instance from its (up to) two parameters. | |
| void | registerDistributionFamily (const DistributionFamily &descriptor) |
| Register a family; called by the registrar at static init. | |
| std::vector< const DistributionFamily * > | listDistributionFamilies () |
| Every registered family, sorted by name token. | |
| const DistributionFamily * | lookupDistributionFamily (const std::string &name) |
| Look up a family by its on-disk name token. | |
ComparatorRuleRegistry – pairwise §B.2 closed forms | |
Closed-form \(P(X < Y)\) for an ordered pair of independent RV families. On continuous distributions every ordered comparator reduces to \(P(X < Y)\) or its complement, so rules are keyed on the family pair alone (no operator in the key). Pairwise behaviour deliberately stays out of the | |
| using | ComparatorRule |
| A pairwise closed form for \(P(X < Y)\), X and Y independent. | |
| void | registerComparatorRule (const char *x, const char *y, ComparatorRule rule) |
| Register the \(P(X < Y)\) closed form for a family pair. | |
| double | comparatorPairLess (const Distribution &X, const Distribution &Y) |
| \(P(X < Y)\) for two independent RVs. | |
ClosureRuleRegistry – pairwise family-closure folds on PLUS | |
Closed-form folds of a sum of independent scalar terms into a single distribution (Normal + Normal, same-rate Exponential / Erlang chains). Like the comparator rules, pairwise behaviour stays out of the A rule receives the whole term list rather than reducing pairwise so its accumulation arithmetic (e.g. one variance sum with a single final square root) is not perturbed by intermediate re-serialisation. | |
| using | ClosureRule |
| A family sum-closure fold. | |
| using | ProductRule |
A family product-closure fold: the distribution of the product of the (independent) factors, or nullptr when the shape is outside the closure. | |
| using | TransformRule |
| A closed-form image of a monotone transform of one family (e.g. | |
| void | registerClosureRule (const char *x, const char *y, ClosureRule rule) |
| Register the sum-closure rule for a family pair (name-token keyed, like the comparator rules). | |
| void | registerProductRule (const char *x, const char *y, ProductRule rule) |
| Register the product-closure rule for a family pair (name-token keyed, like the sum-closure rules). | |
| void | registerTransformRule (const char *transform, const char *family, TransformRule rule) |
Register the image rule for transform ("ln" / "exp" / ...; the evaluator maps its arith opcodes to these names, keeping this registry opcode-free) applied to family. | |
| std::unique_ptr< Distribution > | closeProductFactors (const std::vector< const Distribution * > &factors) |
Fold a product of independent factors into a single distribution when a registered closure covers every family present (same first-vs-each dispatch as closePlusTerms); nullptr on any miss. | |
| std::unique_ptr< Distribution > | closeTransform (const char *transform, const Distribution &x) |
The image distribution of transform applied to x, when a registered rule covers x's family; nullptr otherwise. | |
| std::unique_ptr< Distribution > | closePlusTerms (const std::vector< ClosureTerm > &terms) |
Fold PLUS(terms) into a single distribution when a registered closure covers every family in the sum. | |
| using provsql::ClosedFormShape |
One of the closed-form shapes the analytical-curves payload can render: bare RV (continuous PDF/CDF), Dirac (point mass), categorical (multiple point masses), or Bernoulli mixture of any two of the above.
Definition at line 201 of file RangeCheck.h.
| using provsql::ClosureRule |
A family sum-closure fold.
Returns the closed-form distribution of the summed terms, or nullptr when the shape is outside the closure (mixed rates, scaled / shifted terms a family cannot absorb, degenerate variance...).
Definition at line 431 of file Distribution.h.
| using provsql::ComparatorRule |
A pairwise closed form for \(P(X < Y)\), X and Y independent.
Returns NaN when its parameter guards fail (e.g. a non-positive rate); the driver then tries the generic quadrature.
Definition at line 358 of file Distribution.h.
Construct a family instance from its (up to) two parameters.
Definition at line 265 of file Distribution.h.
| using provsql::ProductRule |
A family product-closure fold: the distribution of the product of the (independent) factors, or nullptr when the shape is outside the closure.
Scalar factors are the caller's job (applied afterwards via affine).
Definition at line 453 of file Distribution.h.
| using provsql::TransformRule |
A closed-form image of a monotone transform of one family (e.g.
exp of a normal is a lognormal), or nullptr when the family has none.
Definition at line 481 of file Distribution.h.
|
strong |
A circuit feature a method's cost/applicability estimate depends on, but that is not free to acquire.
Acquiring a feature has a cost (modelled by EvalContext::featureCost), and the chooser acquires one lazily only when no already-known method is cheaper than acquiring it – so a circuit the cheap methods resolve (read-once via independent, certified via inversion-free) never pays for analysis that could not change the decision. Free/O(1) features (#inputs, an inversion-free certificate) are not modelled here – they are read eagerly.
DnfShape is a linear dnfShape walk. TreewidthProxy is a cheap (O(V+E)) degeneracy lower bound on the circuit's treewidth that gates tree-decomposition's cost – it rules the method out when the bound already exceeds the build's limit, while the bounded-treewidth build can still fail implicitly when the bound is inconclusive.
| Enumerator | |
|---|---|
| DnfShape | |
| TreewidthProxy | |
Definition at line 77 of file ProbabilityMethod.h.
|
strong |
The contract the user grants – the "path".
Exact is tolerance (0,0); Relative promises (1±epsilon) with confidence 1-delta; Additive promises |p̂-p| <= epsilon with the same confidence. Admissible method sets nest Exact ⊂ Relative ⊂ Additive.
The tolerance is recorded but does not by itself drive method selection: named methods dispatch by name and the empty method set runs the exact ladder.
| Enumerator | |
|---|---|
| Exact | |
| Relative | |
| Additive | |
Definition at line 52 of file ProbabilityMethod.h.
| double provsql::aggAvgRawMomentExact | ( | GenericCircuit & | gc, |
| gate_t | agg_gate, | ||
| unsigned | k, | ||
| bool & | ok ) |
Exact k-th raw moment of AVG = SUM/COUNT over independent rows, conditional on COUNT >= 1.
The "easy case" of the joint (sum,count) machinery: every semimod contributor must be a product of private gate_input leaves (parseProductContributor) and the rows pairwise leaf-disjoint, so the per-row inclusion indicators are independent and the joint PMF is a plain fold. AVG over the empty world is NULL, so the moment conditions on the aggregate being defined (the MIN / MAX convention). Sets ok false – the caller falls back to the Monte-Carlo scalar path – on any other shape (shared leaves, compound contributors, non-numeric values, unset probabilities, support blow-up, or a never-defined aggregate).
Definition at line 1322 of file AggMarginalEvaluator.cpp.


| std::optional< double > provsql::aggCollapsedRawMoment | ( | const GenericCircuit & | gc, |
| gate_t | agg, | ||
| unsigned | k ) |
Collapsed raw moment E[C^k] of a correlated COUNT / SUM agg, or std::nullopt when the circuit does not match the shared-latent shape.
k in {1, 2}.
Definition at line 506 of file CollapsedAggMoment.cpp.


| std::optional< std::pair< double, double > > provsql::aggCollapsedRawMoments | ( | const GenericCircuit & | gc, |
| gate_t | agg ) |
| double provsql::analytical_mean | ( | const DistributionSpec & | d | ) |
Closed-form expectation E[X] for a basic distribution.
Definition at line 156 of file RandomVariable.cpp.

| double provsql::analytical_raw_moment | ( | const DistributionSpec & | d, |
| unsigned | k ) |
Closed-form raw moment \(E[X^k]\) for a basic distribution.
Returns 1 for \(k = 0\) and analytical_mean for \(k = 1\).
Definition at line 166 of file RandomVariable.cpp.

| double provsql::analytical_variance | ( | const DistributionSpec & | d | ) |
Closed-form variance Var(X) for a basic distribution.
Definition at line 161 of file RandomVariable.cpp.

| std::optional< std::vector< std::tuple< double, double, double > > > provsql::analyticalHistogram | ( | const ClosedFormShape & | shape, |
| int | bins ) |
Exact histogram (bin_lo, bin_hi, probability mass) of a closed-form shape, in bins equal-width bins over its natural range.
Defined in RvAnalyticalCurves.cpp (where the shape CDF / range helpers live). Lets rv_histogram answer for a closed-form distribution without sampling – e.g. a truncated Gaussian under provsql.rv_mc_samples = 0. Returns std::nullopt when the range is degenerate or the CDF is unavailable, so the caller can fall back to Monte Carlo.
Definition at line 264 of file RvAnalyticalCurves.cpp.

|
inline |
Binomial coefficient \(\binom{n}{k}\) as a double (exact for the small orders the moment expansions use).
Definition at line 57 of file PivotIntegration.h.

|
inline |
C(n, k) as a double (exact for the small moment orders used here).
Definition at line 23 of file DistributionCommon.h.
| double provsql::booleanSubcircuitProbability | ( | GenericCircuit & | gc, |
| gate_t | root, | ||
| const std::string & | method = "", | ||
| const std::string & | args = "", | ||
| bool | inv_free_cert = false, | ||
| const Tolerance & | tol = Tolerance{}, | ||
| bool | mc_fallback = true, | ||
| std::string * | actual_method_out = nullptr ) |
Probability of the Boolean function rooted at root in gc – THE single entry point over the method portfolio.
getBooleanCircuit builds the Boolean view (HAVING semantics + BoolExpr translation); the empty / "default" / "exact" method then runs the cost-ordered auto-chooser (MethodCatalog::chooseAndRun), while a named method dispatches byName. Every caller that needs "the probability of
a Boolean subcircuit" – the top-level probability_evaluate and the moment evaluator's mixture weights alike – routes through here, so the Boolean-view build and the method portfolio are single-sourced. gc's comparators should already be resolved (see resolveComparators in ComparatorResolution.h) for an exact result.
When the Boolean view cannot be built (the circuit carries random variables, or a large sampleable HAVING aggregate under an approximate request), the probability is delegated to the tolerance-appropriate generic-circuit estimator: the Dagum-Karp-Luby-Ross stopping rule for a Relative request, fixed-sample monteCarloRV for Additive, and – for an Exact request with mc_fallback – monteCarloRV at the provsql.rv_mc_samples budget (the moment path's residual comparators).
| gc | the circuit holding the sub-circuit to evaluate. |
| root | the gate whose probability is computed. |
| method | "" / "default" / "exact" runs the auto-chooser; any other name dispatches that method byName. |
| args | method arguments (tolerance strings, compiler names). |
| inv_free_cert | whether an inversion-free certificate is present (unlocks the inversion-free method in the portfolio). |
| tol | the guarantee requested of the portfolio and of the no-Boolean-view estimator: Exact (default), Relative, Additive. |
| mc_fallback | for an Exact request only: when true, a circuit with no Boolean view is estimated by monteCarloRV instead of raising (the moment path opts in; probability_evaluate's exact arm passes false so an unresolved RV comparator surfaces its diagnostic). |
| actual_method_out | if non-null, receives the method actually run (for provsql.last_eval_method reporting). |
Definition at line 1951 of file probability_evaluate.cpp.


| double provsql::cdfAt | ( | const DistributionSpec & | d, |
| double | c ) |
Closed-form CDF \(F_X(c) = P(X \le c)\) for a basic continuous distribution.
Returns the cumulative distribution at c for the distribution d. Used internally by AnalyticEvaluator's gate_cmp resolution and by the HybridEvaluator decomposer's monotone-shared-scalar fast path to compute interval probabilities analytically (no MC noise) when the shared scalar is a bare gate_rv. Returns NaN when d carries a parameter shape the CDF doesn't cover (e.g. non-integer Erlang shape, which would require the regularised lower incomplete gamma function).
std::erf.c<=a, 1 for c>=b, (c - a) / (b - a) otherwise.1 - exp(-λc) for c>0; 0 for c<=0.k≥1): finite-sum form \(1 - e^{-\lambda c} \sum_{n=0}^{k-1}
(\lambda c)^n / n!\) for c>0. Definition at line 33 of file AnalyticEvaluator.cpp.


| std::optional< double > provsql::centralFromRaw | ( | unsigned | k, |
| Raw && | raw ) |
Central moment of order k from a raw-moment closure: \(E[(X-\mu)^k] = \sum_{i=0}^{k} \binom{k}{i} (-\mu)^{k-i} E[X^i]\).
raw maps a moment order to the (conditional) raw moment, returning std::nullopt when it cannot be resolved — which propagates, so the caller falls back exactly as it would for the raw moment itself. raw(0) must be 1.
Definition at line 79 of file PivotIntegration.h.

| bool provsql::circuitHasObserve | ( | const GenericCircuit & | gc, |
| gate_t | root ) |
Whether the circuit reachable from root contains a gate_observe – the signal that a conditioning event is continuous-density evidence and must be evaluated by importance sampling rather than the analytic / rejection conditional paths.
Definition at line 973 of file MonteCarloSampler.cpp.


| bool provsql::circuitHasRV | ( | const GenericCircuit & | gc, |
| gate_t | root ) |
Walk the circuit reachable from root looking for any gate_rv.
Used by probability_evaluate to dispatch between the existing BooleanCircuit path and the RV-aware sampler in this file.
Definition at line 996 of file MonteCarloSampler.cpp.


| bool provsql::circuitHasUnresolvedSampleableAgg | ( | const GenericCircuit & | gc, |
| gate_t | root ) |
Whether a surviving gate_agg exists and every one is sample-faithful (SUM / AVG / MIN / MAX / COUNT – every aggregate the sampler reproduces exactly).
A gate_agg the exact closed-form / marginal-vector pre-passes did not fold into a Bernoulli gate_input marks a HAVING aggregate comparator whose exact resolution needs provsql_having's threshold-lineage expansion – which does not terminate in practice for a large-magnitude / large-support aggregate (the dense kMaxSumRange and sparse kMaxSumSupport caps exceeded). For an (eps,delta) request probability_evaluate uses this to route the circuit straight to the world-sampler (the gate_agg arm of evalScalar) – a sound FPRAS for the apx-safe corner of the HAVING trichotomy – instead of attempting the non-terminating Boolean expansion.
The sampler's gate_agg arm pushes each kept contributor's value into the matching Aggregator, reproducing SQL semantics exactly: the value gate is the row's contribution (the summed term for SUM; the 0/1 indicator for COUNT, 0 for a NULL row so count(x) does not count NULLs; the compared value for AVG / MIN / MAX), so NULL rows are handled and a contributor-free iteration finalises to the value the exact evaluator uses (0 for a scalar COUNT, whose single row exists over empty input; NaN -> comparison false for every other case, SQL's NULL or a grouped aggregation's absent row), and gate_arith over them is covered too.
COUNT reaches this arm only as a scalar aggregation. Its value-support is small (0/1 per row), so a grouped COUNT comparison is resolved before any sampler runs – by RangeCheck when the bounds decide it, otherwise by provsql_having's world enumeration – and both of those already exclude the empty world. The grouped arm below is nonetheless written to decline such a world rather than report 0, so the aggregate stays correct if the routing ever sends one here.
Definition at line 1018 of file MonteCarloSampler.cpp.


| std::unique_ptr< Distribution > provsql::closePlusTerms | ( | const std::vector< ClosureTerm > & | terms | ) |
Fold PLUS(terms) into a single distribution when a registered closure covers every family in the sum.
Dispatch: the first RV term's family is looked up against itself and against every other RV term's family; all lookups must resolve to the same rule (this is how the Exponential / Erlang pairs share one Erlang-sum rule). Returns nullptr on any miss, on an inconsistent pair, when no RV term is present (the constant-fold path's job), or when the rule itself declines.
Definition at line 175 of file Distribution.cpp.
| std::unique_ptr< Distribution > provsql::closeProductFactors | ( | const std::vector< const Distribution * > & | factors | ) |
Fold a product of independent factors into a single distribution when a registered closure covers every family present (same first-vs-each dispatch as closePlusTerms); nullptr on any miss.
Definition at line 146 of file Distribution.cpp.
| std::unique_ptr< Distribution > provsql::closeTransform | ( | const char * | transform, |
| const Distribution & | x ) |
The image distribution of transform applied to x, when a registered rule covers x's family; nullptr otherwise.
Definition at line 167 of file Distribution.cpp.

| std::optional< double > provsql::collapsedConditionalMoment | ( | const GenericCircuit & | gc, |
| gate_t | target, | ||
| gate_t | event, | ||
| unsigned | k ) |
Collapsed exact posterior raw moment E[R^k | Y = C] for a latent target R conditioned (through the equality event event) on a discrete rv Y – parametrised by target – equalling a correlated COUNT C.
event must be a gate_cmp with the = operator whose operands are a parametric discrete gate_rv over target and a gate_agg count. The count's pmf P(C=j) is obtained by the collapse; the posterior is then the 1-D quadrature \(E[R^k|C] = \int r^k f_R(r) L(r)\,dr / \int f_R(r) L(r)\,dr\) with likelihood \(L(r) = \sum_j P(C=j)\,\mathrm{pmf}_Y(j;\theta(r))\) – exact up to quadrature, O(n^2 + G K). std::nullopt on any shape mismatch (the caller then falls back to importance sampling). k in {1, 2}.
Definition at line 519 of file CollapsedAggMoment.cpp.

| std::optional< std::pair< double, double > > provsql::collectRvConstraints | ( | const GenericCircuit & | gc, |
| gate_t | event_root, | ||
| gate_t | target_rv ) |
Walk event_root collecting rv op c constraints on target_rv.
Descends through AND-conjunct factors (gate_times, gate_one, Boolean leaves whose footprint doesn't include target_rv – these are independent of the RV and contribute no truncation) collecting every gate_cmp interpretable as target_rv op c for a constant c, and intersects them into a running interval seeded with the unconditional support of target_rv.
Returns the resulting interval as (lo, hi), or std::nullopt if the walk found a structure that defeats the recognisers (a gate_plus / gate_monus disjunction over the chain, a cmp shape other than rv op const, ...). Callers treat std::nullopt as "fall back to the unconditional case" – sound for support and MC fallback for moments.
Constraints on RVs other than target_rv are ignored; they affect P(A) but not the truncation of the target's distribution.
Definition at line 1432 of file RangeCheck.cpp.

| double provsql::comparatorPairLess | ( | const Distribution & | X, |
| const Distribution & | Y ) |
\(P(X < Y)\) for two independent RVs.
Applies the registered closed form for the family pair when there is one; on a registry miss (or a rule declining with NaN) falls back to the 1-D composite-Simpson quadrature \(P(X<Y) = \int (1 - F_Y(t))\, f_X(t)\, dt\) over X's integration range. NaN when neither decides (a density / CDF is undefined, e.g. a non-integer Erlang shape), so the caller falls back to Monte Carlo.
Definition at line 223 of file Distribution.cpp.

| double provsql::compute_central_moment | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| unsigned | k, | ||
| std::optional< gate_t > | event_root = std::nullopt ) |
Compute the central moment \(E[(X - E[X])^k]\) (or \(E[(X - E[X \mid A])^k \mid A]\) if event_root is set).
k = 0 returns 1; k = 1 returns 0; k = 2 returns the variance. Higher orders are obtained by binomial expansion in terms of the raw moments returned by compute_raw_moment, which inherits the analytical / MC dispatch described above.
Definition at line 1937 of file Expectation.cpp.


| double provsql::compute_expectation | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > | event_root = std::nullopt ) |
Compute \(E[X]\) (or \(E[X \mid A]\) if event_root is set) over the scalar sub-circuit rooted at root.
The conditional path requires that event_root be a gate_t in the same GenericCircuit as root – typically the circuit was loaded via getJointCircuit so a shared gate_rv between root and event has one gate_t, which is what couples the MC sampler. When event_root is std::nullopt the unconditional path (existing analytical decomposition with MC fallback) is taken unchanged.
| CircuitException | on malformed circuits, unknown distribution kinds, when provsql.rv_mc_samples is 0 and a sub-expression cannot be decomposed analytically, or when the conditional MC pass accepts too few samples (suggesting P(A) is very small or zero). |
Definition at line 1919 of file Expectation.cpp.

| double provsql::compute_quantile | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| double | p, | ||
| std::optional< gate_t > | event_root = std::nullopt ) |
Compute the p-quantile \(F^{-1}(p)\) of the scalar rooted at root (of the truncated distribution if event_root is set).
Requires \(p \in [0, 1]\) (the caller validates); p = 0 / 1 return the (truncated) support edges. Analytic for a bare gate_rv – the family's elementary inverse CDF where one exists, the generic monotone-CDF bisection (numericQuantile) otherwise – and exact for a categorical mixture; compound scalar circuits fall back to the empirical Monte Carlo quantile (linear interpolation, the percentile_cont convention) at the provsql.rv_mc_samples budget, with the same conditional-acceptance guards as the moment estimators.
Definition at line 2050 of file Expectation.cpp.


| double provsql::compute_raw_moment | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| unsigned | k, | ||
| std::optional< gate_t > | event_root = std::nullopt ) |
Compute the raw moment \(E[X^k]\) (or \(E[X^k \mid A]\) if event_root is set) for k >= 0.
k = 0 returns 1; k = 1 delegates to compute_expectation.
Definition at line 1928 of file Expectation.cpp.

| std::pair< double, double > provsql::compute_support | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > | event_root = std::nullopt ) |
Compute the [lo, hi] support interval of a scalar sub-circuit rooted at root.
Same interval-arithmetic propagation runRangeCheck uses internally, exposed for the SQL support() function:
gate_value: point [c, c].gate_rv: distribution support (uniform exact, exponential on [0, +∞), normal on (-∞, +∞)).gate_arith: propagated through +, −, ×, /, unary −.Anything else collapses to the conservative all-real interval (-∞, +∞). Never throws on unrecognised gates – callers receive the wide interval instead, which is the right semantic for "we
cannot prove a tighter bound".
When event_root is set, the returned interval is the intersection of the unconditional support with the per-RV constraints implied by the AND-conjunct chain rooted at the event (rv op c cmps over root collected via the same walker runRangeCheck uses for joint feasibility). Constraints we cannot interpret are silently skipped: the result is then a conservative superset of the true conditional support, never a subset.
Definition at line 1399 of file RangeCheck.cpp.

| std::optional< double > provsql::computeCorrelation | ( | GenericCircuit & | gc, |
| gate_t | x, | ||
| gate_t | y, | ||
| std::optional< gate_t > | event ) |
Pearson \(\rho(X, Y) = Cov(X, Y) / (\sigma_X \sigma_Y)\) (conditioned on event when set).
Same exact tiers as computeCovariance; on the Monte Carlo path the covariance and BOTH standard deviations are read off one coupled pass. std::nullopt when either variance is 0 (or the statistics are undefined): correlation with a degenerate variable has no value, and the SQL binding maps this to NULL.
Definition at line 275 of file RvCovariance.cpp.


| double provsql::computeCovariance | ( | GenericCircuit & | gc, |
| gate_t | x, | ||
| gate_t | y, | ||
| std::optional< gate_t > | event ) |
\(Cov(X, Y)\) (or \(Cov(X, Y \mid E)\)) over a joint circuit.
Exact tiers first: a variance readout when the two roots coincide, an exact 0 when the roots' stochastic-leaf footprints are structurally independent (given the event), and the closed-form \(E[XY] - E[X]\,E[Y]\) when every factor decomposes analytically. Otherwise one coupled Monte Carlo pass at the provsql.rv_mc_samples budget.
Definition at line 233 of file RvCovariance.cpp.


| double provsql::computeEntropy | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > | event ) |
Entropy of root in nats: Shannon for a discrete view, differential for a continuous one.
With event, the entropy of the conditional distribution (MC plug-in estimate).
Definition at line 236 of file InformationTheory.cpp.


| double provsql::computeKL | ( | const GenericCircuit & | gc, |
| gate_t | p_root, | ||
| gate_t | q_root ) |
Kullback-Leibler divergence KL(P || Q) in nats.
Infinity when P is not absolutely continuous w.r.t. Q (mismatched kinds, an atom / region of P outside Q's support). Both roots must resolve to density views; raises otherwise.
Definition at line 273 of file InformationTheory.cpp.


| double provsql::computeMutualInformation | ( | const GenericCircuit & | gc, |
| gate_t | x_root, | ||
| gate_t | y_root ) |
Mutual information I(X; Y) in nats: exactly 0 for structurally independent roots, H(X) / Infinity for identical discrete / continuous roots, and the 2-D histogram plug-in estimate over coupled joint draws otherwise.
Definition at line 313 of file InformationTheory.cpp.


| std::vector< unsigned > provsql::computeRefCounts | ( | const GenericCircuit & | gc | ) |
Reference count of every gate as a wire-target across the whole circuit.
One pass over all wire lists; O(total wires).
Definition at line 109 of file CmpEvaluatorCommon.cpp.


| std::optional< double > provsql::conjugateLogEvidence | ( | const GenericCircuit & | gc, |
| gate_t | evidence ) |
The exact log marginal likelihood \(\ln P(\mathrm{data})\) of a conjugate-shaped evidence circuit; std::nullopt on any shape mismatch or when a rule in the fold has no predictive density (the caller keeps the Monte Carlo mean-weight path).
The latent is inferred from the evidence itself: every observed leaf must wire the same bare all-literal gate_rv prior. The result is the sum of each rule's log predictive density of its datum under the running posterior (the sequential chain-rule factorisation of the joint marginal), accumulated in log space.
Definition at line 208 of file ConjugatePosterior.cpp.

| std::optional< DistributionSpec > provsql::conjugatePosterior | ( | const GenericCircuit & | gc, |
| gate_t | target, | ||
| gate_t | evidence ) |
The exact posterior of target given evidence, as a resolved distribution spec, when the circuit matches the conjugate shape; std::nullopt on any mismatch (the caller falls back to importance sampling).
Recognised shape: target is a bare all-literal gate_rv (the prior); evidence flattens through the gate_times conjunction spine (the shape and_agg builds) into gate_observe atoms only (gate_one factors are transparently skipped); each observed leaf parses to a DistributionTemplate with exactly one wired slot whose wire is target itself; and the registry has an update rule for every (likelihood family, wired slot, running posterior family) triple. Every registered update is exchangeable, so the left-nested and_agg fold order is irrelevant, and mixed likelihoods sharing one conjugate prior compose (a Gamma-prior rate observed through interleaved Poisson counts and Exponential gaps stays Gamma).
Definition at line 202 of file ConjugatePosterior.cpp.

| double provsql::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).
Exact precisely when the contributor's sub-circuit is a private read-once tree: every randomness-bearing gate it visits must have reference count 1. That single condition gives pairwise-disjoint leaf sets across contributors, no reuse outside the cmp, and read-once-ness within a contributor. Supports input / times / plus / monus and the one / zero constants; clears ok on any other gate type or on a reference-count violation. See CountCmpEvaluator.h for the full argument.
Definition at line 123 of file CmpEvaluatorCommon.cpp.


| std::string provsql::double_to_text | ( | double | v | ) |
Format a double back into the canonical text form used by gate_value extras and gate_rv distribution parameters (the serialisation counterpart of parseDoubleStrict).
std::to_chars produces the shortest decimal representation that round-trips through std::from_chars / std::stod, so round cases like 0.2 = 0.4/2 print as "0.2" rather than "0.20000000000000001" while irrational values fall back to whatever length is needed for exact recovery. The legacy std::ostringstream << setprecision(17) path is kept as a defensive fallback in case to_chars fails (range / buffer).
Definition at line 43 of file RandomVariable.cpp.
| DTreeInterval provsql::dtreeBounds | ( | const BooleanCircuit & | c, |
| Clauses | clauses, | ||
| double | max_width, | ||
| unsigned long | budget, | ||
| unsigned long * | steps_out ) |
| DTreeInterval provsql::dtreeBounds | ( | const BooleanCircuit & | c, |
| std::vector< std::set< gate_t > > | clauses, | ||
| double | max_width, | ||
| unsigned long | budget = 0, | ||
| unsigned long * | steps_out = nullptr ) |
Certified probability interval of a monotone DNF, refined to a target width (Olteanu-Huang-Koch d-tree).
Refines BooleanCircuit::dnfBounds by independent-or decomposition and Shannon expansion until upper-lower <= max_width, propagating the width budget so the returned interval honours it: through Shannon the same budget passes to both cofactors (the mixture width is at most the larger branch's), through an independent-or of k components each gets max_width/k (the OR width is at most the sum of the component widths). max_width == 0 forces exact compilation (lower == upper).
| c | Circuit owning the input marginals (getProb). |
| clauses | The DNF as per-clause input-leaf supports (consumed). |
| max_width | Absolute target for upper-lower (0 = exact). |
| budget | Subproblem (recursion-step) ceiling; 0 = unbounded. On overrun a CircuitException is thrown so the caller's cost-based chooser escalates to another method. |
| steps_out | If non-null, receives the number of recursion steps taken (for cost calibration). |
lower <= Pr[clauses] <= upper. | DTreeInterval provsql::dtreeBoundsCircuit | ( | const BooleanCircuit & | c, |
| gate_t | root, | ||
| double | max_width, | ||
| unsigned long | budget = 0, | ||
| unsigned long * | steps_out = nullptr ) |
Certified probability interval of an arbitrary Boolean circuit, refined to a target width (the d-tree generalised off monotone DNF).
Same anytime engine as dtreeBounds, but recursing on the circuit DAG (AND / OR / NOT / IN) instead of a flat monotone-DNF clause set, so it applies to negation (EXCEPT / monus, encoded A AND NOT B), nested AND / OR (e.g. a CNF-shaped circuit), and arbitrary sharing.
The cheap leaf bound generalises dnfBounds soundly to any gate: an independent-component split (children with disjoint free-variable footprints compose exactly), then a Bonferroni lower / min upper for AND, a max lower / union upper for OR, and a flip [1-U,1-L] for NOT. It is refined by independent-component decomposition and Shannon expansion on the most frequent shared free variable until upper-lower <= max_width (0 = exact). Every step keeps lower <= Pr <= upper (Shannon is an exact mixture; independence is over disjoint input cones, never overclaimed).
Throws CircuitException on a multivalued (MULIN / MULVAR) or UNDETERMINED gate in the cone of root, so the caller falls back to another method on BID circuits.
| c | Circuit (gate types, wiring, input marginals). |
| root | Root gate whose probability interval is computed. |
| max_width | Absolute target for upper-lower (0 = exact). |
| budget | Subproblem (recursion-step) ceiling; 0 = unbounded. On overrun a CircuitException is thrown so the caller's cost-based chooser escalates to another method. |
| steps_out | If non-null, receives the number of recursion steps taken (for cost calibration). |
lower <= Pr[root] <= upper. | double provsql::evaluateBooleanProbability | ( | const GenericCircuit & | gc, |
| gate_t | boolRoot ) |
Probability that the Boolean subcircuit rooted at boolRoot evaluates to true under the tuple-independent probabilistic-database model.
Tries BooleanCircuit::independentEvaluation first; if that throws (e.g. the subcircuit is not disconnected for that method), falls back to Monte Carlo with provsql.rv_mc_samples samples. Used by the mixture moment evaluators for compound Boolean Bernoulli wires.
Definition at line 93 of file Expectation.cpp.

| bool provsql::eventIsProvablyInfeasible | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > | event_root ) |
True iff the conditioning event is provably infeasible for a bare gate_rv root.
Distinguishes "event proved infeasible" (event resolves to gate_zero, or collectRvConstraints intersects to an empty interval) from "shape unsupported by @c matchTruncatedSingleRv" (return std::nullopt that just means "fall back to MC").
Used by the conditional-moment dispatcher to raise an explicit infeasibility error before falling through to MC rejection – MC would still detect the same condition by accepting 0 of N samples, but the closed-form predicate spots it without ten thousand wasted draws and emits a tighter message.
Returns false for non-gate_rv roots and for roots whose event/support pair is not provably infeasible by this cheap pass (the caller can still proceed to MC).
Definition at line 1544 of file RangeCheck.cpp.


|
inline |
Expand a command template into a runnable shell command line.
Replaces {binary} / {in} / {out} and any extra placeholders (e.g. {tmpdir}, {pivotAC}) in tpl. When tpl contains no {binary} placeholder, a non-empty binary is prepended (the common "<binary> <args>" shape); a template that places the binaries itself (the dpmc pipeline) is returned as-is.
Header-only and dependency-free on purpose, so the standalone tdkc build can expand a template without linking the registry.
Definition at line 57 of file ToolRegistry.h.

|
static |
Parse a gate_value's extra as a finite float8.
Sibling of extract_constant_string in having_semantics.cpp but parsing a double, with a const GenericCircuit ref (used in the closed-form shape detector path). Bails on NaN / ±Infinity so a downstream stem renderer never sees a non-finite x coordinate.
Definition at line 1471 of file RangeCheck.cpp.


|
static |
Same parsing applied to a mulinput's outcome label (categorical).
Definition at line 1489 of file RangeCheck.cpp.


| unsigned provsql::foldDegenerateMixtures | ( | GenericCircuit & | gc | ) |
Collapse degenerate Bernoulli gate_mixture gates whose selector is certainly true (pi = 1) or certainly false (pi = 0) to the corresponding arm.
A classic 3-wire mixture mixture(p, X, Y) with P(p) = 1 is distributionally X (and Y when P(p) = 0). The collapse is exact and correlation-safe precisely at those two points: a deterministic selector carries no coupling, so folding it does not decouple a selector shared across mixtures – which is why only the exact 0/1 cases are admitted (a fractional pi genuinely couples the arms and must reach the sampler intact). pi is taken only where it is known without a probability computation: a resolved gate_one / gate_zero selector, or a bare gate_input whose pinned probability is 1 or 0 (the latter includes the default 1 of a provenance-tracked but non-probabilistic tuple). A compound Boolean selector is left for the probability-aware evaluators.
The mixture is rewritten as a single-wire gate_arith PLUS passthrough to the surviving arm (liftConditionedToTarget), so it references rather than copies the survivor – a shared survivor keeps its single gate identity. Runs at load time before runConstantFold and foldSemiringIdentities, which then reduce the resulting passthroughs and any now-constant enclosing arithmetic (e.g. the provenance-weighted count in avg's denominator collapses to a gate_value, letting the analytic evaluator divide by it).
Definition at line 1246 of file HybridEvaluator.cpp.


|
inline |
Regularised lower incomplete gamma \(P(a, x) = \gamma(a, x) /
\Gamma(a)\) for a > 0, x >= 0.
Series expansion of \(\gamma(a, x)\) for x < a + 1, modified Lentz continued fraction for the complement \(Q(a, x)\) otherwise – each converges fast in its region (Numerical Recipes §6.2). NaN on invalid a or non-convergence, so callers fall through to Monte Carlo.
Definition at line 124 of file DistributionCommon.h.
| double provsql::importanceEvidence | ( | const GenericCircuit & | gc, |
| gate_t | evidence, | ||
| unsigned | samples ) |
Marginal likelihood P(data) of evidence: the mean raw importance weight over samples prior draws.
The same quantity rejection conditioning computes as P(C), now a product of the observations' densities. Backs provsql.evidence.
Definition at line 931 of file MonteCarloSampler.cpp.


| WeightedPosterior provsql::importanceSampleConditional | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| gate_t | evidence, | ||
| unsigned | samples ) |
Self-normalised importance sampling of root given evidence.
For each of samples prior draws the shared Sampler resets its per-iteration caches, then:
evidence to an importance weight (evalWeight): a gate_observe contributes its leaf's pdf at the datum, a Boolean conditioning event contributes a 0/1 weight, a gate_times multiplies its children's weights – populating scalar_cache_ for every latent the evidence touches;root as a scalar using the SAME caches, so a latent shared between root and evidence is drawn once and the weight and the value observe it jointly;(value, weight) particle.Coupling the weight and the value through one joint circuit (getJointCircuit) is what makes the shared latent a single gate_t; the particles are then draws from the posterior of root given the data.
| gc | Circuit (typically from getJointCircuit). |
| root | Scalar gate whose posterior we sample. |
| evidence | Evidence circuit (an and_agg conjunction of gate_observe / Boolean events). |
| samples | Number of prior draws. |
Definition at line 898 of file MonteCarloSampler.cpp.


|
inline |
Inverse standard-normal CDF, Beasley-Springer-Moro (1995).
Returns z such that \(\Phi(z) = p\). Accurate to about 1e-7 over p ∈ [0.02425, 1 - 0.02425], with a tail rational fallback for the rest of (0, 1). Callers must clamp p strictly inside (0, 1) since the function diverges at the endpoints; the truncated-normal sampler clamps to [1e-15, 1 - 1e-15] before each call.
The Beasley-Springer-Moro routine is in widespread library use (NumPy/SciPy 'norminv', etc.) and its accuracy is several orders of magnitude tighter than the sampling noise the tests can detect at 10k draws, so it's a comfortable margin.
Definition at line 72 of file DistributionCommon.h.
| std::string provsql::kcmcp_compile | ( | const std::string & | endpoint, |
| uint8_t | input_format, | ||
| const std::string & | problem ) |
Compile problem on a KCMCP server and return its d-DNNF NNF text.
Connects to endpoint ("unix:/path" or "host:port"), performs the HELLO handshake, issues one compile REQUEST for problem in the given input_format (0 = dimacs-cnf, 1 = circuit-bcs12) wanting ddnnf-nnf output, and returns the RESULT's NNF text verbatim (parsed by BooleanCircuit::parseDDNNF, exactly as the CLI temp-file path is). A fresh connection per call.
Honours PostgreSQL query-cancel / statement_timeout while waiting: a pending cancel closes the socket (so the server abandons the job) and is then raised, mirroring the cancel discipline in external_tool.cpp. Throws std::runtime_error on any connect / protocol / server-ERROR failure so the caller can fall back to the CLI path.
Definition at line 252 of file kcmcp_client.cpp.

|
inline |
ln B(a, b) = lnΓ(a) + lnΓ(b) − lnΓ(a+b), for a, b > 0.
Definition at line 36 of file DistributionCommon.h.
| gate_t provsql::lift_conditioning | ( | GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > & | event_opt ) |
Lift conditioning out of a scalar arithmetic expression.
Normalise conditioning in a scalar sub-circuit before evaluation.
Implements "f(X|A, Y|B, …) = f(X, Y, …) | (A ∧ B ∧ …)": walks the scalar tree rooted at root, replaces every nested gate_conditioned by a transparent passthrough to its target (so the tree becomes the plain arithmetic over the unconditioned distributions), collects the evidence children, and conjoins them – together with any pre-existing event_opt – into a single conditioning event. The conjunction is built as an in-memory gate_times over the evidence gates, all of which already live in the (joint) circuit, so a base gate_rv shared between a value and its evidence keeps a single draw under the MC sampler. A conditioned ROOT is peeled to its bare target (returned), so a stored "X | C" reaching any low-level RV entry point keeps the closed-form scalar path; the (possibly new) root is returned. Leaves event_opt untouched and returns root unchanged when the expression carries no conditioning.
Peels a conditioned ROOT to its bare target and rewrites every buried gate_conditioned into a transparent passthrough, folding all collected evidence (and any pre-existing event_opt) into a single conditioning event left in event_opt. Returns the (possibly new) root so a stored "X | C" reaching a low-level RV entry point evaluates as the bare scalar conditioned on the folded event – keeping the closed-form path available. No-op (returns root, leaves event_opt untouched) when there is no conditioning.
Definition at line 2134 of file Expectation.cpp.


| std::vector< const DistributionFamily * > provsql::listDistributionFamilies | ( | ) |
Every registered family, sorted by name token.
Backs the provsql.rv_families() catalog function.
Definition at line 242 of file Distribution.cpp.

| const ConjugateRule * provsql::lookupConjugateRule | ( | const std::string & | likelihood_family, |
| int | wired_param, | ||
| const std::string & | prior_family ) |
Look up the conjugate rule for (likelihood family, wired parameter position, prior family); nullptr on a miss.
Definition at line 137 of file Distribution.cpp.
| const DistributionFamily * provsql::lookupDistributionFamily | ( | const std::string & | name | ) |
Look up a family by its on-disk name token.
Used by parse_distribution_spec to resolve the interned descriptor and expected parameter count; nullptr for an unknown name.
Definition at line 250 of file Distribution.cpp.

| dDNNF provsql::makeDDAuto | ( | BooleanCircuit & | c, |
| gate_t | g ) |
Cost-select a d-DNNF construction route for gate g of Boolean circuit c and build it – the default makeDD route.
A thin entry point over MethodCatalog::chooseAndBuildDD that builds the EvalContext from the Boolean view alone (the d-D portfolio needs no generic-circuit state); the callers that have a method/compiler request route the empty / "default" / "auto" case here and keep BooleanCircuit::makeDD for the named routes (tree-decomposition / interpret-as-dd / compilation, plus makeDD's own internal interpret -> tree-decomposition -> compiler fallback chain).
Definition at line 1721 of file probability_evaluate.cpp.


| std::unique_ptr< Distribution > provsql::makeDistribution | ( | const DistributionSpec & | spec | ) |
Construct the per-family Distribution for a parsed spec.
Returns nullptr only for a spec with a null family pointer (which parse_distribution_spec never produces). Parameter-validity guards live in the family methods (e.g. pdf returns NaN for a non-positive σ).
Definition at line 257 of file Distribution.cpp.

| bool provsql::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)).
Accepts both operand orders (agg left or right), flipping op in the latter case. Mirrors pw_from_cmp_gate's build_from and the SUM-of-1s → COUNT remap. Returns false (leaving out untouched) on any shape mismatch; cheap to call.
| [in] | gc | Circuit to inspect. |
| [in] | cmp | Candidate gate_cmp. |
| [out] | out | Filled on success. |
true iff the shape matched. Definition at line 17 of file CmpEvaluatorCommon.cpp.


| std::optional< ClosedFormShape > provsql::matchClosedFormDistribution | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > | event_root ) |
Detect any of the closed-form shapes supported by rv_analytical_curves.
Generalisation of matchTruncatedSingleRv that adds Bernoulli mixtures, categoricals, and Dirac (scalar gate_value) roots. Conditioning (event_root) is honoured for bare RV roots only; Dirac / categorical / mixture roots bail when the event isn't gate_one (the post-load-simplification "always true" default).
Returns std::nullopt when none of the supported shapes match; callers fall back to histogram-only rendering.
Definition at line 1679 of file RangeCheck.cpp.


| std::optional< TruncatedSingleRv > provsql::matchTruncatedSingleRv | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| std::optional< gate_t > | event_root ) |
Detect a closed-form, optionally-truncated single-RV shape.
Common shape-detection helper shared by every closed-form single-RV consumer:
try_truncated_closed_form (truncated moments, Expectation.cpp);try_truncated_closed_form_sample (rejection-free sampling, MonteCarloSampler.cpp);rv_analytical_curves (PDF / CDF overlay, RvAnalyticalCurves.cpp).Returns std::nullopt when the shape is not tractable:
root is not a bare gate_rv;extra does not parse as a DistributionSpec;event_root resolves to gate_zero (event already decided infeasible by runRangeCheck);collectRvConstraints fails (incomplete walk);lo >= hi).When event_root is omitted or resolves to gate_one, the returned TruncatedSingleRv carries the RV's natural support and truncated = false; callers that don't distinguish the conditional and unconditional cases (e.g. the analytical-curves x-range chooser) can read uniformly off the result.
Definition at line 1507 of file RangeCheck.cpp.


| ConditionalScalarPairSamples provsql::monteCarloConditionalScalarPairSamples | ( | const GenericCircuit & | gc, |
| gate_t | root_a, | ||
| gate_t | root_b, | ||
| gate_t | event_root, | ||
| unsigned | samples ) |
Rejection-sample the PAIR (root_a, root_b) conditioned on event_root.
The pair analogue of monteCarloConditionalScalarSamples: per iteration the indicator is evaluated first, and on acceptance both scalar roots are evaluated against the SAME per-iteration caches, so any stochastic leaf shared between the two values and/or the event produces one draw all three observe. The accepted pairs are samples from the joint conditional distribution \((A, B) \mid E\) – the input the single-pass covariance / correlation estimators need.
Definition at line 853 of file MonteCarloSampler.cpp.

| ConditionalScalarSamples provsql::monteCarloConditionalScalarSamples | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| gate_t | event_root, | ||
| unsigned | samples ) |
Rejection-sample root conditioned on event_root.
For each of samples iterations, the shared Sampler resets its per-iteration cache, then:
event_root as a Boolean (populating bool_cache_ and scalar_cache_ for every gate_rv / gate_input touched);true, evaluates root as a scalar using the SAME caches, so any shared gate_t leaf produces one draw that the indicator and the value both observe;This coupling is the entire point of routing the conditional path through one joint circuit: a gate_rv reachable from both root and event_root has the same gate_t and therefore shares its per-iteration draw between the indicator (which decides acceptance) and the value (which we record). The accepted draws are samples from the conditional distribution \(X \mid A\) where X = root and A = event_root.
| gc | Circuit (typically from getJointCircuit). |
| root | Scalar gate whose value we sample. |
| event_root | Boolean gate that the iteration must satisfy. |
| samples | Number of iterations to attempt. |
Definition at line 823 of file MonteCarloSampler.cpp.


| std::vector< double > provsql::monteCarloJointDistribution | ( | const GenericCircuit & | gc, |
| const std::vector< gate_t > & | cmps, | ||
| unsigned | samples ) |
Estimate the joint distribution of cmps via Monte Carlo.
For each of samples worlds, samples the underlying continuous island once (shared gate_rv leaves use the same per-iteration draw, per monteCarloRV's evalScalar) and evaluates each comparator in cmps; the k = cmps.size() resulting bits form a single word w with bit i = result of cmps[i]. The returned vector has size 2^k; entry w is the empirical probability that the joint outcome w occurred.
Used by the multi-cmp half of the hybrid evaluator's island decomposer to inline a categorical distribution over the k cmps that share an island; cmps must all sit over a continuous island whose scalar evaluation reuses common gate_rv leaves so the cmp draws are correctly correlated.
k is capped at 30 (the result vector size is 2^30) to keep memory bounded; the decomposer enforces a much tighter cap (k_max in HybridEvaluator.cpp) so this is purely a safety limit. Throws CircuitException above the cap.
| gc | The circuit. |
| cmps | The comparators jointly evaluated. |
| samples | Number of independent worlds. |
w (bit i = cmps[i] outcome). Definition at line 739 of file MonteCarloSampler.cpp.

| double provsql::monteCarloRV | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| unsigned | samples ) |
Run Monte Carlo on a circuit that may contain gate_rv leaves.
| gc | The circuit (loaded from the mmap store via CircuitFromMMap). |
| root | Gate to evaluate as a Boolean expression. |
| samples | Number of independent worlds to sample. |
root is true.| CircuitException | on malformed circuits (unknown gate kind in a Boolean position, malformed extra, unknown comparison operator, etc.). |
Definition at line 677 of file MonteCarloSampler.cpp.


| double provsql::monteCarloRVStopping | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| double | eps, | ||
| double | delta, | ||
| unsigned long | max_samples, | ||
| unsigned long & | samples_used, | ||
| bool & | reached_target ) |
Whole-circuit (eps,delta)-relative probability via the Dagum-Karp-Luby-Ross stopping rule.
The general-Bernoulli case of BooleanCircuit::karpLubyStopping, driven by the RV-aware Sampler's evalBool rather than by DNF coverage trials, so it applies to ANY circuit the sampler can evaluate (plain Boolean, continuous gate_rv, and HAVING gate_cmp / gate_agg) – the universal relative estimator. Draws whole-circuit worlds until the success count reaches the threshold Y1 = 1 + (1+eps)*4*(e-2)*ln(2/delta)/eps^2, then returns Y1/N: a relative (eps,delta) approximation of Pr[root]. The sample count N adapts to the true Pr[root] (expected Y1/Pr[root]), so the cost is polynomial precisely when Pr[root] is at least 1/poly.
Sampling stops early at max_samples worlds; reached_target is then false and the return is the plain unbiased success/N mean over the spent budget (the relative target was not met – the caller reports the weaker, additive guarantee actually achieved).
| gc | The circuit. |
| root | Gate to evaluate as a Boolean event. |
| eps | Target relative error (in (0,1]). |
| delta | Target failure probability (in (0,1)). |
| max_samples | Hard cap on the number of worlds drawn. |
| samples_used | Output: worlds actually drawn. |
| reached_target | Output: whether the threshold was reached before the cap (i.e. the relative guarantee holds). |
Definition at line 695 of file MonteCarloSampler.cpp.


| std::pair< std::vector< double >, std::vector< double > > provsql::monteCarloScalarPairSamples | ( | const GenericCircuit & | gc, |
| gate_t | root_a, | ||
| gate_t | root_b, | ||
| unsigned | samples ) |
Coupled per-iteration draws of two scalar roots.
Each iteration resets the per-iteration cache once and evaluates both roots against it, so any stochastic leaf shared between root_a and root_b produces a single draw both observe: the returned pairs are samples from the JOINT distribution of (A, B). Backs the mutual-information plug-in estimator.
Definition at line 797 of file MonteCarloSampler.cpp.


| std::vector< double > provsql::monteCarloScalarSamples | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| unsigned | samples ) |
Sample a scalar sub-circuit samples times and return the draws.
root must yield a scalar (gate_value, gate_rv, or gate_arith over scalar children); otherwise a CircuitException is thrown. Each iteration uses a fresh per-iteration memo cache so that repeated occurrences of the same gate_rv UUID inside an arithmetic expression share their draw within an iteration but not across iterations.
The RNG is seeded from provsql.monte_carlo_seed exactly like monteCarloRV; pinning the GUC makes the returned vector reproducible.
Used as the universal MC fallback by the analytical evaluators (Expectation, HybridEvaluator) when structural shortcuts cannot decide a sub-expression. Returning the raw draws (rather than a single statistic) lets callers compute any combination of moments from a single sampling pass.
Definition at line 777 of file MonteCarloSampler.cpp.


| double provsql::numericQuantile | ( | const Distribution & | d, |
| double | p ) |
Numeric inverse CDF: monotone bisection of cdf() over the family's integration window.
Family-agnostic fallback for families whose quantile() declines (no elementary inverse CDF – Erlang, Gamma): needs only cdf and integrationRange, converges to ~1 ulp, and is deterministic, so the quantile readout stays analytic instead of dropping to Monte Carlo. p outside the window's mass clamps to the window edge (the window covers all but a vanishing tail). NaN when the CDF or the window is unavailable, matching the NaN-as-undecided contract of the other analytic paths.
Definition at line 197 of file Distribution.cpp.

| std::optional< DistributionSpec > provsql::parse_distribution_spec | ( | const std::string & | s | ) |
Parse the on-disk text encoding of a gate_rv distribution.
Accepts "normal:μ,σ", "uniform:a,b", "exponential:λ", "erlang:k,λ", and "gamma:k,λ", with parameters parseable as double. Whitespace around the kind name and parameters is tolerated.
| s | The byte string read from MMappedCircuit::getExtra. |
std::nullopt on malformed input or when any parameter is a wire reference (a compound / latent leaf, which has no constant-parameter closed form – use parse_distribution_template for that case). Definition at line 137 of file RandomVariable.cpp.


| std::optional< DistributionTemplate > provsql::parse_distribution_template | ( | const std::string & | s | ) |
Parse the on-disk text encoding of a gate_rv distribution, keeping wired (token) parameters as wire references.
Accepts the same family tokens as parse_distribution_spec, but a parameter may be either a decimal literal or a wire reference "$i" (0-based index into the gate's wire vector). The literal form is byte-identical to the pre-latent encoding, so an all-literal spec round-trips unchanged.
| s | The byte string read from MMappedCircuit::getExtra. |
std::nullopt on malformed input. Definition at line 108 of file RandomVariable.cpp.


| double provsql::parseDoubleStrict | ( | const std::string & | s | ) |
Strictly parse s as a double.
Used by every consumer that has to interpret the extra byte string of a gate_value: the sampler when sampling a constant leaf, the interval-arith pass when bounding a constant leaf, and any future scalar-evaluation pass. Lives here (rather than next to one specific consumer) so the parsing convention is shared.
| CircuitException | on empty input, non-numeric input, or trailing characters past the parsed double. |
Definition at line 23 of file RandomVariable.cpp.

| double provsql::pdfAt | ( | const DistributionSpec & | d, |
| double | c ) |
Closed-form probability density \(f(c)\) for a basic distribution.
Used by rv_analytical_curves to ship a sampled curve to clients (Studio's Distribution profile overlay). Returns 0 outside the natural support and NaN for parameter shapes the analytical form doesn't cover (e.g. non-integer Erlang shape).
1/(b-a) for a<=c<=b, 0 otherwise.λ·exp(-λc) for c>=0, 0 otherwise.k>=1): \(\frac{\lambda^k c^{k-1} e^{-\lambda c}}{(k-1)!}\) for c>=0, 0 otherwise. Definition at line 28 of file AnalyticEvaluator.cpp.

|
inline |
Standard normal CDF Φ(z) = ½(1 + erf(z/√2)).
Mirrors the NormalDistribution::cdf convention so the truncation formulas here use the same numerics.
Definition at line 51 of file DistributionCommon.h.
|
inline |
Standard normal pdf φ(z) = exp(-z²/2)/√(2π).
Definition at line 42 of file DistributionCommon.h.
| std::vector< double > provsql::posteriorResample | ( | const WeightedPosterior & | post, |
| unsigned | n ) |
Sampling-importance-resampling: draw n posterior samples from a weighted particle set (proportional to weight, with replacement).
Turns the weighted particles of importanceSampleConditional into (approximately) unweighted posterior draws for rv_sample. Returns an empty vector when there is no positive-weight particle. The RNG is seeded from provsql.monte_carlo_seed, like every other sampling path.
Definition at line 949 of file MonteCarloSampler.cpp.


|
static |
2^k with the exponent clamped to keep the cost finite (a clamped exponent still sorts the method dead last – it is then a guaranteed fall-through).
Definition at line 882 of file probability_evaluate.cpp.
| void provsql::registerClosureRule | ( | const char * | x, |
| const char * | y, | ||
| ClosureRule | rule ) |
Register the sum-closure rule for a family pair (name-token keyed, like the comparator rules).
Definition at line 114 of file Distribution.cpp.

| void provsql::registerComparatorRule | ( | const char * | x, |
| const char * | y, | ||
| ComparatorRule | rule ) |
Register the \(P(X < Y)\) closed form for a family pair.
Keyed by the families' name tokens rather than descriptor pointers so a family file can register a cross-family rule without depending on another file's static-initialisation order.
Definition at line 108 of file Distribution.cpp.

| void provsql::registerConjugateRule | ( | const char * | likelihood_family, |
| int | wired_param, | ||
| const char * | prior_family, | ||
| const ConjugateRule & | rule ) |
Register the conjugate update for observations of likelihood_family whose parameter wired_param (0 = p1, 1 = p2) is the latent, against a prior of prior_family.
Definition at line 130 of file Distribution.cpp.

| void provsql::registerDistributionFamily | ( | const DistributionFamily & | descriptor | ) |
Register a family; called by the registrar at static init.
Definition at line 237 of file Distribution.cpp.

| void provsql::registerProductRule | ( | const char * | x, |
| const char * | y, | ||
| ProductRule | rule ) |
Register the product-closure rule for a family pair (name-token keyed, like the sum-closure rules).
Definition at line 119 of file Distribution.cpp.

| void provsql::registerTransformRule | ( | const char * | transform, |
| const char * | family, | ||
| TransformRule | rule ) |
Register the image rule for transform ("ln" / "exp" / ...; the evaluator maps its arith opcodes to these names, keeping this registry opcode-free) applied to family.
Definition at line 124 of file Distribution.cpp.

| void provsql::resolveComparators | ( | GenericCircuit & | gc, |
| gate_t | root, | ||
| bool | simplify, | ||
| bool | decompose ) |
Run the comparator-resolution pipeline on gc, rewriting every gate_cmp (RV comparison, HAVING aggregate comparison) into Boolean structure so the downstream getBooleanCircuit / BoolExpr translation never meets a raw comparator.
The single source of truth for the resolution pipeline. Two flags carry the (principled) differences between the two callers:
| gc | the circuit whose comparators are resolved in place. |
| root | the gate below which comparators are rewritten. |
| simplify | run runHybridSimplifier, which folds gate_arith-over- closed-form distributions. Sound for the probability path (the circuit collapses to Boolean, so a folded value RV is never observed as a value) but it MUST be false for the scalar-moment path: that path takes moments over the very value structure the fold rewrites, and a value-structure shared latent (mu_i + d inside normal(mu_i+d, s)) would be decoupled into independent Normals, corrupting the covariance. |
| decompose | run runHybridDecomposer, which groups correlated comparators into a gate_mulinput joint table (capped at JOINT_TABLE_K_MAX). The probability path wants it; the moment path leaves it false so genuinely-correlated comparators stay raw and fall to the direct RV Monte-Carlo sampler, which couples the shared base RV at any group size (no k cap, no joint-table quantisation). |
Emits the "shortcut by probability-side pre-pass" NOTICE at provsql.verbose_level >= 5.
Definition at line 46 of file ComparatorResolution.cpp.


| unsigned provsql::runAggMarginalEvaluator | ( | GenericCircuit & | gc | ) |
Run the safe-join aggregate marginal-vector pre-pass over gc.
For every gate_cmp matching the hierarchical-join shape (see file docstring) over COUNT / SUM / MIN / MAX, computes the comparator's exact probability through the recursive hierarchical engine and replaces the cmp by a Bernoulli gate_input via GenericCircuit::resolveCmpToBernoulli. Leaves every other cmp untouched. COUNT / SUM use the count/weighted-sum distribution (block mixture + additive convolution); MIN / MAX reduce to a handful of "all of a value-thresholded subset absent" probabilities over the same hierarchical recursion.
| gc | Circuit to mutate in place. |
Definition at line 1114 of file AggMarginalEvaluator.cpp.


| unsigned provsql::runAnalyticEvaluator | ( | GenericCircuit & | gc | ) |
Run the closed-form CDF resolution pass over gc.
For every gate_cmp in the circuit whose two sides match one of the supported shapes (see the header docstring), computes the comparator's probability analytically and replaces the cmp by a Bernoulli gate_input via GenericCircuit::resolveCmpToBernoulli.
| gc | Circuit to mutate in place. |
Definition at line 238 of file AnalyticEvaluator.cpp.


| unsigned provsql::runConstantFold | ( | GenericCircuit & | gc | ) |
Constant-fold pass over every gate_arith in gc.
Walks the circuit bottom-up and replaces any gate_arith whose children all evaluate to scalar constants with the equivalent gate_value (e.g. arith(NEG, value:2) becomes value:-2, arith(PLUS, value:1, value:2) becomes value:3).
Strictly a subset of runHybridSimplifier (only try_eval_constant fires; no family closures, identity drops, or mixture lifts), and therefore safe to run at load time alongside runRangeCheck and foldSemiringIdentities: the resulting gate_value gates carry no random identity, so no consumer's shared-RV coupling is broken by the rewrite. The family closures stay behind the separate hybrid_evaluation GUC because they replace a multi-leaf subtree with a fresh gate_rv UUID and would decouple shared base RVs that other parts of the circuit reference.
Lifts the -c::random_variable parser quirk (which builds an arith(NEG, value:c) gate rather than value:-c) into a clean gate_value before downstream consumers like collectRvConstraints / asRvVsConstCmp inspect the circuit.
Definition at line 1224 of file HybridEvaluator.cpp.


| unsigned provsql::runCountCmpEvaluator | ( | GenericCircuit & | gc | ) |
Run the Poisson-binomial pre-pass over gc.
For every gate_cmp whose shape matches the first-slice scope (see file docstring), computes the comparator's probability by Poisson-binomial CDF and replaces the cmp by a Bernoulli gate_input via GenericCircuit::resolveCmpToBernoulli.
| gc | Circuit to mutate in place. |
Definition at line 206 of file CountCmpEvaluator.cpp.


| unsigned provsql::runHavingAlwaysTrueRewriter | ( | GenericCircuit & | gc | ) |
Probability-side pre-pass: rewrite HAVING-style gate_cmp gates that are provably TRUE on the agg's value-interval into an OR over the agg's per-row K-gates.
Probability-side pre-pass that rewrites gate_cmp gates provably true on the agg's value-interval to a gate_plus over the agg's per-row K-gates.
Companion to runCountCmpEvaluator's Poisson-binomial pre-pass: where that one resolves COUNT op C to a closed-form Bernoulli, this one catches the always-true sub-case (e.g. COUNT <= K with K >= N inputs, or any aggregator whose value-interval entirely satisfies the predicate) and replaces the cmp with gate_plus over the agg's K-gates – the "group is non-empty" indicator.
Why a separate pass: runRangeCheck deliberately blocks TRUE decisions because gate_one is universally unsound for HAVING (it would credit the empty world). The safe TRUE rewrite "OR of K-gates" requires absorptive gate_plus semantics (probability, Boolean, formula, why, which, max-min, max-max), so the pass is restricted to the probability-evaluate path where absorption is guaranteed by the downstream BoolExpr translation.
Fires regardless of provsql.cmp_probability_evaluation: when the Poisson-binomial path is disabled (developer A/B testing), this lighter shortcut still catches the always-true case and spares the d-DNNF compiler the 2^N-clause DNF that provsql_having's enumerate_valid_worlds would otherwise emit.
Same matching contract as decideAggVsConstCmp for the agg side: cmp wires must be {gate_agg, scalar-const-encoded-as-semimod}, the agg's children must all be gate_semimod, and the agg kind must be one of COUNT / SUM / MIN / MAX (the only kinds with an interval). Mismatches leave the cmp untouched.
| gc | Circuit to mutate in place. |
Catches the always-true HAVING case (e.g. COUNT <= K with K >= N) that runRangeCheck deliberately leaves alone (the universally-sound gate_one rewrite would credit the empty world). Sound only in absorptive semirings; restricted to the probability-evaluate path.
RangeCheck.cpp for the full contract. Definition at line 1220 of file RangeCheck.cpp.


| unsigned provsql::runHybridDecomposer | ( | GenericCircuit & | gc, |
| unsigned | samples ) |
Marginalise unresolved continuous-island gate_cmp gates into Bernoulli gate_input leaves.
Runs after RangeCheck, the simplifier (runHybridSimplifier), and AnalyticEvaluator have done what they can. Picks up the residual comparators whose two sides are an entirely continuous island (subtree of gate_value, gate_rv, gate_arith with no Boolean structure underneath) but whose specific shape is not one the analytic CDF resolver handles – e.g. Normal + Uniform > 0, heterogeneous-rate sums of exponentials, or other compositions the simplifier could not fold to a bare distribution leaf.
Each qualifying comparator is marginalised by drawing samples worlds and applying the comparator scalar-by-scalar; the empirical probability replaces the gate_cmp via resolveCmpToBernoulli. The circuit downstream becomes purely Boolean, so the existing independent / tree-decomposition / compilation methods become available on circuits that would otherwise have to fall through to whole-circuit MC.
Singleton groups are marginalised into a single gate_input via GenericCircuit::resolveCmpToBernoulli.
Multi-cmp shared-island groups (k comparators sharing one or more base gate_rv leaves, detected via pairwise footprint overlap with union-find) are resolved by inlining a 2^k joint distribution table:
gate_input acts as the block key.gate_mulinput per joint outcome with positive probability, all sharing the key, carries the joint mass (mutually-exclusive block).gate_plus over the mulinputs whose joint outcome word has the comparator's bit set. The downstream OR over the rewritten comparators thereby observes the dependent joint distribution: mulinputs across comparators dedup at OR sites in BooleanCircuit::independentEvaluationInternal (or are Bayesian-tree-rewritten by rewriteMultivaluedGates before tree-decomposition / monte-carlo / external compilers). Groups with k > JOINT_TABLE_K_MAX (currently 8, i.e. 256 outcomes) fall through to whole-circuit MC to keep the materialisation bounded.| gc | Circuit to mutate in place. |
| samples | Number of MC iterations used per marginalisation. Callers typically pass provsql_rv_mc_samples. |
Definition at line 2097 of file HybridEvaluator.cpp.


| unsigned provsql::runHybridSimplifier | ( | GenericCircuit & | gc | ) |
Run the peephole simplifier over gc.
Visits every gate in post-order and applies the closure rules described in the header comment until a fixed point is reached.
| gc | Circuit to mutate in place. |
Definition at line 1301 of file HybridEvaluator.cpp.


| unsigned provsql::runMinMaxCmpEvaluator | ( | GenericCircuit & | gc | ) |
Run the MIN / MAX closed-form pre-pass over gc.
For every gate_cmp whose shape matches a MIN(a)/MAX(a) op C HAVING predicate over independent private contributors, computes the comparator's probability in closed form and replaces the cmp by a Bernoulli gate_input via GenericCircuit::resolveCmpToBernoulli.
| gc | Circuit to mutate in place. |
Definition at line 102 of file MinMaxCmpEvaluator.cpp.


| unsigned provsql::runRangeCheck | ( | GenericCircuit & | gc | ) |
Run the support-based pruning pass over gc.
For every gate_cmp in the circuit, computes the interval of (lhs - rhs) via interval arithmetic over gate_value, gate_rv, and gate_arith leaves; when the interval is provably above, below, or disjoint from zero, replaces the gate_cmp by a Bernoulli gate_input carrying the decided probability (0 or 1).
Comparators whose interval is inconclusive (overlaps zero) are left intact for downstream passes.
Iterates every gate (rather than walking from a specific root) so that a single sweep at getGenericCircuit time benefits every downstream consumer regardless of which sub-circuit they later traverse.
| gc | Circuit to mutate in place. |
Definition at line 976 of file RangeCheck.cpp.


| unsigned provsql::runSumCmpEvaluator | ( | GenericCircuit & | gc | ) |
Run the weighted-sum DP pre-pass over gc.
For every gate_cmp whose shape matches a SUM(a) op C HAVING predicate over independent private contributors and whose reachable-sum range is within kMaxSumRange, computes the comparator's probability by the subset-sum DP and replaces the cmp by a Bernoulli gate_input via GenericCircuit::resolveCmpToBernoulli.
| gc | Circuit to mutate in place. |
Definition at line 43 of file SumCmpEvaluator.cpp.


| std::mt19937_64 provsql::seedRng | ( | ) |
The shared Monte Carlo generator, seeded from the provsql.monte_carlo_seed GUC (-1 = non-deterministic from std::random_device).
Every sampling entry point in this file seeds through here; exposed so closed-form paths that still need draws (the conjugate-posterior exact sampler behind rv_sample) share the same pinned-seed reproducibility.
Definition at line 29 of file MonteCarloSampler.cpp.

|
static |
Unconditional probability mass of a shape over the interval [lo, hi].
TruncatedSingleRv arms supplied here must carry truncated == false (the unconditional shape); the helper uses the natural support to compute the CDF endpoints, so calling with an already-truncated input would double-truncate.
Recursive: a Bernoulli mixture's mass is the Bernoulli-weighted combination of its arms' masses. Categorical mass is the sum of outcome masses falling in the interval. Dirac mass is 1 iff the Dirac value sits in the interval, else 0. Returns std::nullopt when a leaf's spec defeats the closed-form CDF (e.g. non-integer Erlang shape – cdfAt returns NaN there).
Definition at line 1582 of file RangeCheck.cpp.


| double provsql::simpsonIntegrate | ( | double | lo, |
| double | hi, | ||
| int | N, | ||
| F && | f ) |
Composite-Simpson \(\int_{lo}^{hi} f(x)\,dx\) with N panels.
N must be even (every caller passes kSimpsonPanels). A NaN from f aborts the quadrature and returns NaN — the callers' shared convention for "a density / CDF is undefined here, decline to MC".
Definition at line 41 of file PivotIntegration.h.

|
static |
Admissibility of a method's guarantee under a requested tolerance.
The paths nest Exact ⊂ Relative ⊂ Additive: a method is admissible iff its guarantee is at least as tight as the request (an exact method serves any path – "exact when cheaper"; a relative method serves relative & additive; an additive method serves only additive). This both widens the relative/additive portfolios to the approximate members AND keeps the exact path (which calls chooseAndRun with an Exact tolerance) from ever selecting an approximate method.
Definition at line 1750 of file probability_evaluate.cpp.

|
inline |
Shorthand for ToolRegistry::instance().
Definition at line 224 of file ToolRegistry.h.


|
static |
Conditional shape after truncating the underlying variable to [lo, hi].
Bare-RV arm: intersects its natural / current truncation with [lo, hi] and marks the result truncated so downstream shape_pdf renormalises by the truncated CDF. Dirac: keep iff value ∈ interval, otherwise nullopt (infeasible). Categorical: keep outcomes in interval, renormalise masses. Bernoulli mixture: recursively truncate each arm and reweight the Bernoulli by the ratio of arm masses (the standard \( \pi' = \pi Z_L / (\pi Z_L + (1-\pi) Z_R) \) update); a fully-eliminated arm degenerates to the surviving one. Returns nullopt when the truncated shape has zero mass (caller can raise infeasibility).
Definition at line 1628 of file RangeCheck.cpp.


| std::optional< std::vector< double > > provsql::try_truncated_closed_form_sample | ( | const GenericCircuit & | gc, |
| gate_t | root, | ||
| gate_t | event_root, | ||
| unsigned | n ) |
Try to draw n exact samples from the conditional distribution of root given event_root via closed-form truncation, bypassing MC rejection.
Fires only when root is a bare gate_rv whose family admits a closed-form truncation (Uniform / Exponential / Normal) and collectRvConstraints can extract a sound interval from event_root. Other shapes (arith composites, mixtures, Erlang, un-extractable events) return std::nullopt so the caller can fall back to monteCarloConditionalScalarSamples.
Sampling kernels:
collectRvConstraints already intersects with [a, b], so the draw is a plain U(lo, hi) on the intersected interval. 100% acceptance.X > c: memorylessness yields c + Exp(λ). Two-sided lo < X < hi: inverse-CDF via std::log1p / std::expm1 for numerical accuracy near the support boundary.std::erf (matching AnalyticEvaluator::cdfAt); inverse uses the Beasley-Springer-Moro rational approximation (~1e-7 accuracy, ample for sampling).Empty / degenerate truncations (lo >= hi after intersection) also return std::nullopt so the caller's MC fallback can emit its usual "accepted 0" diagnostic.
The RNG is seeded from provsql.monte_carlo_seed identically to monteCarloScalarSamples, so a pinned seed gives reproducible output on either path.
Definition at line 884 of file MonteCarloSampler.cpp.


|
static |
Definition at line 844 of file probability_evaluate.cpp.
|
static |
Definition at line 845 of file probability_evaluate.cpp.
|
static |
Definition at line 846 of file probability_evaluate.cpp.
|
static |
Definition at line 867 of file probability_evaluate.cpp.
|
static |
Definition at line 866 of file probability_evaluate.cpp.
|
static |
Definition at line 877 of file probability_evaluate.cpp.
|
static |
Definition at line 878 of file probability_evaluate.cpp.
|
static |
Definition at line 830 of file probability_evaluate.cpp.
|
static |
Definition at line 831 of file probability_evaluate.cpp.
|
static |
Definition at line 865 of file probability_evaluate.cpp.
|
static |
Definition at line 863 of file probability_evaluate.cpp.
|
static |
Definition at line 832 of file probability_evaluate.cpp.
|
static |
Definition at line 833 of file probability_evaluate.cpp.
|
static |
Definition at line 864 of file probability_evaluate.cpp.
|
static |
Definition at line 838 of file probability_evaluate.cpp.
|
static |
Definition at line 847 of file probability_evaluate.cpp.
|
inlineconstexpr |
Definition at line 20 of file DistributionCommon.h.
|
inlineconstexpr |
Definition at line 19 of file DistributionCommon.h.
|
static |
Sanity bound on the reachable-input count for the auto-chosen 2^N possible-worlds enumeration: above it the method drops out of the portfolio so it is never attempted (its 2^N cost already deprioritises it, but this guards against a catastrophic last-resort attempt if every cheaper method failed).
The by-name call ignores it (up to possibleWorlds' own 64 limit). The actual small-N-vs-compile crossover is a cost comparison, not this bound.
Definition at line 806 of file probability_evaluate.cpp.
|
static |
Largest clause count for which the auto-chosen sieve (2^m inclusion-exclusion) is admitted (matches BooleanCircuit::sieve's internal cap).
The by-name call is unaffected.
Definition at line 811 of file probability_evaluate.cpp.
|
constexpr |
Panel count shared by every composite-Simpson quadrature over a distribution's integration range: exact for the low-degree polynomial integrands of the Uniform cases, high-accuracy otherwise.
Definition at line 31 of file PivotIntegration.h.