\set ECHO none \pset format unaligned -- Event negation: the prefix ! operator (function alias provenance_not) is the -- complement of a Boolean provenance event -- sugar for monus(one, x), i.e. -- Boolean NOT / probability 1-P(x). It is an ordinary semiring expression (not -- a measure-only marker), so it composes like any monus; a conditioned token is -- refused as its child. The motivating use is conditioning on the -- non-occurrence of a UCQ violation event (a denial constraint): Q | ! W. CREATE TABLE t(id int, p float); INSERT INTO t VALUES (1,0.6),(2,0.5),(3,0.7); SELECT add_provenance('t'); DO $$ BEGIN PERFORM set_prob(provenance(), p) FROM t; END $$; SET provsql.active = off; DO $$ BEGIN PERFORM set_config('n.t1', (SELECT provsql FROM t WHERE id=1)::text, false); PERFORM set_config('n.t2', (SELECT provsql FROM t WHERE id=2)::text, false); END $$; RESET provsql.active; -- !x = NOT x: P(!t1) = 1 - 0.6 = 0.4, and the prefix operator and the -- provenance_not function agree. SELECT abs(probability_evaluate(! current_setting('n.t1')::uuid) - 0.4) < 1e-9 AS not_op_ok, probability_evaluate(! current_setting('n.t1')::uuid) = probability_evaluate(provenance_not(current_setting('n.t1')::uuid)) AS op_eq_fn; -- Double negation: !!t1 = t1 (probability back to 0.6). SELECT abs(probability_evaluate(! ! current_setting('n.t1')::uuid) - 0.6) < 1e-9 AS double_neg_ok; -- Negation composes under times like any monus: P(t1 AND !t2) = 0.6*0.5 = 0.3. SELECT abs(probability_evaluate(provenance_times(current_setting('n.t1')::uuid, ! current_setting('n.t2')::uuid)) - 0.3) < 1e-9 AS compose_ok; -- Denial constraint: P(booking 1 present | no two overlapping same-room -- bookings). The violation event W is built by provenance aggregation over the -- join (each joined row's provenance is a ⊗ b; GROUP BY () ORs them) -- no -- hand-rolled gates -- captured into a GUC, then conditioned on its negation via -- "| !". Only pair (1,2) overlaps, so W = b1∧b2 (P=0.3) and the posterior is -- 0.6·0.5/0.7 = 0.428571. CREATE TABLE bookings(id int, room int, lo int, hi int, p float); INSERT INTO bookings VALUES (1,7,10,20,0.6),(2,7,15,25,0.5),(3,7,30,40,0.7); SELECT add_provenance('bookings'); DO $$ BEGIN PERFORM set_prob(provenance(), p) FROM bookings; END $$; DO $$ DECLARE wtok uuid; BEGIN SELECT provenance() INTO wtok FROM bookings a JOIN bookings b ON a.id