\set ECHO none \pset format unaligned -- Reachability self-join conjunctions: "are these k vertices all -- reachable" -- FROM reach r1, ..., reach rk with one constant node -- binding each. The row provenance is the provenance_times of -- *correlated* per-vertex reach tokens (they share edges), which -- entangles the per-vertex certificates. The lowering detects the -- shape, compiles the certified all-members-reachable circuit (the -- pending rescuer-set congruence folded through the decomposition DP) -- and plants it at the times-canonical address the conjunction -- computes -- so the natural query stays on the linear certified -- route, with joint-worlds semantics: probability evaluation is the -- k-terminal reliability, nonnegative min-plus the cost of the -- cheapest covering subgraph (directed Steiner cost), shared edges -- paid once. SET provsql.provenance = 'absorptive'; -- Hub network: 1->2 (cost 1), 1->3 (4), 2->4 (2), 3->4 (1), -- 4->5 (3), 4->6 (2); p = .9 everywhere. CREATE TABLE btwc_link(src int, dst int, cost float8); INSERT INTO btwc_link VALUES (1,2,1),(1,3,4),(2,4,2),(3,4,1),(4,5,3),(4,6,2); SELECT add_provenance('btwc_link'); DO $$ BEGIN PERFORM set_prob(provenance(), 0.9) FROM btwc_link; END $$; SELECT create_provenance_mapping('btwc_cost', 'btwc_link', 'cost'); -- A conjunction outside the recognised shape first (the second -- binding is an expression): nothing is planted, the generic path -- stays correct -- and uncertified. CREATE TABLE btwc_fb AS WITH RECURSIVE reach(node) AS ( SELECT 1 UNION SELECT e.dst FROM btwc_link e JOIN reach r ON e.src = r.node ) SELECT 1 AS ok, provenance() AS pv FROM reach r1, reach r2 WHERE r1.node = 5 AND r2.node = r1.node + 1; SELECT remove_provenance('btwc_fb'); -- P(reach 5 and reach 6) = P(reach 4)*.9*.9 -- = (.81 + .81 - .81^2)*.81 = .780759. SELECT (get_infos(pv)).info1 AS certified, round(probability_evaluate(pv, 'possible-worlds')::numeric, 6) AS rel FROM btwc_fb; DROP TABLE btwc_fb; -- The recognised shape: the certified all-members circuit is planted -- at the times-canonical address; probability evaluates through the -- linear independent route, exactly. CREATE TABLE btwc_2 AS WITH RECURSIVE reach(node) AS ( SELECT 1 UNION SELECT e.dst FROM btwc_link e JOIN reach r ON e.src = r.node ) SELECT 'both supplied' AS answer, provenance() AS pv FROM reach r1, reach r2 WHERE r1.node = 5 AND r2.node = 6; SELECT remove_provenance('btwc_2'); -- Steiner cost: trunk 1->2->4 (3) + 4->5 (3) + 4->6 (2) = 8, the -- shared trunk paid once (the raw product would pay it twice). SELECT answer, get_gate_type(pv) AS root, (get_infos(pv)).info1 AS certified, round(probability_evaluate(pv, 'independent')::numeric, 6) AS rel, round(probability_evaluate(pv, 'possible-worlds')::numeric, 6) AS rel_pw, sr_tropical(pv, 'btwc_cost', nonnegative => true) AS steiner FROM btwc_2; DROP TABLE btwc_2; -- The deviating phrasing now computes the same token multiset and -- lands on the planted gate: content addressing, not syntax. CREATE TABLE btwc_fb2 AS WITH RECURSIVE reach(node) AS ( SELECT 1 UNION SELECT e.dst FROM btwc_link e JOIN reach r ON e.src = r.node ) SELECT 1 AS ok, provenance() AS pv FROM reach r1, reach r2 WHERE r1.node = 5 AND r2.node = r1.node + 1; SELECT remove_provenance('btwc_fb2'); SELECT (get_infos(pv)).info1 AS certified, round(probability_evaluate(pv, 'independent')::numeric, 6) AS rel FROM btwc_fb2; DROP TABLE btwc_fb2; -- Three terminals; the optimal covering tree routes *through* -- terminal 3: 1->3 (4) + 3->4 (1) + 4->5 (3) + 4->6 (2) = 10. CREATE TABLE btwc_3 AS WITH RECURSIVE reach(node) AS ( SELECT 1 UNION SELECT e.dst FROM btwc_link e JOIN reach r ON e.src = r.node ) SELECT 1 AS ok, provenance() AS pv FROM reach r1, reach r2, reach r3 WHERE r1.node = 5 AND r2.node = 6 AND r3.node = 3; SELECT remove_provenance('btwc_3'); SELECT (get_infos(pv)).info1 AS certified, round(probability_evaluate(pv, 'independent')::numeric, 6) AS rel, round(probability_evaluate(pv, 'possible-worlds')::numeric, 6) AS rel_pw, sr_tropical(pv, 'btwc_cost', nonnegative => true) AS steiner FROM btwc_3; -- Counting refuses the planted token (absorptive quotient only). SELECT sr_counting(pv, 'btwc_cost') FROM btwc_3; DROP TABLE btwc_3; -- Cyclic data: a return edge 6->1 changes nothing for the terminals -- (loops never help coverage), and the compilation handles the cycle -- natively. CREATE TABLE btwc_cyc(src int, dst int, cost float8); INSERT INTO btwc_cyc VALUES (1,2,1),(2,3,4),(3,1,1),(2,4,2); SELECT add_provenance('btwc_cyc'); DO $$ BEGIN PERFORM set_prob(provenance(), 0.5) FROM btwc_cyc; END $$; SELECT create_provenance_mapping('btwc_cyc_cost', 'btwc_cyc', 'cost'); CREATE TABLE btwc_c AS WITH RECURSIVE reach(node) AS ( SELECT 1 UNION SELECT e.dst FROM btwc_cyc e JOIN reach r ON e.src = r.node ) SELECT 1 AS ok, provenance() AS pv FROM reach r1, reach r2 WHERE r1.node = 3 AND r2.node = 4; SELECT remove_provenance('btwc_c'); -- Both need 1->2 (.5), then 2->3 (.5) and 2->4 (.5): rel = .125; -- Steiner = 1 + 4 + 2 = 7. SELECT (get_infos(pv)).info1 AS certified, round(probability_evaluate(pv, 'independent')::numeric, 6) AS rel, round(probability_evaluate(pv, 'possible-worlds')::numeric, 6) AS rel_pw, sr_tropical(pv, 'btwc_cyc_cost', nonnegative => true) AS steiner FROM btwc_c; DROP TABLE btwc_c; SELECT remove_provenance('btwc_cyc'); DROP TABLE btwc_cyc; SET provsql.provenance = 'semiring'; SELECT remove_provenance('btwc_link'); DROP TABLE btwc_link; RESET provsql.provenance;