\set ECHO none \pset format unaligned SET search_path TO provsql_test,provsql; -- probability_bounds(token) returns a cheap CERTIFIED interval [lower,upper] -- with lower <= probability_evaluate(token) <= upper, computed without -- compiling the circuit (the Olteanu-Huang-Koch d-tree leaf bound, ICDE 2010 -- Fig. 3). It is deterministic (no sampling), so the expected values are -- exact. boolean_provenance off so the load-time fold leaves the DNF intact. SET provsql.boolean_provenance = off; CREATE TABLE pb(id int); INSERT INTO pb SELECT generate_series(1,6); SELECT add_provenance('pb'); DO $$ BEGIN PERFORM set_prob(provenance(), 0.1*id) FROM pb; END $$; -- Build the witness circuits with the rewriter off (we manipulate the provsql -- column directly, which the planner hook would otherwise intercept). SET provsql.active = off; DO $$ DECLARE x uuid[]; BEGIN SELECT array_agg(provsql::uuid ORDER BY id) INTO x FROM pb; -- (a) read-once DNF: (x1 x2) OR (x3 x4) OR (x5 x6). The clauses have disjoint -- supports, so the bound's single bucket gives lower = upper = exact. PERFORM set_config('pb.ro', provenance_plus(ARRAY[ provenance_times(x[1],x[2]), provenance_times(x[3],x[4]), provenance_times(x[5],x[6])])::text, false); -- (b) shared-variable DNF: (x1 x2) OR (x1 x3). x1 is in both clauses, so they -- fall in different buckets and the interval is non-trivial but sound. PERFORM set_config('pb.sh', provenance_plus(ARRAY[ provenance_times(x[1],x[2]), provenance_times(x[1],x[3])])::text, false); -- (c) non-DNF: AND-of-ORs (x1 OR x2) AND (x3 OR x4) -- a times over plus gates, -- which is not the monotone OR-of-ANDs shape the leaf bound requires. PERFORM set_config('pb.cnf', provenance_times( provenance_plus(ARRAY[x[1],x[2]]), provenance_plus(ARRAY[x[3],x[4]]))::text, false); END $$; RESET provsql.active; -- (a) Read-once: the interval collapses to the exact probability. SELECT round(lower::numeric,6) AS ro_lo, round(upper::numeric,6) AS ro_hi, round(probability_evaluate(current_setting('pb.ro')::uuid)::numeric,6) AS ro_exact FROM probability_bounds(current_setting('pb.ro')::uuid); -- (b) Shared x1: bounds bracket the exact value and the interval is non-trivial. SELECT round(lower::numeric,6) AS sh_lo, round(upper::numeric,6) AS sh_hi, round(probability_evaluate(current_setting('pb.sh')::uuid)::numeric,6) AS sh_exact, lower <= probability_evaluate(current_setting('pb.sh')::uuid) AND probability_evaluate(current_setting('pb.sh')::uuid) <= upper AS sound, lower < upper AS nontrivial FROM probability_bounds(current_setting('pb.sh')::uuid); -- (c) Non-DNF circuit: errors cleanly (the leaf bound is DNF-specific). SELECT lower FROM probability_bounds(current_setting('pb.cnf')::uuid); SELECT remove_provenance('pb'); DROP TABLE pb; RESET provsql.boolean_provenance;