What's new in 1.10.0
ProvSQL 1.10.0 is about exact probability evaluation for query shapes
that used to be out of reach: recursive reachability (network
reliability) compiled along a tree decomposition of the data,
a joint-width compiler for unsafe UCQs over correlated inputs, the
Möbius-inversion route that completes the safe-UCQ dichotomy, an
absorptive provenance class that makes semiring evaluation meaningful
on cyclic recursion (min-cost paths and friends), and a conditioning
surface (the | operator) that turns ProvSQL into a probability
calculator. HAVING gains boolean-aggregate, array_agg and
generalized choose() comparisons, and Shapley/Banzhaf computation
picks its d-DNNF construction route by cost.
Recursive reachability on bounded-treewidth data
- Network reliability through a plain
WITH RECURSIVEquery.
Underprovsql.provenance = 'boolean', recursive reachability
queries over a tracked edge relation are recognised and compiled
along a tree decomposition of the data graph into
deterministic-decomposable (d-D) circuits, by construction and
certified per gate: linear size for fixed data treewidth, cyclic
graphs native, evaluated linearly by the certificate-aware
independentmethod. An undirected cyclic ladder with 2998
probabilistic edges answers exactly in ~0.3 s through the plain
recursive query, where the generic Boolean fixpoint exceeded two
minutes at 28 edges. Any unrecognised shape (or a treewidth above
the cap) falls back to the generic route with a notice. - Recognised variants. Directed and undirected connectivity,
deterministic edge-column filters, multi-source base arms
(SELECT v FROM sources, probabilistic source sets included),
repair_keyBID edge blocks (compiled as native (k+1)-way
branchings), join-defined edge subqueries with disjoint-support
tokens, and bounded-hop reachability (the hop-counting CTE) via
walk-length-set states. - Reachability aggregations.
GROUP BYover reach joined with a
member relation evaluates per-group "some member reached"
reliability exactly (one shared bottom-up sweep across all groups);
SELECT DISTINCTis recognised as the GROUP BY twin;
member-relation filters push into the planting; and self-join
conjunctions (FROM reach r1, reach r2 WHERE ...) compile the
k-terminal coverage event, giving k-terminal reliability and, under
nonnegative min-plus, exact directed Steiner cost.
Absorptive provenance and cyclic recursion
- One provenance class GUC. The session GUCs collapse into
provsql.provenance = where | semiring (default) | absorptive | boolean; the Boolean-assumption marker generalises to a labelled
assume()gate. - Cyclic recursion, exactly. Under an absorptive class, recursive
queries on cyclic data stop at the absorptive value fixpoint and
their tokens carry an 'absorptive' marker: accepted by absorptive
evaluations, refused with a clear error by counting, why-provenance
and unrestricted tropical.sr_tropical(token, true)(nonnegative
min-plus) gives exact min-cost reachability on cyclic graphs;
Viterbi (most-reliable path), max-min (widest path), Łukasiewicz
and temporal validity ranges all read the compiled reachability
circuits exactly. - Absorptive folds. The load-time simplification rules are split
by the semiring class that justifies them; plus-idempotence and the
absorption laws sound in every absorptive semiring now fire under
the absorptive class.
Joint-width compiler for unsafe UCQs
- Transparent recognition. Under Boolean provenance, unsafe UCQs
(the genuinely #P-hard shapes) are recognised at planning time
(provsql.joint_width, default on) and compiled along a joint
decomposition of data and circuit into a certified d-D, including
over correlated inputs (view-derived lineage, shared events,
repair_keyblocks), the regime where the treewidth of the data or
of the circuit alone says nothing. A cheap width screen
(provsql.joint_max_treewidth) declines cleanly to the standard
route. - Boolean and per-answer. Existence queries and per-answer
GROUP BY/DISTINCTheads of any type are covered, across
comma-list,JOIN ... ON, subquery andUNION(multi-disjunct
UCQ) spellings, with single-relation predicates pushed into the
gathering; a single top-down dynamic program emits one circuit root
per answer, making a k-answer query linear in k. The materialised
token is ordinary provenance:shapley(),expected()and every
named probability method work on it unchanged. - Compile stats.
ucq_joint_compile_statsreports the realised
widths and the essential-variable count mined from functional
dependencies that hold on the gathered data.
Möbius inversion: the last safe-UCQ route
- Safe by cancellation. UCQs that are safe only because their
#P-hard inclusion-exclusion terms carry zero Möbius value (the
dichotomy's q9/QW witnesses) are now answered in polynomial time: a
measure-onlygate_mobiuscombines lifted-inference read-once
islands with signed integer coefficients, while a transparent
lineage child keeps Shapley, semiring evaluation, possible worlds
and PROV export on the literal provenance. Takes precedence over
joint-width when both apply;provsql.mobiusGUC; first-class
'mobius'method name; Boolean and per-answer forms.
Conditioning: ProvSQL as a probability calculator
- The
|operator. Condition any provenance token on an event:
P(Q | W)via the binary|(functioncond()), whole-tuple
conditioning via the prefixgiven(), conditioned
random_variableandagg_tokendistributions (rv | C,
agg | C, composable, with arithmetic over the conditioned
distributions and exact analytical histograms for closed-form
shapes), and the naturalX | (predicate)form for every carrier. - Denial constraints. The prefix
!(functionprovenance_not)
negates a Boolean provenance event, giving theQ | !W
denial-constraint form. - Mixed predicates. Regular comparisons mixed with probabilistic
ones are accepted in WHERE/HAVING conditions; unsupported
combinations (e.g. Shapley on a conditioned token) refuse with
clear errors.
HAVING
- Boolean aggregates.
bool_and/bool_or/everycarry
provenance, compare against constants via an exact two-value
characterisation, and work bare (HAVING bool_or(x),
NOT (every(x))). array_aggcomparisons.array_agg(...) = / <> ARRAY[...]
over any element type via possible-worlds enumeration, following
the aggregate's ORDER BY on every PostgreSQL version and
reconciling PostgreSQL's two boolean text forms.choose()over any type. Equality comparisons ofchoose()
over non-numeric values (booleans, dates, UUIDs, ...) through the
value-as-text domain.- Certified enumerations. When a possible-worlds expansion has
independent contributors, it is built as a certified d-DNNF and
evaluated exactly and linearly (AVG vs constant, arithmetic over
several aggregates, choose-vs-text); correlated contributors keep
their previous routes.
Probability engine
- Cost-selected d-DNNF construction.
shapley(),banzhaf()and
shapley_all_vars()pick among the d-DNNF constructors with the
method catalog's cost-based chooser by default ('auto'; pass
'ladder'to force the historical chain). - BID circuits everywhere. A declarative dispatch flag routes
repair_key/ multivalued circuits through the Boolean rewrite for
every Boolean-only method, sod-tree(and future methods) handle
them instead of erroring. - Deep and shared circuits. Semiring evaluation is memoised and
iterative: shared sub-DAGs are no longer re-expanded per path
(exponential worst case) and circuits as deep as the data no longer
hit the stack-depth ceiling.
Robustness
- Fixed a use-after-free in compiled semiring evaluation over
pass-by-reference carriers: everysr_temporal/sr_interval_*
call read freed memory and could fail on larger circuits. - Fixed
interpret-as-ddreturning probability 0 on circuits with
De Morgan'd ORs (NOT gates were treated as leaves). - HAVING
array_agg(bool)vs a constant bool array no longer always
fails, and the comparison no longer depends on the executor's row
order (PostgreSQL 16+ masked this by pre-sorting ordered-aggregate
input).
Documentation
- The probability chapter is reorganised user-workflow-first and
gains a tractable-cases grid (data, annotation, query class, data
complexity, mechanism) covering all routes, with the method
catalogue completed. - New Conditioning chapter; case study 7 restructured into parts A/B/C
(cyclic reachability through the absorptive class, the
bounded-treewidth reliability route, joint-width and Möbius); new
case study 8, "ProvSQL as a probability calculator", notebook-first. - A floating button (and
\shortcut) collapses the documentation
sidebar; sitemap, per-page meta descriptions and Open Graph tags
across the site.
Development
make coveragebuilds a gcov-instrumented extension, runs the
suite in a throwaway cluster and reports line and never-called
function coverage.