-- General initialization CREATE SCHEMA facts; -- Define predicates CREATE TABLE facts.edge (id serial PRIMARY KEY, arg0 bigint, arg1 bigint); CREATE TABLE facts.reachable (id serial PRIMARY KEY, arg0 bigint, arg1 bigint); CREATE TABLE facts.same_clique (id serial PRIMARY KEY, arg0 bigint, arg1 bigint); -- Restrict predicates to contain unique facts CREATE UNIQUE INDEX pred_edge_unique ON facts.edge (arg0,arg1); CREATE UNIQUE INDEX pred_reachable_unique ON facts.reachable (arg0,arg1); CREATE UNIQUE INDEX pred_same_clique_unique ON facts.same_clique (arg0,arg1); -- Add triggers to automate rules CREATE FUNCTION holmes_rule_reach_edge_0() RETURNS trigger AS $reach_edge$ BEGIN INSERT INTO facts.reachable (arg0, arg1) (SELECT NEW.arg0, NEW.arg1 ) ON CONFLICT DO NOTHING; RETURN NULL; END; $reach_edge$ LANGUAGE plpgsql; CREATE TRIGGER holmes_rule_reach_edge_0 AFTER INSERT ON facts.edge FOR EACH ROW EXECUTE PROCEDURE holmes_rule_reach_edge_0(); ; CREATE FUNCTION holmes_rule_reach_trans_0() RETURNS trigger AS $reach_trans$ BEGIN INSERT INTO facts.reachable (arg0, arg1) (SELECT NEW.arg0, t0.arg1 FROM facts.reachable as t0 WHERE NEW.arg1 = t0.arg0) ON CONFLICT DO NOTHING; RETURN NULL; END; $reach_trans$ LANGUAGE plpgsql; CREATE TRIGGER holmes_rule_reach_trans_0 AFTER INSERT ON facts.edge FOR EACH ROW EXECUTE PROCEDURE holmes_rule_reach_trans_0(); CREATE FUNCTION holmes_rule_reach_trans_1() RETURNS trigger AS $reach_trans$ BEGIN INSERT INTO facts.reachable (arg0, arg1) (SELECT t0.arg0, NEW.arg1 FROM facts.edge as t0 WHERE t0.arg1 = NEW.arg0) ON CONFLICT DO NOTHING; RETURN NULL; END; $reach_trans$ LANGUAGE plpgsql; CREATE TRIGGER holmes_rule_reach_trans_1 AFTER INSERT ON facts.reachable FOR EACH ROW EXECUTE PROCEDURE holmes_rule_reach_trans_1(); ; CREATE FUNCTION holmes_rule_scc_0() RETURNS trigger AS $scc$ BEGIN INSERT INTO facts.same_clique (arg0, arg1) (SELECT NEW.arg0, NEW.arg1 FROM facts.reachable as t0 WHERE NEW.arg1 = t0.arg0 AND NEW.arg0 = t0.arg1) ON CONFLICT DO NOTHING; RETURN NULL; END; $scc$ LANGUAGE plpgsql; CREATE TRIGGER holmes_rule_scc_0 AFTER INSERT ON facts.reachable FOR EACH ROW EXECUTE PROCEDURE holmes_rule_scc_0(); CREATE FUNCTION holmes_rule_scc_1() RETURNS trigger AS $scc$ BEGIN INSERT INTO facts.same_clique (arg0, arg1) (SELECT t0.arg0, t0.arg1 FROM facts.reachable as t0 WHERE t0.arg1 = NEW.arg0 AND t0.arg0 = NEW.arg1) ON CONFLICT DO NOTHING; RETURN NULL; END; $scc$ LANGUAGE plpgsql; CREATE TRIGGER holmes_rule_scc_1 AFTER INSERT ON facts.reachable FOR EACH ROW EXECUTE PROCEDURE holmes_rule_scc_1(); ; CREATE FUNCTION insert_for_clique(iters int) RETURNS VOID as $$ DECLARE counter integer := 0; BEGIN LOOP EXIT WHEN counter = iters; INSERT INTO facts.edge (arg0, arg1) values (counter, counter + 1); counter := counter + 1; END LOOP; INSERT INTO facts.edge (arg0, arg1) values (counter, 0); END ; $$ LANGUAGE plpgsql; SELECT insert_for_clique(1000);