![]() |
ProvSQL SQL API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
Custom type random_variable: a thin wrapper around a provenance gate UUID, used to expose continuous probabilistic c-tables in SQL. More...
Types | |
| TYPE | provsql.rv_percentile_state |
Transition state for rv_percentile_impl: the fraction (from the first row) plus the interleaved indicator/value token pairs. More... | |
Functions | |
| random_variable | provsql.random_variable_in (CSTRING) |
| Input function for the random_variable type. | |
| CSTRING | provsql.random_variable_out (random_variable) |
| Output function for the random_variable type. | |
| random_variable | provsql.random_variable_make (UUID tok) |
| Build a random_variable from a UUID (internal). | |
| CREATE | provsql.CAST (random_variable AS UUID) WITHOUT FUNCTION AS ASSIGNMENT |
| Binary-coercible cast random_variable -> UUID. | |
| CREATE | provsql.CAST (UUID AS random_variable) WITHOUT FUNCTION |
| random_variable | provsql.agg_token_to_random_variable (AGG_TOKEN a) |
Coerce an AGG_TOKEN to a random_variable (its circuit token). | |
| random_variable | provsql.CAST(AGG_TOKEN AS RANDOM_VARIABLE) (AGG_TOKEN) |
| BOOL | provsql.is_finite_float8 (DOUBLE PRECISION x) |
Internal: true iff x is a finite (non-NaN, non-±∞) float8. | |
| random_variable | provsql.rv_parametric2 (TEXT family, UUID p1_tok, DOUBLE PRECISION p1_lit, UUID p2_tok, DOUBLE PRECISION p2_lit) |
Internal: build a two-parameter latent gate_rv. | |
| random_variable | provsql.rv_parametric1 (TEXT family, UUID p_tok) |
Internal: build a one-parameter latent gate_rv (rate/scale). | |
| random_variable | provsql.normal (random_variable mu, DOUBLE PRECISION sigma) |
| normal(mu, sigma) | |
| random_variable | provsql.normal (DOUBLE PRECISION mu, random_variable sigma) |
| random_variable | provsql.normal (random_variable mu, random_variable sigma) |
| random_variable | provsql.logistic (random_variable mu, DOUBLE PRECISION s) |
| logistic(mu, s) | |
| random_variable | provsql.logistic (DOUBLE PRECISION mu, random_variable s) |
| random_variable | provsql.logistic (random_variable mu, random_variable s) |
| random_variable | provsql.uniform (random_variable a, DOUBLE PRECISION b) |
| uniform(a, b) | |
| random_variable | provsql.uniform (DOUBLE PRECISION a, random_variable b) |
| random_variable | provsql.uniform (random_variable a, random_variable b) |
| random_variable | provsql.exponential (random_variable lambda) |
| exponential(lambda) | |
| random_variable | provsql.gamma (random_variable k, DOUBLE PRECISION lambda) |
| gamma(k, lambda) | |
| random_variable | provsql.gamma (DOUBLE PRECISION k, random_variable lambda) |
| random_variable | provsql.gamma (random_variable k, random_variable lambda) |
| random_variable | provsql.lognormal (random_variable mu, DOUBLE PRECISION sigma) |
| lognormal(mu, sigma) | |
| random_variable | provsql.lognormal (DOUBLE PRECISION mu, random_variable sigma) |
| random_variable | provsql.lognormal (random_variable mu, random_variable sigma) |
| random_variable | provsql.weibull (random_variable k, DOUBLE PRECISION lambda) |
| weibull(k, lambda) | |
| random_variable | provsql.weibull (DOUBLE PRECISION k, random_variable lambda) |
| random_variable | provsql.weibull (random_variable k, random_variable lambda) |
| random_variable | provsql.pareto (random_variable xm, DOUBLE PRECISION alpha) |
| pareto(xm, alpha) | |
| random_variable | provsql.pareto (DOUBLE PRECISION xm, random_variable alpha) |
| random_variable | provsql.pareto (random_variable xm, random_variable alpha) |
| random_variable | provsql.beta (random_variable alpha, DOUBLE PRECISION beta) |
| beta(alpha, beta) | |
| random_variable | provsql.beta (DOUBLE PRECISION alpha, random_variable beta) |
| random_variable | provsql.beta (random_variable alpha, random_variable beta) |
| random_variable | provsql.inverse_gamma (random_variable alpha, DOUBLE PRECISION beta) |
| inverse_gamma(alpha, beta) | |
| random_variable | provsql.inverse_gamma (DOUBLE PRECISION alpha, random_variable beta) |
| random_variable | provsql.inverse_gamma (random_variable alpha, random_variable beta) |
| random_variable | provsql.inverse_gaussian (random_variable mu, DOUBLE PRECISION lambda) |
| inverse_gaussian(mu, lambda) | |
| random_variable | provsql.inverse_gaussian (DOUBLE PRECISION mu, random_variable lambda) |
| random_variable | provsql.inverse_gaussian (random_variable mu, random_variable lambda) |
| random_variable | provsql.normal (DOUBLE PRECISION mu, DOUBLE PRECISION sigma) |
| Construct a normal-distribution random variable. | |
| random_variable | provsql.logistic (DOUBLE PRECISION mu, DOUBLE PRECISION s) |
| Construct a logistic-distribution random variable Logistic(μ, s). | |
| random_variable | provsql.uniform (DOUBLE PRECISION a, DOUBLE PRECISION b) |
| Construct a uniform-distribution random variable on [a, b]. | |
| random_variable | provsql.exponential (DOUBLE PRECISION lambda) |
| Construct an exponential-distribution random variable with rate λ | |
| random_variable | provsql.erlang (INTEGER k, DOUBLE PRECISION lambda) |
Construct an Erlang-distribution random variable, sum of k i.i.d. | |
| random_variable | provsql.gamma (DOUBLE PRECISION k, DOUBLE PRECISION lambda) |
Construct a gamma-distribution random variable with shape k (any positive real) and rate lambda. | |
| random_variable | provsql.chi_squared (DOUBLE PRECISION k) |
Construct a chi-squared random variable with k degrees of freedom: syntactic sugar for gamma(k/2, 1/2). | |
| random_variable | provsql.lognormal (DOUBLE PRECISION mu, DOUBLE PRECISION sigma) |
Construct a log-normal random variable: exp of a Normal(mu, sigma), parameterised by the underlying normal (so its median is exp(mu) and its mean exp(mu + sigma^2/2)). | |
| random_variable | provsql.weibull (DOUBLE PRECISION k, DOUBLE PRECISION lambda) |
Construct a Weibull random variable with shape k and scale lambda. | |
| random_variable | provsql.pareto (DOUBLE PRECISION xm, DOUBLE PRECISION alpha) |
Construct a Pareto random variable with scale (minimum) xm and shape alpha. | |
| random_variable | provsql.inverse_gamma (DOUBLE PRECISION alpha, DOUBLE PRECISION beta) |
Construct an inverse-gamma random variable with shape alpha and scale beta. | |
| random_variable | provsql.inverse_gaussian (DOUBLE PRECISION mu, DOUBLE PRECISION lambda) |
Construct an inverse-Gaussian (Wald) random variable with mean mu and shape lambda. | |
| random_variable | provsql.wald (DOUBLE PRECISION mu, DOUBLE PRECISION lambda) |
| Wald distribution: alias for inverse_gaussian. | |
| random_variable | provsql.categorical_from_log_pmf (DOUBLE_PRECISION[] outcomes, DOUBLE_PRECISION[] log_pmf) |
| Build a discrete (categorical) random variable from outcomes and UNNORMALISED log-masses. | |
| random_variable | provsql.poisson (DOUBLE PRECISION lambda) |
Construct a Poisson random variable with mean lambda, as a truncated categorical. | |
| random_variable | provsql.poisson (random_variable lambda) |
Poisson with a LATENT rate: poisson(random_variable). | |
| random_variable | provsql.beta (DOUBLE PRECISION alpha, DOUBLE PRECISION beta) |
| Construct a Beta(α, β) random variable on the unit interval. | |
| random_variable | provsql.binomial (INTEGER n, DOUBLE PRECISION p) |
Construct a Binomial(n, p) random variable (number of successes in n independent trials), as a categorical. | |
| random_variable | provsql.binomial (INTEGER n, random_variable p) |
Binomial with a fixed trial count and a LATENT success probability: binomial(INTEGER, random_variable). | |
| random_variable | provsql.geometric (DOUBLE PRECISION p) |
| Construct a Geometric(p) random variable – the number of TRIALS up to and including the first success (support starting at 1; subtract 1 for the failures convention). | |
| random_variable | provsql.geometric (random_variable p) |
Geometric with a LATENT success probability: geometric(random_variable). | |
| random_variable | provsql.hypergeometric (INTEGER pop_n, INTEGER k_marked, INTEGER n) |
Construct a Hypergeometric(N, K, n) random variable: the number of marked items among n draws WITHOUT replacement from a population of pop_n items of which k_marked are marked. | |
| random_variable | provsql.negative_binomial (DOUBLE PRECISION r, DOUBLE PRECISION p) |
Construct a negative-binomial random variable: the number of FAILURES before the r-th success (support starting at 0), with real r > 0 allowed (the Polya / overdispersed-count parameterisation, the Poisson-Gamma mixture). | |
| random_variable | provsql.negative_binomial (DOUBLE PRECISION r, random_variable p) |
| random_variable | provsql.negative_binomial (random_variable r, DOUBLE PRECISION p) |
| random_variable | provsql.negative_binomial (random_variable r, random_variable p) |
| TABLE | provsql.rv_families () |
| Catalog of the registered continuous-distribution families. | |
| random_variable | provsql.mixture (UUID p, random_variable x, random_variable y) |
| Construct a probabilistic-mixture random variable. | |
| random_variable | provsql.mixture (DOUBLE PRECISION p_value, random_variable x, random_variable y) |
Ad-hoc mixture constructor that mints a fresh anonymous gate_input Bernoulli with probability p_value. | |
| random_variable | provsql.categorical (DOUBLE_PRECISION[] probs, DOUBLE_PRECISION[] outcomes) |
| Categorical-RV constructor over explicit (probabilities, values) arrays. | |
| random_variable | provsql.gmm (DOUBLE_PRECISION[] weights, DOUBLE_PRECISION[] means, DOUBLE_PRECISION[] stddevs) |
| Gaussian-mixture-model (GMM) constructor. | |
| random_variable | provsql.empirical_samples (DOUBLE_PRECISION[] samples) |
Empirical-samples constructor: the ecdf of a sample bundle as a random_variable. | |
| random_variable | provsql.empirical_cdf (DOUBLE_PRECISION[] grid, DOUBLE_PRECISION[] cdf) |
Empirical-CDF constructor: a piecewise-linear CDF table as a random_variable. | |
| random_variable | provsql.as_random (DOUBLE PRECISION c) |
| Lift a deterministic constant into a random_variable. | |
| CREATE | provsql.CAST (DOUBLE PRECISION AS random_variable) WITH FUNCTION as_random(DOUBLE PRECISION) AS IMPLICIT |
| Implicit cast DOUBLE PRECISION -> random_variable (lifts a scalar literal to a constant RV). | |
| random_variable | provsql.as_random (INTEGER c) |
as_random for INTEGER (delegates to the float8 form). | |
| random_variable | provsql.as_random (NUMERIC c) |
as_random for NUMERIC (delegates to the float8 form). | |
| random_variable | provsql.CAST(INTEGER AS RANDOM_VARIABLE) (INTEGER) |
| Implicit cast INTEGER -> random_variable. | |
| random_variable | provsql.CAST(NUMERIC AS RANDOM_VARIABLE) (NUMERIC) |
| Implicit cast NUMERIC -> random_variable. | |
Arithmetic and comparison on random_variable | |
Each binary operator below is declared on This avoids the resolution ambiguity that would arise if both (rv, NUMERIC) and (rv, rv) overloads were declared while implicit casts also existed. Arithmetic operators build a Comparison operators are placeholders that return | |
| CREATE OPERATOR CLASS random_variable_ops DEFAULT FOR TYPE random_variable USING btree AS OPERATOR<, OPERATOR 2<=, OPERATOR 3=, OPERATOR 4 > | provsql.OPERATOR |
| random_variable | provsql.random_variable_plus (random_variable a, random_variable b) |
random_variable + random_variable (gate_arith PLUS). | |
| random_variable | provsql.random_variable_minus (random_variable a, random_variable b) |
random_variable - random_variable (gate_arith MINUS). | |
| random_variable | provsql.random_variable_times (random_variable a, random_variable b) |
random_variable * random_variable (gate_arith TIMES). | |
| random_variable | provsql.random_variable_div (random_variable a, random_variable b) |
random_variable / random_variable (gate_arith DIV). | |
| random_variable | provsql.random_variable_neg (random_variable a) |
Unary -random_variable (gate_arith NEG). | |
| random_variable | provsql.random_variable_pow (random_variable a, random_variable b) |
random_variable ^ random_variable (gate_arith POW). | |
| random_variable | provsql.ln (random_variable a) |
Natural logarithm of a random_variable (gate_arith LN). | |
| random_variable | provsql.exp (random_variable a) |
e^x for a random_variable (gate_arith EXP). | |
| random_variable | provsql.pow (random_variable a, random_variable b) |
pow / power spellings of the ^ operator, mirroring PostgreSQL's NUMERIC surface. | |
| random_variable | provsql.power (random_variable a, random_variable b) |
| random_variable | provsql.sqrt (random_variable a) |
Square root of a random_variable: sugar for x ^ 0.5 (no gate or opcode of its own). | |
| oid | provsql.random_variable_cmp_oid (TEXT sym) |
| Internal helper: float8-comparator OID for a given symbol. | |
| BOOLEAN | provsql.random_variable_cmp_placeholder (random_variable a, random_variable b) |
| Placeholder body shared by every random_variable_* comparison procedure. | |
| BOOLEAN | provsql.random_variable_lt (random_variable a, random_variable b) |
| BOOLEAN | provsql.random_variable_le (random_variable a, random_variable b) |
| BOOLEAN | provsql.random_variable_eq (random_variable a, random_variable b) |
| BOOLEAN | provsql.random_variable_ne (random_variable a, random_variable b) |
| BOOLEAN | provsql.random_variable_ge (random_variable a, random_variable b) |
| BOOLEAN | provsql.random_variable_gt (random_variable a, random_variable b) |
| UUID | provsql.rv_cmp_lt (random_variable a, random_variable b) |
Build a gate_cmp for a < b and return its UUID. | |
| UUID | provsql.rv_cmp_le (random_variable a, random_variable b) |
Build a gate_cmp for a ≤ b and return its UUID. | |
| UUID | provsql.rv_cmp_eq (random_variable a, random_variable b) |
Build a gate_cmp for a = b and return its UUID. | |
| UUID | provsql.rv_cmp_ne (random_variable a, random_variable b) |
Build a gate_cmp for a <> b and return its UUID. | |
| UUID | provsql.rv_cmp_ge (random_variable a, random_variable b) |
Build a gate_cmp for a ≥ b and return its UUID. | |
| UUID | provsql.rv_cmp_gt (random_variable a, random_variable b) |
Build a gate_cmp for a > b and return its UUID. | |
| BOOLEAN | provsql.random_variable_op_random_variable (random_variable left, random_variable right) |
Prefix unary minus on random_variable. | |
| BOOLEAN | provsql.random_variable_lt_random_variable (random_variable left, random_variable right) |
| BOOLEAN | provsql.random_variable_le_random_variable (random_variable left, random_variable right) |
| BOOLEAN | provsql.random_variable_eq_random_variable (random_variable left, random_variable right) |
| BOOLEAN | provsql.random_variable_ne_random_variable (random_variable left, random_variable right) |
| BOOLEAN | provsql.random_variable_ge_random_variable (random_variable left, random_variable right) |
| BOOLEAN | provsql.random_variable_gt_random_variable (random_variable left, random_variable right) |
| INTEGER | provsql.random_variable_btree_cmp (random_variable a, random_variable b) |
btree comparison support for random_variable – always an error. | |
| random_variable | provsql.random_variable_cond (random_variable rv, UUID cond) |
Condition a random variable on an event: "X | C". | |
| BOOLEAN | provsql.random_variable_op_uuid (random_variable left, UUID right) |
| random_variable | provsql.random_variable_cond_predicate (random_variable rv, BOOLEAN predicate) |
Placeholder for "X | (predicate)" – conditioning a random variable on a Boolean comparison written naturally. | |
| BOOLEAN | provsql.random_variable_op_boolean (random_variable left, BOOLEAN right) |
| UUID | provsql.rv_conditioned_target (UUID token) |
| Unpack the target of a random-variable conditioning gate. | |
| UUID | provsql.rv_conditioned_prov (UUID token, UUID prov) |
Combine a conditioning gate's event with an explicit prov. | |
| UUID | provsql.evidence_as_observation (UUID ev) |
| Internal: rewrite a point-equality conditioning event into an observation. | |
| UUID | provsql.observe (random_variable x, DOUBLE PRECISION datum) |
Internal: bind an observed datum to a random-variable leaf – the likelihood-weighting evidence behind "X | (Y = d)". | |
| UUID | provsql.and_agg_sfunc (UUID state, UUID ev) |
Conjunction state function for and_agg (evidence gate_times). | |
| VOID | provsql.and_agg (UUID) |
| Conjoin per-row evidence tokens into one evidence circuit. | |
| DOUBLE PRECISION | provsql.evidence (UUID evidence) |
Marginal likelihood P(data) of an evidence circuit. | |
| UUID[] | provsql.observe_atoms (UUID evidence) |
The observe atoms of an evidence circuit. | |
| TABLE | provsql.shapley_observe (UUID target, UUID evidence, TEXT payoff='expected') |
| Shapley attribution of each observation to a posterior moment. | |
Order statistics over random_variable | |
Same-row They lower to a single PostgreSQL's built-in | |
| CREATE OR REPLACE FUNCTION | provsql.greatest (VARIADIC args random_variable[]) RETURNS random_variable AS CREATE OR REPLACE FUNCTION "least"(VARIADIC args random_variable[]) RETURNS random_variable AS random_variable rv_case(UUID[] children) |
| "greatest" / "least" are col_name keywords, so the CREATE FUNCTION name must be quoted; callers reach them qualified as provsql.greatest(...). | |
| AGG_TOKEN | provsql.agg_case (UUID[] children) |
Build an AGG_TOKEN from a guarded-selection gate_case. | |
Aggregates over random_variable | |
An overload of the standard Lives in the Direct calls outside a provenance-tracked query treat each row's contribution unconditionally (no per-row Boolean selector). When the planner hook sees a The internal state is the array of UUIDs of the per-row mixtures. The final function builds a single | |
| random_variable | provsql.rv_aggregate_semimod (UUID prov, random_variable rv) |
Per-row helper: wrap an RV in mixture(prov, rv, as_random(0)). | |
| random_variable | provsql.rv_aggregate_semimod (UUID prov, random_variable rv, DOUBLE PRECISION identity) |
| Identity-parameterised per-row wrap for an RV-returning aggregate. | |
| random_variable | provsql.rv_aggregate_indicator (UUID prov) |
Per-row denominator wrap for avg(random_variable): the provenance indicator \(\mathbf{1}\{\varphi\}\). | |
| random_variable | provsql.rv_aggregate_indicator (UUID prov, random_variable rv) |
| Value-aware presence indicator: NULL when the row's aggregated value is NULL. | |
| UUID[] | provsql.sum_rv_sfunc (UUID[] state, random_variable rv) |
State-transition function for sum(random_variable). | |
| random_variable | provsql.sum_rv_ffunc (UUID[] state) |
Final function for sum(random_variable): build a gate_arith PLUS root. | |
| VOID | provsql.sum (random_variable) |
| random_variable | provsql.rv_sum_or_null_ffunc (UUID[] state) |
Numerator final function for the avg rewrite: sum, but NULL on an empty group. | |
| VOID | provsql.rv_sum_or_null (random_variable) |
| random_variable | provsql.avg_rv_ffunc (UUID[] state) |
Final function for avg(random_variable). | |
| VOID | provsql.avg (random_variable) |
| random_variable | provsql.product_rv_ffunc (UUID[] state) |
Final function for product(random_variable): fold a gate_arith TIMES root over the per-row contributions. | |
| VOID | provsql.product (random_variable) |
| random_variable | provsql.extremum_rv_ffunc (UUID[] state, INTEGER op, DOUBLE PRECISION identity) |
Final function for max(random_variable) / min(random_variable): fold a gate_arith MAX / MIN root over the per-row contributions. | |
| random_variable | provsql.max_rv_ffunc (UUID[] state) |
| random_variable | provsql.min_rv_ffunc (UUID[] state) |
| VOID | provsql.max (random_variable) |
| VOID | provsql.min (random_variable) |
| UUID[] | provsql.rv_stat1_sfunc (UUID[] state, random_variable x) |
| SQL-standard statistic aggregates over random_variable rows: covar_pop / covar_samp / corr (two-argument), stddev_pop / stddev_samp (one-argument), and the ordered-set percentile_cont. | |
| UUID[] | provsql.rv_stat2_sfunc (UUID[] state, random_variable x, random_variable y) |
State transition for the two-argument RV statistic aggregates (covar_pop / covar_samp / corr): append the certain indicator and the row's RV pair as a triple. | |
| UUID[] | provsql.rv_stat1_impl_sfunc (UUID[] state, random_variable ind, random_variable x) |
Indicator-carrying state transition for the one-argument rv_*_impl statistic aggregates: the planner-hook rewrite passes the row's provenance indicator rv_aggregate_indicator(prov) as ind. | |
| UUID[] | provsql.rv_stat2_impl_sfunc (UUID[] state, random_variable ind, random_variable x, random_variable y) |
Indicator-carrying state transition for the two-argument rv_*_impl statistic aggregates. | |
| VOID | provsql.rv_stat_sum_tokens (UUID[] state, INTEGER stride, OUT UUID n_tok, OUT UUID sx_tok, OUT UUID sxx_tok, OUT UUID sy_tok, OUT UUID sxy_tok, OUT UUID syy_tok) |
| Mint the indicator-weighted power-sum gates shared by the covariance / stddev final functions. | |
| UUID | provsql.rv_stat_var_pop_token (UUID n_tok, UUID s_tok, UUID ss_tok) |
| Population-variance gate \(SXX/N - (SX/N)^2\) from the power-sum tokens. | |
| UUID | provsql.rv_stat_var_samp_token (UUID n_tok, UUID s_tok, UUID ss_tok) |
| Sample-variance gate \((SXX - SX^2/N) / (N - 1)\) from the power-sum tokens (NaN in a world with \(N \le 1\), the undefined-world convention). | |
| UUID | provsql.rv_stat_sqrt_token (UUID v_tok) |
| \(\sqrt{\max(v, 0)}\) gate over a variance token: the max-clamp removes the tiny negative values float error can produce (variance is mathematically non-negative), so the POW domain guard never fires. | |
| UUID | provsql.rv_stat_covar_pop_token (UUID n_tok, UUID sx_tok, UUID sy_tok, UUID sxy_tok) |
| Population-covariance gate \(SXY/N - (SX/N)(SY/N)\) from the power-sum tokens. | |
| random_variable | provsql.covar_pop_rv_ffunc (UUID[] state) |
Final function for covar_pop(random_variable, random_variable). | |
| random_variable | provsql.covar_samp_rv_ffunc (UUID[] state) |
Final function for covar_samp(random_variable, random_variable): \((SXY - SX\,SY/N) / (N-1)\). | |
| random_variable | provsql.corr_rv_ffunc (UUID[] state) |
Final function for corr(random_variable, random_variable): \(\mathrm{covar\_pop} / \sqrt{\max(v_x v_y, 0)}\) (a zero-variance world divides to \(\pm\infty\) / NaN, the undefined-world convention, matching SQL's NULL for a zero-stddev input). | |
| random_variable | provsql.stddev_pop_rv_ffunc (UUID[] state) |
Final function for stddev_pop(random_variable). | |
| random_variable | provsql.stddev_samp_rv_ffunc (UUID[] state) |
Final function for stddev_samp(random_variable). | |
| VOID | provsql.covar_pop (random_variable, random_variable) |
| VOID | provsql.covar_samp (random_variable, random_variable) |
| VOID | provsql.corr (random_variable, random_variable) |
| VOID | provsql.stddev_pop (random_variable) |
| VOID | provsql.stddev_samp (random_variable) |
| VOID | provsql.rv_covar_pop_impl (random_variable, random_variable, random_variable) |
| The indicator-carrying rewrite targets (planner hook only; never called directly by users). | |
| VOID | provsql.rv_covar_samp_impl (random_variable, random_variable, random_variable) |
| VOID | provsql.rv_corr_impl (random_variable, random_variable, random_variable) |
| VOID | provsql.rv_stddev_pop_impl (random_variable, random_variable) |
| VOID | provsql.rv_stddev_samp_impl (random_variable, random_variable) |
| random_variable | provsql.rv_percentile_make (DOUBLE PRECISION fraction, UUID[] pairs) |
Mint the PROVSQL_ARITH_PERCENTILE gate: the continuous percentile (SQL percentile_cont) over a group of RV rows. | |
| UUID[] | provsql.percentile_cont_rv_sfunc (UUID[] state, random_variable x) |
State transition for the public ordered-set percentile_cont(float8) WITHIN GROUP (ORDER BY random_variable): append the certain indicator and the row's RV. | |
| random_variable | provsql.percentile_cont_rv_ffunc (UUID[] state, DOUBLE PRECISION fraction) |
Final function for the public ordered-set percentile_cont: receives the direct fraction argument after the state. | |
| VOID | provsql.percentile_cont (DOUBLE PRECISION ORDER BY random_variable) |
| rv_percentile_state | provsql.rv_percentile_impl_sfunc (rv_percentile_state state, DOUBLE PRECISION fraction, random_variable ind, random_variable x) |
State transition for rv_percentile_impl, the planner-hook rewrite target of a provenance-tracked percentile_cont: stashes the (group-constant) fraction and appends the indicator/value pair. | |
| random_variable | provsql.rv_percentile_impl_ffunc (rv_percentile_state state) |
Final function for rv_percentile_impl. | |
| VOID | provsql.rv_percentile_impl (DOUBLE PRECISION, random_variable, random_variable) |
Custom type random_variable: a thin wrapper around a provenance gate UUID, used to expose continuous probabilistic c-tables in SQL.
The UUID indexes either a gate_rv (an actual distribution) or a gate_value (a zero-variance constant produced by provsql.as_random). Binary-coercible with UUID (same 16-byte layout), so an rv-typed expression flows directly into any function expecting a UUID at zero runtime cost.
Constructors live in this group: provsql.normal(μ, σ), provsql.uniform(a, b), provsql.exponential(λ), provsql.erlang(k, λ), provsql.gamma(k, λ), provsql.chi_squared(k), provsql.lognormal(μ, σ), provsql.weibull(k, λ), provsql.pareto(xₘ, α), provsql.beta(α, β), the discrete count constructors (provsql.poisson(λ), provsql.binomial(n, p), provsql.geometric(p), provsql.hypergeometric(N, K, n), provsql.negative_binomial(r, p), all lowering to categorical via categorical_from_log_pmf), and provsql.as_random(c). Operator overloads (+ - * / and the six comparators) are defined further below, alongside direct rv_cmp_* UUID constructors for callers that want a gate_cmp token without going through the planner hook.
| AGG_TOKEN provsql.agg_case | ( | UUID[] | children | ) |
Build an AGG_TOKEN from a guarded-selection gate_case.
The aggregate-carrier analogue of rv_case: a thin AGG_TOKEN wrapper over the carrier-agnostic provenance_case, the target of the planner-hook lowering of a searched CASE whose guards are aggregate comparisons and whose branches are aggregates. The branches (and default) are already flattened into [guard_1, value_1, ..., default] UUIDs. The display cell carries the actual-world CASE value – the branch selected on the actual data, resolved by agg_gate_value, exactly as a bare aggregate's cell carries its actual-world value. The probabilistic result is produced by the measure evaluators (expected / probability / possible-worlds / Monte Carlo) from the gate, not the token's cell.
| random_variable provsql.agg_token_to_random_variable | ( | AGG_TOKEN | a | ) |
Coerce an AGG_TOKEN to a random_variable (its circuit token).
An aggregate over probabilistic tuples IS a random variable: its AGG_TOKEN carries the provenance circuit of the aggregate distribution. Exposing that as a random_variable lets a comparison / conditioning predicate mix the two – e.g. conditioning a latent leaf on a count, "R | (poisson(lambda) = C)" with C a count(*) AGG_TOKEN – resolve to the ordinary random_variable comparison operators (which the planner hook rewrites into a gate_cmp). IMPLICIT so the mixed comparison type-checks without an explicit cast; the polymorphic dispatchers keep their exact AGG_TOKEN overloads (an exact match beats the cast).
| VOID provsql.and_agg | ( | UUID | ) |
Conjoin per-row evidence tokens into one evidence circuit.
The evidence-conjunction counterpart used to fold one observe (or any Boolean conditioning event) per row into a single gate_times root, to be passed as the prov argument of the moment / quantile / sample readouts. An empty group yields NULL (no evidence).
| UUID provsql.and_agg_sfunc | ( | UUID | state, |
| UUID | ev ) |
Conjunction state function for and_agg (evidence gate_times).
Not STRICT: provenance_times maps a NULL operand to the times neutral, so an empty group leaves the state NULL (no evidence) and a first row seeds it with that row's evidence.
| random_variable provsql.as_random | ( | DOUBLE PRECISION | c | ) |
Lift a deterministic constant into a random_variable.
Creates a gate_value carrying the constant's TEXT form so that comparisons against a random_variable column produce the same circuit shape regardless of whether the operand is an actual RV or a literal constant.
Marked IMMUTABLE: the gate UUID is derived deterministically from the constant via the same v5 convention as provenance_semimod's inline value gate (concat('value', CAST(c AS VARCHAR))), so as_random(2) always resolves to the same gate, and any other code path that already creates a value gate for the same constant (e.g. provenance_semimod) shares the UUID. create_gate is idempotent on already-mapped tokens, so repeat invocations are harmless.
| random_variable provsql.as_random | ( | INTEGER | c | ) |
as_random for INTEGER (delegates to the float8 form).
| random_variable provsql.as_random | ( | NUMERIC | c | ) |
as_random for NUMERIC (delegates to the float8 form).
| VOID provsql.avg | ( | random_variable | ) |
| random_variable provsql.avg_rv_ffunc | ( | UUID[] | state | ) |
Final function for avg(random_variable).
avg lifts the "@c AVG @c = @c SUM @c / @c COUNT" identity into the random_variable algebra:
\[ \mathrm{AVG}(x) \;=\; \frac{\sum_i \mathbf{1}\{\varphi_i\} \cdot X_i} {\sum_i \mathbf{1}\{\varphi_i\}}. \]
In a provenance-tracked query the planner-hook rewrites avg(x) into rv_sum_or_null(rv_aggregate_semimod(prov, x)) / sum(rv_aggregate_indicator(prov)) (see make_rv_aggregate_expression), so both the numerator and the provenance-weighted count denominator are built by sum's fold and no gate is inspected. This FFUNC is therefore reached only on an untracked call, where every row is unconditionally present: the numerator is sum over the raw per-row RVs and the denominator is the plain row count n (each row contributing as_random(1)).
Empty group: returns NULL, matching standard SQL AVG (and unlike sum, whose empty group is the additive identity as_random(0)): the caller cannot otherwise disambiguate "0 rows" from "rows summing
to 0".
| random_variable provsql.beta | ( | DOUBLE PRECISION | alpha, |
| DOUBLE PRECISION | beta ) |
Construct a Beta(α, β) random variable on the unit interval.
The conjugate prior of Bernoulli / binomial success probabilities: closed-form moments, CDF through the regularised incomplete beta, quantiles through the generic CDF bisection over the finite [0, 1] support, and closed-form truncated moments (interval conditioning). Beta(1, 1) IS Uniform(0, 1) and is silently routed through uniform to share its richer closed forms.
Validation: both shapes must be finite and strictly positive.
| random_variable provsql.beta | ( | DOUBLE PRECISION | alpha, |
| random_variable | beta ) |
| random_variable provsql.beta | ( | random_variable | alpha, |
| DOUBLE PRECISION | beta ) |
beta(alpha, beta)
| random_variable provsql.beta | ( | random_variable | alpha, |
| random_variable | beta ) |
| random_variable provsql.binomial | ( | INTEGER | n, |
| DOUBLE PRECISION | p ) |
Construct a Binomial(n, p) random variable (number of successes in n independent trials), as a categorical.
Enumerated over {0..n} by the log-space recurrence ln p(k+1) = ln p(k) + ln((n-k)/(k+1)) + ln(p/(1-p)) (outcomes below 1e-15 relative mass are dropped). p = 0 / p = 1 are Diracs at 0 / n; n is capped at 10000.
| random_variable provsql.binomial | ( | INTEGER | n, |
| random_variable | p ) |
Binomial with a fixed trial count and a LATENT success probability: binomial(INTEGER, random_variable).
n is a literal trial count; p is a latent (token-valued) success probability (e.g. "40.0 / N" for a latent population size N). Builds a parametric gate_rv leaf (family "binomial", extra "binomial:n,$0") the Monte Carlo sampler resolves per draw; observe weights by the Binomial pmf. Unblocks capture-recapture-style posteriors such as "N | (binomial(50, 40.0/N) = recaptured_count)".
| CREATE provsql.CAST | ( | DOUBLE PRECISION AS | random_variable | ) |
Implicit cast DOUBLE PRECISION -> random_variable (lifts a scalar literal to a constant RV).
Lets users write WHERE reading > 2.5::float8 instead of WHERE reading > provsql.as_random(2.5); the planner-hook rewriter then sees a uniform random_variable on both sides. Sibling casts below cover INTEGER and NUMERIC literals so plain WHERE reading > 2 and WHERE reading > 2.5 also work; PostgreSQL's operator resolution does not chain casts across more than one step, so each NUMERIC-source type needs its own direct cast.
| CREATE provsql.CAST | ( | random_variable AS | UUID | ) |
Binary-coercible cast random_variable -> UUID.
A random_variable is byte-for-byte a pg_uuid_t (alignment char, length 16), so WITHOUT FUNCTION lets PostgreSQL reinterpret the bytes at zero runtime cost. The cast is ASSIGNMENT (not IMPLICIT): an implicit cross-domain cast would silently reroute a comparison such as v < w to UUID < UUID (raw byte comparison) whenever provsql is not in search_path, since operators are resolved through search_path but casts are not. Demoting to ASSIGNMENT turns that silent wrong result into a clean parse error. Passing a random_variable to a UUID-taking function now needs an explicit v::UUID (function resolution never applies assignment casts).
| CREATE provsql.CAST | ( | UUID AS | random_variable | ) |
| random_variable provsql.CAST(AGG_TOKEN AS RANDOM_VARIABLE) | ( | AGG_TOKEN | ) |
| random_variable provsql.CAST(INTEGER AS RANDOM_VARIABLE) | ( | INTEGER | ) |
Implicit cast INTEGER -> random_variable.
| random_variable provsql.CAST(NUMERIC AS RANDOM_VARIABLE) | ( | NUMERIC | ) |
Implicit cast NUMERIC -> random_variable.
| random_variable provsql.categorical | ( | DOUBLE_PRECISION[] | probs, |
| DOUBLE_PRECISION[] | outcomes ) |
Categorical-RV constructor over explicit (probabilities, values) arrays.
Builds a categorical-form gate_mixture directly: a fresh gate_input "key" anchor and one gate_mulinput per outcome with positive mass, all sharing the key. The wires [key, mul_1, ..., mul_n] are what downstream evaluators (Expectation, MonteCarloSampler, AnalyticEvaluator, RangeCheck) recognise via isCategoricalMixture and treat as a scalar RV with the categorical distribution probs over outcomes.
Validation:
probs and outcomes must be non-null, same length, length ≥ 1.probs[i] must be finite, in [0, 1], and the array must sum to 1 within 1e-9.outcomes[i] must be finite.Each call mints a fresh key gate and a fresh set of mulinputs, so two calls to categorical with the same arrays are independent categorical RVs. The marking is VOLATILE accordingly.
Degenerate case: a categorical with exactly one positive-mass outcome reduces to as_random(v) at construction (the block would just be a single mulinput, which is operationally a Dirac point mass). Two such calls share the gate_value UUID via the v5 convention as_random already uses.
mixture for the Bernoulli-weighted choice constructor. | random_variable provsql.categorical_from_log_pmf | ( | DOUBLE_PRECISION[] | outcomes, |
| DOUBLE_PRECISION[] | log_pmf ) |
Build a discrete (categorical) random variable from outcomes and UNNORMALISED log-masses.
The shared back end of the discrete count constructors (poisson, binomial, geometric, hypergeometric, negative_binomial), and directly usable for any custom discrete pmf: the log-masses are shifted by their maximum (so only relative magnitudes matter and no exp underflows), outcomes whose relative mass is below 1e-15 are dropped, and the rest is renormalised before being handed to categorical. Working in log space keeps arbitrarily large parameters stable (e.g. a Poisson(1000) pmf whose linear-space recurrence would underflow at exp(-1000)).
| outcomes | outcome values, same length as log_pmf |
| log_pmf | natural logs of the (unnormalised) masses |
| random_variable provsql.chi_squared | ( | DOUBLE PRECISION | k | ) |
Construct a chi-squared random variable with k degrees of freedom: syntactic sugar for gamma(k/2, 1/2).
k is accepted as double precision so fractional degrees of freedom work; it must be finite and strictly positive. Even degrees of freedom route through erlang via gamma's INTEGER-shape rule.
| VOID provsql.corr | ( | random_variable | , |
| random_variable | ) |
| random_variable provsql.corr_rv_ffunc | ( | UUID[] | state | ) |
Final function for corr(random_variable, random_variable): \(\mathrm{covar\_pop} / \sqrt{\max(v_x v_y, 0)}\) (a zero-variance world divides to \(\pm\infty\) / NaN, the undefined-world convention, matching SQL's NULL for a zero-stddev input).
| VOID provsql.covar_pop | ( | random_variable | , |
| random_variable | ) |
| random_variable provsql.covar_pop_rv_ffunc | ( | UUID[] | state | ) |
Final function for covar_pop(random_variable, random_variable).
| VOID provsql.covar_samp | ( | random_variable | , |
| random_variable | ) |
| random_variable provsql.covar_samp_rv_ffunc | ( | UUID[] | state | ) |
Final function for covar_samp(random_variable, random_variable): \((SXY - SX\,SY/N) / (N-1)\).
| random_variable provsql.empirical_cdf | ( | DOUBLE_PRECISION[] | grid, |
| DOUBLE_PRECISION[] | cdf ) |
Empirical-CDF constructor: a piecewise-linear CDF table as a random_variable.
Loads a tabulated CDF – simulation output percentile tables, risk models, expert-elicited forecasts – as the distribution whose CDF is cdf[i] at grid[i], linear in between: mass cdf[i+1] - cdf[i] spread uniformly over (grid[i], grid[i+1]), plus (when cdf[1] > 0) an atom of mass cdf[1] at grid[1] for the probability at or below the grid start. Packaged, like gmm, as a stick-breaking cascade of Bernoulli mixture nodes over uniform components (and the optional as_random atom), so moments and sampling are exact through the existing mixture machinery; comparisons ride Monte Carlo.
Validation: same-length arrays of at least two entries, grid strictly increasing and finite, cdf non-decreasing within [0, 1] and ending at 1 within 1e-9.
| random_variable provsql.empirical_samples | ( | DOUBLE_PRECISION[] | samples | ) |
Empirical-samples constructor: the ecdf of a sample bundle as a random_variable.
Loads a Monte Carlo / MCMC / bootstrap sample array as the discrete distribution putting mass 1/n on each draw (duplicates merge, so a value drawn k times carries k/n) – the standard empirical distribution. Reduces entirely to categorical, so the whole exact discrete surface applies: moments are the sample moments, comparisons against constants are decided analytically ("fraction of
samples below c"), and quantiles are the exact empirical quantiles.
At most 10000 distinct values (the categorical block cap): thin the chain or bin the samples (e.g. with width_bucket) beyond that.
| random_variable provsql.erlang | ( | INTEGER | k, |
| DOUBLE PRECISION | lambda ) |
Construct an Erlang-distribution random variable, sum of k i.i.d.
exponentials with shared rate lambda
The Erlang distribution is the sum of k independent Exp(λ) random variables (equivalently the gamma with INTEGER shape). It is the natural closure of i.i.d. exponentials under addition, and is materialised here as a single gate_rv so the analytic CDF and closed-form moments fire directly (rather than the sampler having to draw and sum k exponential leaves per Monte-Carlo iteration).
Validation:
k must be ≥ 1. The degenerate k=1 case is silently routed through exponential so erlang(1, λ) shares its gate with exponential(λ).lambda must be finite and strictly positive.| DOUBLE PRECISION provsql.evidence | ( | UUID | evidence | ) |
Marginal likelihood P(data) of an evidence circuit.
The mean raw importance weight over provsql.rv_mc_samples prior draws – the same quantity rejection conditioning computes as P(C), now the product of the observations' densities. evidence is an and_agg conjunction of observe tokens (and/or Boolean events).
| UUID provsql.evidence_as_observation | ( | UUID | ev | ) |
Internal: rewrite a point-equality conditioning event into an observation.
If ev is a gate_cmp with the "=" operator, one side a bare gate_rv leaf and the other a constant, return observe(leaf, const); otherwise return ev unchanged.
This is the bridge that makes the natural equality form the surface for likelihood-weighting conditioning: "X | (Y = c)" and "given(Y = c)" both produce a gate_cmp, which this turns into density evidence. A point event on a bare leaf is only meaningful as an observation (a continuous "Y = c" is measure-zero as a Boolean selection), so the rewrite is unambiguous. Non-equality / non-leaf events pass through as ordinary Boolean conditioning.
| random_variable provsql.exp | ( | random_variable | a | ) |
| random_variable provsql.exponential | ( | DOUBLE PRECISION | lambda | ) |
Construct an exponential-distribution random variable with rate λ
Validation:
lambda must be finite and strictly positive. No degenerate form exists for the exponential distribution, so there is no silent route through as_random.| random_variable provsql.exponential | ( | random_variable | lambda | ) |
exponential(lambda)
| random_variable provsql.extremum_rv_ffunc | ( | UUID[] | state, |
| INTEGER | op, | ||
| DOUBLE PRECISION | identity ) |
Final function for max(random_variable) / min(random_variable): fold a gate_arith MAX / MIN root over the per-row contributions.
The order-statistic analogues of sum / product:
\[ \mathrm{MAX}(x) = \max_{i : \varphi_i} X_i, \qquad \mathrm{MIN}(x) = \min_{i : \varphi_i} X_i. \]
A row absent in a world (its provenance \(\varphi_i\) false) must not perturb the extremum, so it contributes the order-statistic identity \(\mp\infty\). That identity is baked into each per-row contribution upstream: a provenance-tracked query wraps the argument as mixture(prov_i, X_i, as_random(∓∞)) (via the three-argument rv_aggregate_semimod), and an untracked call passes the raw RV through. So the FFUNC is a plain fold with no gate inspection: gate_arith(op, state).
Empty group: the identity as_random(identity) ( \(-\infty\) / \(+\infty\)), the extremum counterpart to sum's as_random(0). Singleton group: the single child directly.
| random_variable provsql.gamma | ( | DOUBLE PRECISION | k, |
| DOUBLE PRECISION | lambda ) |
Construct a gamma-distribution random variable with shape k (any positive real) and rate lambda.
The gamma distribution generalises Erlang to non-INTEGER shape; its CDF is the regularised lower incomplete gamma, evaluated in closed form by the analytic passes. Sums of independent gammas with the same rate fold to a single gamma in the simplifier.
Validation:
k must be finite and strictly positive. An INTEGER k (in INTEGER range) is silently routed through erlang – the gamma with INTEGER shape is Erlang – so gamma(2, λ) shares its gate encoding and closure interplay with erlang(2, λ).lambda must be finite and strictly positive.| random_variable provsql.gamma | ( | DOUBLE PRECISION | k, |
| random_variable | lambda ) |
| random_variable provsql.gamma | ( | random_variable | k, |
| DOUBLE PRECISION | lambda ) |
gamma(k, lambda)
| random_variable provsql.gamma | ( | random_variable | k, |
| random_variable | lambda ) |
| random_variable provsql.geometric | ( | DOUBLE PRECISION | p | ) |
Construct a Geometric(p) random variable – the number of TRIALS up to and including the first success (support starting at 1; subtract 1 for the failures convention).
P(X = k) = (1-p)^{k-1} p, enumerated up to the 1e-15 relative-mass tail and renormalised. p = 1 is a Dirac at 1.
| random_variable provsql.geometric | ( | random_variable | p | ) |
Geometric with a LATENT success probability: geometric(random_variable).
A latent (token-valued) p cannot be enumerated at construction, so this builds a parametric gate_rv leaf (family "geometric") wiring the probability, resolved per draw by the sampler. observe weights by the geometric pmf; unblocks a Beta-Geometric conjugate posterior.
| random_variable provsql.gmm | ( | DOUBLE_PRECISION[] | weights, |
| DOUBLE_PRECISION[] | means, | ||
| DOUBLE_PRECISION[] | stddevs ) |
Gaussian-mixture-model (GMM) constructor.
Packages the common fitted-density pattern – a categorical choice among Normal components – into one call:
No new gate: the mixture decomposes into a stick-breaking cascade of Bernoulli gate_mixture nodes over gate_rv Normal leaves (component i is selected with conditional probability w_i / (w_i + ... + w_n), so the joint selection probabilities are exactly weights), which every evaluator already handles: moments are closed-form through the mixture recursion, sampling is exact, and comparisons ride the existing mixture machinery. Zero-weight components are skipped; a single positive-weight component returns its Normal directly (no mixture node).
Validation mirrors categorical: same-length non-empty arrays, weights finite in [0, 1] summing to 1 within 1e-9; the component parameters are validated by provsql.normal (finite mu, non-negative sigma; sigma = 0 degenerates to a Dirac component).
mixture, categorical, normal | CREATE OR REPLACE FUNCTION provsql.greatest | ( | VARIADIC args | random_variable[] | ) |
"greatest" / "least" are col_name keywords, so the CREATE FUNCTION name must be quoted; callers reach them qualified as provsql.greatest(...).
Idempotence: max / min ignore repeats, so identical children (same gate) are de-duplicated ///< greatest(x, x, y) == greatest(x, y) ///< and a single surviving child collapses to itself ///< greatest(x) == x. DISTINCT also sorts the children, so the argument order does not matter for gate sharing. (Two independent draws of the same distribution are distinct gates and are NOT de-duplicated.)
Build a random_variable from a guarded-selection gate_case.
Thin random_variable wrapper over provenance_case (defined with the other gate builders, since it is UUID-only), the target of the planner-hook CASE-over-RV rewrite: the hook flattens the branches into [guard_1, value_1, ..., default] and emits this call so an RV-typed CASE surfaces as a first-class random_variable.
| random_variable provsql.hypergeometric | ( | INTEGER | pop_n, |
| INTEGER | k_marked, | ||
| INTEGER | n ) |
Construct a Hypergeometric(N, K, n) random variable: the number of marked items among n draws WITHOUT replacement from a population of pop_n items of which k_marked are marked.
The exact finite support [max(0, n-(N-K)), min(n, K)] is enumerated by the pmf ratio recurrence (in log space, so large populations cannot overflow) and normalised – exact "sampling without replacement" probabilities with no combinatorial functions needed.
| random_variable provsql.inverse_gamma | ( | DOUBLE PRECISION | alpha, |
| DOUBLE PRECISION | beta ) |
Construct an inverse-gamma random variable with shape alpha and scale beta.
The distribution of 1/Y for Y ~ gamma(alpha, beta) (the conjugate prior for a Gaussian variance). Its CDF is the regularised upper incomplete gamma, evaluated in closed form by the analytic passes; raw moments are infinite for alpha <= k and reported as Infinity (the mean for alpha <= 1, the variance for alpha <= 2) rather than estimated. Positive scalings rescale beta in the simplifier.
Validation: both parameters must be finite and strictly positive.
| random_variable provsql.inverse_gamma | ( | DOUBLE PRECISION | alpha, |
| random_variable | beta ) |
| random_variable provsql.inverse_gamma | ( | random_variable | alpha, |
| DOUBLE PRECISION | beta ) |
inverse_gamma(alpha, beta)
| random_variable provsql.inverse_gamma | ( | random_variable | alpha, |
| random_variable | beta ) |
| random_variable provsql.inverse_gaussian | ( | DOUBLE PRECISION | mu, |
| DOUBLE PRECISION | lambda ) |
Construct an inverse-Gaussian (Wald) random variable with mean mu and shape lambda.
The first-passage time of Brownian motion with drift: a positive, right-skewed family. Its CDF has a closed form in the standard normal Phi, so comparisons and quantiles are analytic; all raw moments are finite. Positive scalings map c·IG(mu, lambda) to IG(c·mu, c·lambda), and a sum of independent inverse Gaussians sharing the ratio lambda/mu² folds to a single inverse Gaussian in the simplifier. wald is an alias.
Validation: both parameters must be finite and strictly positive.
| random_variable provsql.inverse_gaussian | ( | DOUBLE PRECISION | mu, |
| random_variable | lambda ) |
| random_variable provsql.inverse_gaussian | ( | random_variable | mu, |
| DOUBLE PRECISION | lambda ) |
inverse_gaussian(mu, lambda)
| random_variable provsql.inverse_gaussian | ( | random_variable | mu, |
| random_variable | lambda ) |
| BOOL provsql.is_finite_float8 | ( | DOUBLE PRECISION | x | ) |
Internal: true iff x is a finite (non-NaN, non-±∞) float8.
PostgreSQL's isnan is defined for NUMERIC only, not for DOUBLE PRECISION; we use the inequality form, which works because PG defines NaN = NaN as TRUE for floats (so NaN <> 'NaN'::float8 is FALSE).
| random_variable provsql.ln | ( | random_variable | a | ) |
Natural logarithm of a random_variable (gate_arith LN).
Defined on [0, +Infinity): evaluation raises if a negative value is drawn (restrict the argument's support); a draw of exactly 0 yields -Infinity.
| random_variable provsql.logistic | ( | DOUBLE PRECISION | mu, |
| DOUBLE PRECISION | s ) |
Construct a logistic-distribution random variable Logistic(μ, s).
The location-scale family whose CDF is the logistic sigmoid; a threshold event over a Logistic(0, 1) noise realises the logit link exactly (P(eps < score) = 1/(1 + exp(-score))), the natural link for a log-odds / latent-utility selection model.
Validation:
mu and s must be finite.s (the scale) must be non-negative; s = 0 is the Dirac at mu, routed through as_random(mu) as with normal's sigma = 0.| mu | location (the mean and median). |
| s | scale (> 0); the variance is \(\pi^2 s^2 / 3\). |
random_variable token for Logistic(μ, s).| random_variable provsql.logistic | ( | DOUBLE PRECISION | mu, |
| random_variable | s ) |
| random_variable provsql.logistic | ( | random_variable | mu, |
| DOUBLE PRECISION | s ) |
logistic(mu, s)
| random_variable provsql.logistic | ( | random_variable | mu, |
| random_variable | s ) |
| random_variable provsql.lognormal | ( | DOUBLE PRECISION | mu, |
| DOUBLE PRECISION | sigma ) |
Construct a log-normal random variable: exp of a Normal(mu, sigma), parameterised by the underlying normal (so its median is exp(mu) and its mean exp(mu + sigma^2/2)).
The multiplicative counterpart of normal: products of independent lognormals fold to a lognormal in the simplifier, and the exp(normal(...)) / ln(lognormal(...)) bridges fold in both directions, so log-scale models stay closed-form.
Validation mirrors normal: both parameters must be finite, sigma non-negative; the degenerate sigma = 0 case is silently routed through as_random (a Dirac at exp(mu)).
| random_variable provsql.lognormal | ( | DOUBLE PRECISION | mu, |
| random_variable | sigma ) |
| random_variable provsql.lognormal | ( | random_variable | mu, |
| DOUBLE PRECISION | sigma ) |
lognormal(mu, sigma)
| random_variable provsql.lognormal | ( | random_variable | mu, |
| random_variable | sigma ) |
| VOID provsql.max | ( | random_variable | ) |
| random_variable provsql.max_rv_ffunc | ( | UUID[] | state | ) |
| VOID provsql.min | ( | random_variable | ) |
| random_variable provsql.min_rv_ffunc | ( | UUID[] | state | ) |
| random_variable provsql.mixture | ( | DOUBLE PRECISION | p_value, |
| random_variable | x, | ||
| random_variable | y ) |
Ad-hoc mixture constructor that mints a fresh anonymous gate_input Bernoulli with probability p_value.
Sugar over the mixture(UUID, x, y) form: when the caller doesn't care about reusing the Bernoulli token elsewhere in the circuit (which is the common case – "give me a 0.3 / 0.7 weighted GMM,
I don't need to share the coin"), this overload creates the underlying gate_input on the fly with a fresh uuid_generate_v4() token, pins p_value via set_prob, and threads everything into the UUID-keyed constructor.
Each call mints a NEW Bernoulli, so two calls to mixture(0.5, X, Y) are independent mixtures whose branch selections are uncorrelated. When coupling is desired (e.g. two mixtures sharing a coin), use the mixture(UUID, x, y) form with a user-managed gate_input token.
STABLE / IMMUTABLE would collapse two independent draws into one shared gate.| random_variable provsql.mixture | ( | UUID | p, |
| random_variable | x, | ||
| random_variable | y ) |
Construct a probabilistic-mixture random variable.
Returns a random_variable whose distribution is a Bernoulli mixture of two scalar RV roots: with probability P(p = true) the mixture samples x, with the complementary probability it samples y. The mixing token p is a gate_input Bernoulli whose probability has been pinned with set_prob, and the same p can be shared with other branches of the circuit – the Monte-Carlo sampler's per-iteration cache couples every reference to the same draw, so users can build joint conditional structures (e.g. mixture(p, X1, Y1) + mixture(p, X2, Y2) samples X1 + X2 with prob π and Y1 + Y2 with prob 1-π).
x and y may be any scalar RV root: a base gate_rv (normal / uniform / exponential / erlang), a gate_value Dirac (as_random), a gate_arith expression, or another mixture. N-ary mixtures are built by composition – mixture(p1, A, mixture(p2, B, C)) realises a 3-component mixture with effective weights π1, (1-π1)·π2, (1-π1)·(1-π2).
Validation:
p must point to a Boolean gate (input, mulinput, update, plus, times, monus, project, eq, cmp, zero, one). Compound Boolean gates derive their probability from their atoms via the active probability-evaluation method; a bare gate_input's probability is whatever set_prob pinned (set_prob is responsible for keeping it in [0, 1]).x and y must be scalar RV roots; aggregate / Boolean roots are rejected at construction.Two calls to mixture with the same (p, x, y) operands collapse to the same gate_mixture node by v5-hash, exactly like arith(PLUS, X, Y). Draw independence is controlled by p: sharing p couples branch selection across consumers via the sampler's bool_cache_; minting independent Bernoullis (e.g. via the mixture(p_value, …) overload) decouples them.
| random_variable provsql.negative_binomial | ( | DOUBLE PRECISION | r, |
| DOUBLE PRECISION | p ) |
Construct a negative-binomial random variable: the number of FAILURES before the r-th success (support starting at 0), with real r > 0 allowed (the Polya / overdispersed-count parameterisation, the Poisson-Gamma mixture).
P(X = k) = C(k+r-1, k) p^r (1-p)^k, enumerated by the log-space recurrence ln p(k+1) = ln p(k) + ln((k+r)/(k+1)) + ln(1-p) up to the 1e-15 relative-mass tail. p = 1 is a Dirac at 0.
| random_variable provsql.negative_binomial | ( | DOUBLE PRECISION | r, |
| random_variable | p ) |
| random_variable provsql.negative_binomial | ( | random_variable | r, |
| DOUBLE PRECISION | p ) |
| random_variable provsql.negative_binomial | ( | random_variable | r, |
| random_variable | p ) |
| random_variable provsql.normal | ( | DOUBLE PRECISION | mu, |
| DOUBLE PRECISION | sigma ) |
Construct a normal-distribution random variable.
Creates a fresh gate_rv with "normal:μ,σ" stored in the gate's extra field, and returns a random_variable pointing at it.
Validation:
mu and sigma must be finite (no NaN, no ±Infinity).sigma must be non-negative.sigma is zero the distribution degenerates to the Dirac at mu; the call is silently routed through as_random(mu), producing a gate_value rather than a zero-variance gate_rv. This keeps the sampler / moment / boundcheck paths free of σ=0 special cases and lets normal(x, 0) share its gate with as_random(x).uniform and exponential below.| random_variable provsql.normal | ( | DOUBLE PRECISION | mu, |
| random_variable | sigma ) |
| random_variable provsql.normal | ( | random_variable | mu, |
| DOUBLE PRECISION | sigma ) |
normal(mu, sigma)
| random_variable provsql.normal | ( | random_variable | mu, |
| random_variable | sigma ) |
| UUID provsql.observe | ( | random_variable | x, |
| DOUBLE PRECISION | datum ) |
Internal: bind an observed datum to a random-variable leaf – the likelihood-weighting evidence behind "X | (Y = d)".
x MUST be a bare gate_rv leaf (typically a latent-parameterised one, e.g. normal(mu, 1) sharing a latent mu across rows). Returns an evidence UUID – a gate_observe wrapping the leaf with the datum in extra – that composes with other evidence through and_agg (a gate_times conjunction) and is consumed by the importance-sampling weight walk, contributing the factor f_X(d).
Internal: the user-facing surface is the equality form "X | (Y = d)" (single conditioning) and "given(Y = d)" (per-row evidence for and_agg), both of which route here through evidence_as_observation.
A fresh gate is minted per call (each observation is a distinct evidence atom, so a repeated (leaf, datum) contributes its density factor once per row – and each is a separate Shapley atom). Observing a derived quantity (observe(X+Y, d)) is out of scope: it needs a change-of-variables density; a non-leaf argument is refused.
| UUID[] provsql.observe_atoms | ( | UUID | evidence | ) |
The observe atoms of an evidence circuit.
Collects every gate_observe leaf reachable through the gate_times conjunction spine (the shape and_agg builds – a possibly left-nested tree, since provenance_times does not flatten). Used by shapley_observe to recover the flat observation set regardless of the conjunction's nesting.
| random_variable provsql.pareto | ( | DOUBLE PRECISION | xm, |
| DOUBLE PRECISION | alpha ) |
Construct a Pareto random variable with scale (minimum) xm and shape alpha.
The canonical heavy-tailed power law. Raw moments are infinite for alpha <= k and reported as Infinity (the mean for alpha <= 1, the variance for alpha <= 2) rather than estimated; quantiles, truncated moments, conditional sampling (self-similarity: X | X > a is Pareto(a, alpha)), and Pareto-vs-Pareto comparisons are all exact.
Validation: both parameters must be finite and strictly positive.
| random_variable provsql.pareto | ( | DOUBLE PRECISION | xm, |
| random_variable | alpha ) |
| random_variable provsql.pareto | ( | random_variable | xm, |
| DOUBLE PRECISION | alpha ) |
pareto(xm, alpha)
| random_variable provsql.pareto | ( | random_variable | xm, |
| random_variable | alpha ) |
| VOID provsql.percentile_cont | ( | DOUBLE PRECISION ORDER BY | random_variable | ) |
| random_variable provsql.percentile_cont_rv_ffunc | ( | UUID[] | state, |
| DOUBLE PRECISION | fraction ) |
Final function for the public ordered-set percentile_cont: receives the direct fraction argument after the state.
| UUID[] provsql.percentile_cont_rv_sfunc | ( | UUID[] | state, |
| random_variable | x ) |
State transition for the public ordered-set percentile_cont(float8) WITHIN GROUP (ORDER BY random_variable): append the certain indicator and the row's RV.
Only reachable on untracked input (a provenance-tracked query is rewritten to rv_percentile_impl before planning), where the sort over random_variable raises the ordering-is-meaningless diagnostic first – so in practice this runs only for empty input.
| random_variable provsql.poisson | ( | DOUBLE PRECISION | lambda | ) |
Construct a Poisson random variable with mean lambda, as a truncated categorical.
The pmf is enumerated over [max(0, λ-12√λ), λ+12√λ+30] (the omitted tails carry ~1e-30 of mass) by the log-space recurrence ln p(k+1) = ln p(k) + ln λ - ln(k+1) and handed to categorical_from_log_pmf, so moments, quantiles, and (in)equality comparisons are exact over the enumerated support. lambda = 0 is a Dirac at 0 (routed through as_random); supports up to 10000 outcomes (λ up to ~170000), beyond which it raises – approximate huge means by normal(λ, √λ) instead.
| random_variable provsql.poisson | ( | random_variable | lambda | ) |
Poisson with a LATENT rate: poisson(random_variable).
A latent (token-valued) rate cannot be enumerated into a categorical at construction, so this builds a parametric gate_rv leaf (family "poisson") wiring the rate, exactly like the continuous latent constructors. Only the Monte Carlo sampler resolves the rate (per draw, then draws a Poisson); observe weights by the Poisson pmf; the mean is exact (E[Poisson(Λ)] = E[Λ], affine). Unblocks discrete-likelihood posteriors such as "R | (poisson(120*R) = observed_count)".
| random_variable provsql.pow | ( | random_variable | a, |
| random_variable | b ) |
pow / power spellings of the ^ operator, mirroring PostgreSQL's NUMERIC surface.
Scalar exponents resolve through the implicit NUMERIC-to-rv casts: pow(x, 0.5) is x ^ 0.5.
| random_variable provsql.power | ( | random_variable | a, |
| random_variable | b ) |
| VOID provsql.product | ( | random_variable | ) |
| random_variable provsql.product_rv_ffunc | ( | UUID[] | state | ) |
Final function for product(random_variable): fold a gate_arith TIMES root over the per-row contributions.
Multiplicative analogue of sum(random_variable):
\[ \mathrm{PRODUCT}(x) \;=\; \prod_i \big(\mathbf{1}\{\varphi_i\} \cdot X_i + \mathbf{1}\{\neg\varphi_i\} \cdot 1\big) \;=\; \prod_{i : \varphi_i} X_i. \]
Each per-row contribution already carries the multiplicative identity as its absent-row value: a provenance-tracked query wraps the argument as mixture(prov_i, X_i, as_random(1)) (identity baked in by the three-argument rv_aggregate_semimod), and an untracked call passes the raw RV through. So the FFUNC is a plain fold with no gate inspection: gate_arith(TIMES, state).
Reuses sum_rv_sfunc as the state-transition function. Empty group: the multiplicative identity as_random(1) – the counterpart to sum's empty-group as_random(0). Singleton group: the single child directly, without a one-child TIMES root.
| INTEGER provsql.random_variable_btree_cmp | ( | random_variable | a, |
| random_variable | b ) |
btree comparison support for random_variable – always an error.
A random_variable is a distribution, not a scalar, so it has no total order: sorting (ORDER BY), de-duplicating (DISTINCT), grouping, and the built-in GREATEST / LEAST all reduce to this btree comparison proc, which raises a clear diagnostic rather than a placeholder message.
The proc exists only so a DEFAULT btree operator class can be declared for random_variable – which is what lets PostgreSQL's GREATEST / LEAST grammar parse over random variables so the planner hook can lift it into a gate_arith MAX / MIN order statistic. When the hook is active the GREATEST / LEAST node is rewritten before it ever calls this proc.
| oid provsql.random_variable_cmp_oid | ( | TEXT | sym | ) |
Internal helper: float8-comparator OID for a given symbol.
Wraps the '<sym>(DOUBLE PRECISION,DOUBLE PRECISION)'::regoperator lookup so the per-comparator functions read uniformly. Marked IMMUTABLE because the resolved OID is fixed at catalog level (the float8 comparators are core PG and never re-installed).
| BOOLEAN provsql.random_variable_cmp_placeholder | ( | random_variable | a, |
| random_variable | b ) |
Placeholder body shared by every random_variable_* comparison procedure.
Raises with a uniform message.
| random_variable provsql.random_variable_cond | ( | random_variable | rv, |
| UUID | cond ) |
Condition a random variable on an event: "X | C".
Returns a conditioned distribution that flows onward like any other random_variable: it can be stored, re-conditioned, and queried with expected / variance / moment / support, which then report the conditional distribution. cond is a Boolean-event provenance token, typically a comparison over the variable itself ("X | rv_cmp_gt(X,
as_random(3))" – a truncation) or any external event.
Unlike the UUID carrier's terminal cond, the random-variable form is a composable two-child gate_conditioned [target, condition]: the moment / support dispatchers unpack it and route through the existing conditional evaluator (rv_moment over the joint of the target and the condition). Nested conditioning folds: "(X|A)|B = X|(A∧B)".
| random_variable provsql.random_variable_cond_predicate | ( | random_variable | rv, |
| BOOLEAN | predicate ) |
Placeholder for "X | (predicate)" – conditioning a random variable on a Boolean comparison written naturally.
Lets one write "X | (X > 3)" instead of "X | rv_cmp_gt(X, as_random(3))". Never executes: the ProvSQL planner hook rewrites the Boolean operand (a combination of random_variable comparisons) into the corresponding condition gate and emits random_variable_cond. Reaching it at runtime means the rewriter was inactive or the predicate was not a random_variable comparison.
| random_variable provsql.random_variable_div | ( | random_variable | a, |
| random_variable | b ) |
random_variable / random_variable (gate_arith DIV).
| BOOLEAN provsql.random_variable_eq | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_eq_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| BOOLEAN provsql.random_variable_ge | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_ge_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| BOOLEAN provsql.random_variable_gt | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_gt_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| random_variable provsql.random_variable_in | ( | CSTRING | ) |
Input function for the random_variable type.
| BOOLEAN provsql.random_variable_le | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_le_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| BOOLEAN provsql.random_variable_lt | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_lt_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| random_variable provsql.random_variable_make | ( | UUID | tok | ) |
Build a random_variable from a UUID (internal).
| random_variable provsql.random_variable_minus | ( | random_variable | a, |
| random_variable | b ) |
random_variable - random_variable (gate_arith MINUS).
| BOOLEAN provsql.random_variable_ne | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_ne_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| random_variable provsql.random_variable_neg | ( | random_variable | a | ) |
Unary -random_variable (gate_arith NEG).
| BOOLEAN provsql.random_variable_op_boolean | ( | random_variable | left, |
| BOOLEAN | right ) |
| BOOLEAN provsql.random_variable_op_random_variable | ( | random_variable | left, |
| random_variable | right ) |
Prefix unary minus on random_variable.
| BOOLEAN provsql.random_variable_op_uuid | ( | random_variable | left, |
| UUID | right ) |
| CSTRING provsql.random_variable_out | ( | random_variable | ) |
Output function for the random_variable type.
| random_variable provsql.random_variable_plus | ( | random_variable | a, |
| random_variable | b ) |
random_variable + random_variable (gate_arith PLUS).
| random_variable provsql.random_variable_pow | ( | random_variable | a, |
| random_variable | b ) |
random_variable ^ random_variable (gate_arith POW).
Real-valued branch only: evaluation raises if a negative base is drawn together with a non-INTEGER exponent (write pow(greatest(x, 0), p) for the non-negative branch).
| random_variable provsql.random_variable_times | ( | random_variable | a, |
| random_variable | b ) |
random_variable * random_variable (gate_arith TIMES).
| random_variable provsql.rv_aggregate_indicator | ( | UUID | prov | ) |
Per-row denominator wrap for avg(random_variable): the provenance indicator \(\mathbf{1}\{\varphi\}\).
The row contributes 1 to the running count when present and 0 when absent, so sum over these wraps is the provenance-weighted count \(\sum_i \mathbf{1}\{\varphi_i\}\). The planner-hook rewrites avg(x) into rv_sum_or_null(rv_aggregate_semimod(prov, x)) / sum(rv_aggregate_indicator(prov)) – the "@c AVG @c = @c SUM @c /
@c COUNT" identity lifted into the random_variable algebra – so avg rides entirely on sum's fold and never inspects a gate.
| random_variable provsql.rv_aggregate_indicator | ( | UUID | prov, |
| random_variable | rv ) |
Value-aware presence indicator: NULL when the row's aggregated value is NULL.
SQL aggregates skip NULL inputs, so a NULL random_variable cell must not count in avg's denominator: the wrap yields NULL (which the sum fold skips) exactly when the value is NULL, and the plain one-argument indicator otherwise. The planner-hook avg rewrite emits this form; the one-argument indicator remains for the internal public-form defaults.
| random_variable provsql.rv_aggregate_semimod | ( | UUID | prov, |
| random_variable | rv ) |
Per-row helper: wrap an RV in mixture(prov, rv, as_random(0)).
Internal helper used by the planner-hook rewriter to lift a sum(random_variable) argument into its provenance-aware form. Encodes one row's contribution to the SUM as a Bernoulli mixture over the row's provenance: with probability P(prov) the mixture samples rv, otherwise it samples the additive identity as_random(0). Exposed as a regular SQL function so the planner can construct a FuncExpr by name without needing to disambiguate mixture / as_random overloads at OID-lookup time.
| random_variable provsql.rv_aggregate_semimod | ( | UUID | prov, |
| random_variable | rv, | ||
| DOUBLE PRECISION | identity ) |
Identity-parameterised per-row wrap for an RV-returning aggregate.
Generalises the two-argument rv_aggregate_semimod. The else-branch (a row's contribution when its provenance is false) is as_random(identity) instead of the additive as_random(0). The planner-hook rewrite bakes each aggregate's own identity element into the wrap – 1 for product, \(-\infty\) / \(+\infty\) for max / min – so the aggregate's final function is a plain fold over the per-row mixtures with no gate inspection. sum keeps the two-argument form (identity = 0).
| UUID provsql.rv_cmp_eq | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a = b and return its UUID.
| UUID provsql.rv_cmp_ge | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a ≥ b and return its UUID.
| UUID provsql.rv_cmp_gt | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a > b and return its UUID.
| UUID provsql.rv_cmp_le | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a ≤ b and return its UUID.
| UUID provsql.rv_cmp_lt | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a < b and return its UUID.
| UUID provsql.rv_cmp_ne | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a <> b and return its UUID.
| UUID provsql.rv_conditioned_prov | ( | UUID | token, |
| UUID | prov ) |
Combine a conditioning gate's event with an explicit prov.
For a two-child gate_conditioned [target, condition] returns "condition ∧ prov"; otherwise returns prov unchanged. Lets a stored "X | C" be queried as expected(X|C) (prov defaulting to one) or have an extra condition conjoined as expected(X|C, extra_prov).
| UUID provsql.rv_conditioned_target | ( | UUID | token | ) |
Unpack the target of a random-variable conditioning gate.
For a two-child gate_conditioned [target, condition] (the "X | C" shape) returns target; for any other token returns it unchanged. Used by the moment / support dispatchers to route a conditioned distribution through the existing conditional evaluator.
| VOID provsql.rv_corr_impl | ( | random_variable | , |
| random_variable | , | ||
| random_variable | ) |
| VOID provsql.rv_covar_pop_impl | ( | random_variable | , |
| random_variable | , | ||
| random_variable | ) |
The indicator-carrying rewrite targets (planner hook only; never called directly by users).
| VOID provsql.rv_covar_samp_impl | ( | random_variable | , |
| random_variable | , | ||
| random_variable | ) |
| TABLE provsql.rv_families | ( | ) |
Catalog of the registered continuous-distribution families.
One row per gate_rv family known to this build of the extension: name is the on-disk token (the part before the colon in the gate's extra encoding), nparams the parameter count, param_names the conventional parameter symbols in extra order (e.g. {μ, σ}), and label a short display glyph (e.g. "N", "Γ"). UI clients (ProvSQL Studio's circuit inspector) read this to render families they were not hard-coded for, so a newly added family shows up without a client release.
| random_variable provsql.rv_parametric1 | ( | TEXT | family, |
| UUID | p_tok ) |
Internal: build a one-parameter latent gate_rv (rate/scale).
| random_variable provsql.rv_parametric2 | ( | TEXT | family, |
| UUID | p1_tok, | ||
| DOUBLE PRECISION | p1_lit, | ||
| UUID | p2_tok, | ||
| DOUBLE PRECISION | p2_lit ) |
Internal: build a two-parameter latent gate_rv.
Each parameter is supplied as EITHER a token (pN_tok, a scalar gate UUID) OR a literal (pN_lit); exactly one is non-NULL per parameter. Token parameters are appended to the gate's wire vector in order and referenced as "$i" in the extra TEXT; literal parameters keep their decimal TEXT. Not STRICT: the NULLs are the literal-vs-token sentinels.
| VOID provsql.rv_percentile_impl | ( | DOUBLE PRECISION | , |
| random_variable | , | ||
| random_variable | ) |
| random_variable provsql.rv_percentile_impl_ffunc | ( | rv_percentile_state | state | ) |
Final function for rv_percentile_impl.
| rv_percentile_state provsql.rv_percentile_impl_sfunc | ( | rv_percentile_state | state, |
| DOUBLE PRECISION | fraction, | ||
| random_variable | ind, | ||
| random_variable | x ) |
State transition for rv_percentile_impl, the planner-hook rewrite target of a provenance-tracked percentile_cont: stashes the (group-constant) fraction and appends the indicator/value pair.
| random_variable provsql.rv_percentile_make | ( | DOUBLE PRECISION | fraction, |
| UUID[] | pairs ) |
Mint the PROVSQL_ARITH_PERCENTILE gate: the continuous percentile (SQL percentile_cont) over a group of RV rows.
pairs is the interleaved wire list [ind_1, x_1, ..., ind_n, x_n] (each ind_i a 0/1 presence-indicator RV). The fraction is TEXT-encoded in the gate's extra and participates in the token UUID (two percentiles of the same group at different fractions are distinct gates). Per Monte Carlo draw, the sampler collects the values whose indicator draws 1, sorts them, and linearly interpolates at the fraction; a draw with no present row is NaN (undefined world).
| UUID[] provsql.rv_stat1_impl_sfunc | ( | UUID[] | state, |
| random_variable | ind, | ||
| random_variable | x ) |
Indicator-carrying state transition for the one-argument rv_*_impl statistic aggregates: the planner-hook rewrite passes the row's provenance indicator rv_aggregate_indicator(prov) as ind.
| UUID[] provsql.rv_stat1_sfunc | ( | UUID[] | state, |
| random_variable | x ) |
SQL-standard statistic aggregates over random_variable rows: covar_pop / covar_samp / corr (two-argument), stddev_pop / stddev_samp (one-argument), and the ordered-set percentile_cont.
Row presence is carried by a per-row 0/1 indicator RV: the public aggregates use the certain indicator as_random(1) (every row present), and a provenance-tracked query is rewritten by the planner hook (make_rv_aggregate_expression) to the rv_*_impl aggregates whose extra leading argument is rv_aggregate_indicator(prov), so a row absent in a world drops out of every sum, the count, and the percentile member set. The moment statistics are built from indicator-weighted power sums with existing gate_arith opcodes (e.g. covar_pop = SXY/N - (SX/N)(SY/N)); a world where the statistic is undefined (N = 0, or N = 1 for the sample forms) evaluates to NaN, the established undefined-world convention the moment estimators skip. percentile_cont is the one gate the arithmetic cannot express: it mints the PROVSQL_ARITH_PERCENTILE gate_arith (interleaved [ind_1, x_1, ...] wires, fraction in extra) that the Monte Carlo sampler evaluates by sorting each draw's present values and interpolating.
State transition for the one-argument RV statistic aggregates (stddev_pop / stddev_samp): append the certain indicator and the row's RV as a pair. NULL rows are skipped (standard SQL).
| UUID[] provsql.rv_stat2_impl_sfunc | ( | UUID[] | state, |
| random_variable | ind, | ||
| random_variable | x, | ||
| random_variable | y ) |
Indicator-carrying state transition for the two-argument rv_*_impl statistic aggregates.
| UUID[] provsql.rv_stat2_sfunc | ( | UUID[] | state, |
| random_variable | x, | ||
| random_variable | y ) |
State transition for the two-argument RV statistic aggregates (covar_pop / covar_samp / corr): append the certain indicator and the row's RV pair as a triple.
Rows with either side NULL are skipped (standard SQL covariance semantics).
| UUID provsql.rv_stat_covar_pop_token | ( | UUID | n_tok, |
| UUID | sx_tok, | ||
| UUID | sy_tok, | ||
| UUID | sxy_tok ) |
Population-covariance gate \(SXY/N - (SX/N)(SY/N)\) from the power-sum tokens.
| UUID provsql.rv_stat_sqrt_token | ( | UUID | v_tok | ) |
\(\sqrt{\max(v, 0)}\) gate over a variance token: the max-clamp removes the tiny negative values float error can produce (variance is mathematically non-negative), so the POW domain guard never fires.
| VOID provsql.rv_stat_sum_tokens | ( | UUID[] | state, |
| INTEGER | stride, | ||
| OUT UUID | n_tok, | ||
| OUT UUID | sx_tok, | ||
| OUT UUID | sxx_tok, | ||
| OUT UUID | sy_tok, | ||
| OUT UUID | sxy_tok, | ||
| OUT UUID | syy_tok ) |
Mint the indicator-weighted power-sum gates shared by the covariance / stddev final functions.
state is the flat interleaved aggregate state – pairs [ind, x, ...] (stride 2) or triples [ind, x, y, ...] (stride 3). Emits gate_arith tokens for \(N = \sum_i \mathbf{1}_i\), \(SX = \sum_i \mathbf{1}_i x_i\), \(SXX = \sum_i \mathbf{1}_i x_i^2\) and, at stride 3, \(SY\), \(SXY\), \(SYY\). The per-row indicator gate is shared between \(N\) and every product it weighs, so the Monte Carlo per-iteration cache keeps the row's presence coupled across all the sums (and a repeated child [ind, x, x] reuses the same draw of x, giving \(x^2\), not two independent draws).
| UUID provsql.rv_stat_var_pop_token | ( | UUID | n_tok, |
| UUID | s_tok, | ||
| UUID | ss_tok ) |
Population-variance gate \(SXX/N - (SX/N)^2\) from the power-sum tokens.
| UUID provsql.rv_stat_var_samp_token | ( | UUID | n_tok, |
| UUID | s_tok, | ||
| UUID | ss_tok ) |
Sample-variance gate \((SXX - SX^2/N) / (N - 1)\) from the power-sum tokens (NaN in a world with \(N \le 1\), the undefined-world convention).
| VOID provsql.rv_stddev_pop_impl | ( | random_variable | , |
| random_variable | ) |
| VOID provsql.rv_stddev_samp_impl | ( | random_variable | , |
| random_variable | ) |
| VOID provsql.rv_sum_or_null | ( | random_variable | ) |
| random_variable provsql.rv_sum_or_null_ffunc | ( | UUID[] | state | ) |
Numerator final function for the avg rewrite: sum, but NULL on an empty group.
Identical to sum_rv_ffunc except that an empty group returns NULL rather than the additive identity as_random(0). The planner-hook avg rewrite emits rv_sum_or_null(rv_aggregate_semimod(prov, x)) / sum(rv_aggregate_indicator(prov)); random_variable_div is STRICT, so an empty group propagates the numerator's NULL and avg is NULL – the standard SQL AVG convention – while a non-empty group behaves exactly like sum.
| TABLE provsql.shapley_observe | ( | UUID | target, |
| UUID | evidence, | ||
| TEXT | payoff = 'expected' ) |
Shapley attribution of each observation to a posterior moment.
"Which observation most shifted my posterior?" Because the importance weight is a product of per-observation density factors, dropping an observation is dropping one factor: the classical Shapley value of each gate_observe atom over the coalitional value function "v(S) = payoff(target | observations in S)" is the attribution, a byproduct of the same likelihood-weighting machinery (see the explainable-inference angle in the continuous-distributions notes).
target is the latent (its UUID); evidence is the and_agg conjunction of observe atoms; payoff is 'expected' or 'variance'. Returns each observation atom with its Shapley value; the values sum to "payoff(target | all data) - payoff(target)" (Shapley efficiency: the total shift from prior to posterior).
Exact enumeration over the 2^n observation subsets, so it is capped at n = 12 observations (sampling-based attribution for larger sets is future work); pin provsql.monte_carlo_seed so the coalitional value functions share common random numbers (lower-variance differences).
| random_variable provsql.sqrt | ( | random_variable | a | ) |
Square root of a random_variable: sugar for x ^ 0.5 (no gate or opcode of its own).
Evaluation raises on a negative draw, like any non-INTEGER exponent.
| VOID provsql.stddev_pop | ( | random_variable | ) |
| random_variable provsql.stddev_pop_rv_ffunc | ( | UUID[] | state | ) |
Final function for stddev_pop(random_variable).
| VOID provsql.stddev_samp | ( | random_variable | ) |
| random_variable provsql.stddev_samp_rv_ffunc | ( | UUID[] | state | ) |
Final function for stddev_samp(random_variable).
| VOID provsql.sum | ( | random_variable | ) |
| random_variable provsql.sum_rv_ffunc | ( | UUID[] | state | ) |
Final function for sum(random_variable): build a gate_arith PLUS root.
Empty group (state = '{}'): return as_random(0), the additive identity, so SUM over zero rows is the deterministic scalar 0 – matches the AGG_TOKEN convention in agg_raw_moment.
Singleton group: return the single child directly without minting a useless single-child gate_arith.
Otherwise: build gate_arith(PLUS, state) via provenance_arith.
| UUID[] provsql.sum_rv_sfunc | ( | UUID[] | state, |
| random_variable | rv ) |
State-transition function for sum(random_variable).
Appends the input RV's UUID to the running array. NULL inputs are skipped (matching standard SUM semantics). The aggregate's INITCOND is '{}' so the FINALFUNC always runs even on an empty group, which is what lets us return as_random(0) (the additive identity) for an empty SUM rather than NULL.
| random_variable provsql.uniform | ( | DOUBLE PRECISION | a, |
| DOUBLE PRECISION | b ) |
Construct a uniform-distribution random variable on [a, b].
Validation:
a and b must be finite.a must be ≤ b (reversed bounds are rejected).a; the call is silently routed through as_random(a) for the same reason as normal with sigma = 0.| random_variable provsql.uniform | ( | DOUBLE PRECISION | a, |
| random_variable | b ) |
| random_variable provsql.uniform | ( | random_variable | a, |
| DOUBLE PRECISION | b ) |
uniform(a, b)
| random_variable provsql.uniform | ( | random_variable | a, |
| random_variable | b ) |
| random_variable provsql.wald | ( | DOUBLE PRECISION | mu, |
| DOUBLE PRECISION | lambda ) |
Wald distribution: alias for inverse_gaussian.
| random_variable provsql.weibull | ( | DOUBLE PRECISION | k, |
| DOUBLE PRECISION | lambda ) |
Construct a Weibull random variable with shape k and scale lambda.
lambda is the SCALE (the 63.2% quantile), not a rate: k = 1 is the exponential with rate 1/lambda, and that case is silently routed through exponential to share its gate. The shape tunes the hazard: k < 1 infant mortality, k > 1 wear-out. Quantiles are exact, truncated moments are closed-form (via the regularised incomplete gamma), and the min of i.i.d. Weibulls has a closed-form mean (min-stability).
Validation: both parameters must be finite and strictly positive.
| random_variable provsql.weibull | ( | DOUBLE PRECISION | k, |
| random_variable | lambda ) |
| random_variable provsql.weibull | ( | random_variable | k, |
| DOUBLE PRECISION | lambda ) |
weibull(k, lambda)
| random_variable provsql.weibull | ( | random_variable | k, |
| random_variable | lambda ) |
| CREATE OPERATOR CLASS random_variable_ops DEFAULT FOR TYPE random_variable USING btree AS provsql.OPERATOR<, OPERATOR 2<=, OPERATOR 3=, OPERATOR 4 > FUNCTION random_variable_btree_cmp(random_variable, random_variable) |