-- customerkg-agentic-marketing.sql -- CustomerKG: a synthetic quick-service-restaurant estate that holds customer, business, decision and control context, -- projected as an RDF View. All rows are invented for illustration. Standard SQL up to Part 2; Parts 3 to 6 are Virtuoso extensions. -- Run: isql :1111 dba < customerkg-agentic-marketing.sql (or paste into Conductor's Interactive SQL page) -- Change CustomerKG.kidehen if you want another qualifier or owner; keep it identical everywhere in the file. -- Part 1: tables, parents before children CREATE TABLE CustomerKG.kidehen.channel (channel_id INTEGER NOT NULL PRIMARY KEY, channel_name VARCHAR(40) NOT NULL, channel_kind VARCHAR(8) NOT NULL); CREATE TABLE CustomerKG.kidehen.product (product_id INTEGER NOT NULL PRIMARY KEY, product_name VARCHAR(48) NOT NULL, category VARCHAR(16) NOT NULL, margin_pct INTEGER NOT NULL); CREATE TABLE CustomerKG.kidehen.customer (customer_id INTEGER NOT NULL PRIMARY KEY, full_name VARCHAR(48) NOT NULL, lifecycle_stage VARCHAR(12) NOT NULL, loyalty_tier VARCHAR(8) NOT NULL, home_city VARCHAR(24) NOT NULL, usual_order_day VARCHAR(10) NOT NULL); CREATE TABLE CustomerKG.kidehen.identity_signal (signal_id INTEGER NOT NULL PRIMARY KEY, customer_id INTEGER, signal_kind VARCHAR(16) NOT NULL, signal_value VARCHAR(24) NOT NULL, match_method VARCHAR(16) NOT NULL, confidence INTEGER NOT NULL, seen_date DATE NOT NULL, FOREIGN KEY (customer_id) REFERENCES CustomerKG.kidehen.customer (customer_id)); CREATE TABLE CustomerKG.kidehen.consent (consent_id INTEGER NOT NULL PRIMARY KEY, customer_id INTEGER NOT NULL, channel_id INTEGER NOT NULL, status VARCHAR(10) NOT NULL, updated_date DATE NOT NULL, FOREIGN KEY (customer_id) REFERENCES CustomerKG.kidehen.customer (customer_id), FOREIGN KEY (channel_id) REFERENCES CustomerKG.kidehen.channel (channel_id)); CREATE TABLE CustomerKG.kidehen.offer (offer_id INTEGER NOT NULL PRIMARY KEY, offer_name VARCHAR(40) NOT NULL, offer_kind VARCHAR(16) NOT NULL, discount_pct INTEGER NOT NULL, product_id INTEGER, FOREIGN KEY (product_id) REFERENCES CustomerKG.kidehen.product (product_id)); CREATE TABLE CustomerKG.kidehen.guardrail (guardrail_id INTEGER NOT NULL PRIMARY KEY, rule_name VARCHAR(48) NOT NULL, rule_kind VARCHAR(20) NOT NULL, limit_value INTEGER NOT NULL, offer_id INTEGER, FOREIGN KEY (offer_id) REFERENCES CustomerKG.kidehen.offer (offer_id)); CREATE TABLE CustomerKG.kidehen.campaign (campaign_id INTEGER NOT NULL PRIMARY KEY, campaign_name VARCHAR(48) NOT NULL, goal VARCHAR(80) NOT NULL, start_date DATE NOT NULL); CREATE TABLE CustomerKG.kidehen.decision (decision_id INTEGER NOT NULL PRIMARY KEY, customer_id INTEGER NOT NULL, campaign_id INTEGER NOT NULL, arm VARCHAR(10) NOT NULL, action_kind VARCHAR(16) NOT NULL, offer_id INTEGER, channel_id INTEGER, decided_date DATE NOT NULL, rationale VARCHAR(160) NOT NULL, approved_by_human INTEGER NOT NULL, FOREIGN KEY (customer_id) REFERENCES CustomerKG.kidehen.customer (customer_id), FOREIGN KEY (campaign_id) REFERENCES CustomerKG.kidehen.campaign (campaign_id), FOREIGN KEY (offer_id) REFERENCES CustomerKG.kidehen.offer (offer_id), FOREIGN KEY (channel_id) REFERENCES CustomerKG.kidehen.channel (channel_id)); CREATE TABLE CustomerKG.kidehen.decision_guardrail (decision_id INTEGER NOT NULL, guardrail_id INTEGER NOT NULL, PRIMARY KEY (decision_id, guardrail_id), FOREIGN KEY (decision_id) REFERENCES CustomerKG.kidehen.decision (decision_id), FOREIGN KEY (guardrail_id) REFERENCES CustomerKG.kidehen.guardrail (guardrail_id)); CREATE TABLE CustomerKG.kidehen.context_item (item_id INTEGER NOT NULL PRIMARY KEY, decision_id INTEGER NOT NULL, context_type VARCHAR(10) NOT NULL, context_key VARCHAR(24) NOT NULL, context_value VARCHAR(120) NOT NULL, FOREIGN KEY (decision_id) REFERENCES CustomerKG.kidehen.decision (decision_id)); CREATE TABLE CustomerKG.kidehen.outcome (outcome_id INTEGER NOT NULL PRIMARY KEY, decision_id INTEGER NOT NULL, ordered INTEGER NOT NULL, revenue_usd INTEGER NOT NULL, margin_usd INTEGER NOT NULL, media_cost_usd INTEGER NOT NULL, discount_cost_usd INTEGER NOT NULL, repeat_visit_30d INTEGER NOT NULL, window_end DATE NOT NULL, FOREIGN KEY (decision_id) REFERENCES CustomerKG.kidehen.decision (decision_id)); -- Part 2: rows, one INSERT each (Virtuoso has no multi-row VALUES) INSERT INTO CustomerKG.kidehen.channel VALUES (1, 'App push', 'owned'); INSERT INTO CustomerKG.kidehen.channel VALUES (2, 'Email', 'owned'); INSERT INTO CustomerKG.kidehen.channel VALUES (3, 'SMS', 'owned'); INSERT INTO CustomerKG.kidehen.channel VALUES (4, 'Paid social', 'paid'); INSERT INTO CustomerKG.kidehen.channel VALUES (5, 'Display retargeting', 'paid'); INSERT INTO CustomerKG.kidehen.product VALUES (1, 'Classic Burger Meal', 'meal', 38); INSERT INTO CustomerKG.kidehen.product VALUES (2, 'Family Meal Bundle', 'bundle', 31); INSERT INTO CustomerKG.kidehen.product VALUES (3, 'Side of Fries', 'side', 62); INSERT INTO CustomerKG.kidehen.product VALUES (4, 'Weekly Friday Combo', 'meal', 35); INSERT INTO CustomerKG.kidehen.product VALUES (5, 'Dessert Treat', 'dessert', 58); INSERT INTO CustomerKG.kidehen.customer VALUES (1, 'Avery Quinn', 'lapsing', 'gold', 'Austin', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (2, 'Blake Moreno', 'lapsing', 'silver', 'Denver', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (3, 'Casey Lindholm', 'lapsed', 'gold', 'Seattle', 'Saturday'); INSERT INTO CustomerKG.kidehen.customer VALUES (4, 'Devon Okafor', 'lapsed', 'bronze', 'Atlanta', 'Thursday'); INSERT INTO CustomerKG.kidehen.customer VALUES (5, 'Emery Castillo', 'lapsing', 'silver', 'Phoenix', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (6, 'Frankie Novak', 'lapsed', 'bronze', 'Chicago', 'Sunday'); INSERT INTO CustomerKG.kidehen.customer VALUES (7, 'Gray Whitfield', 'lapsing', 'silver', 'Boston', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (8, 'Harper Doyle', 'lapsed', 'bronze', 'Portland', 'Saturday'); INSERT INTO CustomerKG.kidehen.customer VALUES (9, 'Indigo Raman', 'lapsed', 'gold', 'Dallas', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (10, 'Jules Barrow', 'lapsing', 'silver', 'Miami', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (11, 'Kendall Osei', 'lapsed', 'bronze', 'Tampa', 'Saturday'); INSERT INTO CustomerKG.kidehen.customer VALUES (12, 'Lennox Pryce', 'lapsed', 'bronze', 'Raleigh', 'Sunday'); INSERT INTO CustomerKG.kidehen.customer VALUES (13, 'Marlowe Tran', 'lapsing', 'gold', 'San Jose', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (14, 'Noel Ferreira', 'lapsed', 'bronze', 'Newark', 'Thursday'); INSERT INTO CustomerKG.kidehen.customer VALUES (15, 'Oakley Brandt', 'active', 'silver', 'Omaha', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (16, 'Parker Zielinski', 'active', 'gold', 'Madison', 'Saturday'); INSERT INTO CustomerKG.kidehen.customer VALUES (17, 'Quincy Abara', 'active', 'silver', 'Memphis', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (18, 'Rowan Eklund', 'active', 'bronze', 'Boise', 'Sunday'); INSERT INTO CustomerKG.kidehen.customer VALUES (19, 'Sage Whitlock', 'active', 'gold', 'Tulsa', 'Friday'); INSERT INTO CustomerKG.kidehen.customer VALUES (20, 'Tatum Reyes', 'active', 'silver', 'Reno', 'Friday'); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (1, 1, 'email', 'hem:a1f3', 'deterministic', 100, stringdate('2026-08-02')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (2, 1, 'loyalty_id', 'LY-10001', 'deterministic', 100, stringdate('2026-08-02')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (3, 1, 'app_session', 'sess:77a1', 'probabilistic', 86, stringdate('2026-09-24')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (4, 2, 'email', 'hem:b2c4', 'deterministic', 100, stringdate('2026-08-05')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (5, 2, 'device', 'dev:ios-31c', 'probabilistic', 82, stringdate('2026-09-20')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (6, 3, 'email', 'hem:c3d5', 'deterministic', 100, stringdate('2026-07-30')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (7, 3, 'app_session', 'sess:5e90', 'agentic', 91, stringdate('2026-09-27')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (8, 3, 'ad_exposure', 'imp:vid-204', 'probabilistic', 74, stringdate('2026-09-25')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (9, 4, 'email', 'hem:d4e6', 'deterministic', 100, stringdate('2026-07-15')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (10, 4, 'device', 'dev:and-8b2', 'probabilistic', 79, stringdate('2026-09-18')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (11, 5, 'email', 'hem:e5f7', 'deterministic', 100, stringdate('2026-08-11')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (12, 5, 'app_session', 'sess:a310', 'agentic', 88, stringdate('2026-09-26')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (13, 6, 'loyalty_id', 'LY-10006', 'deterministic', 100, stringdate('2026-06-21')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (14, 6, 'ad_exposure', 'imp:soc-118', 'probabilistic', 71, stringdate('2026-09-23')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (15, 7, 'email', 'hem:f708', 'deterministic', 100, stringdate('2026-08-19')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (16, 7, 'device', 'dev:ios-99d', 'deterministic', 100, stringdate('2026-09-21')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (17, 8, 'email', 'hem:0819', 'deterministic', 100, stringdate('2026-07-02')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (18, 8, 'app_session', 'sess:c442', 'probabilistic', 77, stringdate('2026-09-19')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (19, 9, 'email', 'hem:192a', 'deterministic', 100, stringdate('2026-08-08')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (20, 9, 'app_session', 'sess:1d6b', 'agentic', 93, stringdate('2026-09-27')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (21, 10, 'email', 'hem:2a3b', 'deterministic', 100, stringdate('2026-08-14')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (22, 11, 'loyalty_id', 'LY-10011', 'deterministic', 100, stringdate('2026-05-30')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (23, 12, 'email', 'hem:3b4c', 'deterministic', 100, stringdate('2026-06-12')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (24, 13, 'email', 'hem:4c5d', 'deterministic', 100, stringdate('2026-08-22')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (25, 13, 'app_session', 'sess:e8f2', 'probabilistic', 84, stringdate('2026-09-24')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (26, 14, 'email', 'hem:5d6e', 'deterministic', 100, stringdate('2026-06-03')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (27, NULL, 'app_session', 'sess:9b13', 'unmatched', 0, stringdate('2026-09-28')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (28, NULL, 'ad_exposure', 'imp:soc-402', 'unmatched', 0, stringdate('2026-09-28')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (29, NULL, 'device', 'dev:and-c10', 'unmatched', 0, stringdate('2026-09-29')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (30, NULL, 'app_session', 'sess:2f77', 'unmatched', 0, stringdate('2026-09-29')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (31, 15, 'email', 'hem:6e7f', 'deterministic', 100, stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (32, 16, 'email', 'hem:7f80', 'deterministic', 100, stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (33, 17, 'email', 'hem:8091', 'deterministic', 100, stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (34, 18, 'email', 'hem:91a2', 'deterministic', 100, stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (35, 19, 'email', 'hem:a2b3', 'deterministic', 100, stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.identity_signal VALUES (36, 20, 'email', 'hem:b3c4', 'deterministic', 100, stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (1, 1, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (2, 2, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (3, 3, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (4, 4, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (5, 5, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (6, 6, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (7, 7, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (8, 8, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (9, 9, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (10, 10, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (11, 11, 2, 'withdrawn', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (12, 12, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (13, 13, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (14, 14, 2, 'withdrawn', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (15, 15, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (16, 16, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (17, 17, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (18, 18, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (19, 19, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (20, 20, 2, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (21, 1, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (22, 3, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (23, 5, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (24, 9, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (25, 13, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (26, 15, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (27, 16, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (28, 19, 1, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (29, 8, 1, 'withdrawn', stringdate('2026-09-10')); INSERT INTO CustomerKG.kidehen.consent VALUES (30, 4, 3, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (31, 6, 3, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (32, 12, 3, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (33, 17, 3, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (34, 3, 4, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (35, 6, 4, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (36, 11, 4, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (37, 4, 5, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.consent VALUES (38, 12, 5, 'granted', stringdate('2026-08-01')); INSERT INTO CustomerKG.kidehen.offer VALUES (1, 'Friday reminder', 'reminder', 0, 4); INSERT INTO CustomerKG.kidehen.offer VALUES (2, 'Free side with any meal', 'incentive', 15, 3); INSERT INTO CustomerKG.kidehen.offer VALUES (3, 'Family bundle, 20 percent off', 'bundle-incentive', 20, 2); INSERT INTO CustomerKG.kidehen.offer VALUES (4, '10 percent off next order', 'incentive', 10, NULL); INSERT INTO CustomerKG.kidehen.offer VALUES (5, 'Dessert on us', 'incentive', 12, 5); INSERT INTO CustomerKG.kidehen.guardrail VALUES (1, 'Maximum discount depth 20 percent', 'discount-cap', 20, NULL); INSERT INTO CustomerKG.kidehen.guardrail VALUES (2, 'At most 3 contacts per 14 days', 'contact-frequency', 3, NULL); INSERT INTO CustomerKG.kidehen.guardrail VALUES (3, 'Contact only on a consented channel', 'consent-required', 1, NULL); INSERT INTO CustomerKG.kidehen.guardrail VALUES (4, 'Human approval above 15 percent discount', 'human-approval', 15, NULL); INSERT INTO CustomerKG.kidehen.guardrail VALUES (5, 'Bundle offers need human approval', 'human-approval', 1, 3); INSERT INTO CustomerKG.kidehen.campaign VALUES (1, 'Reactivate lapsed customers', 'reactivate lapsed customers', stringdate('2026-09-22')); INSERT INTO CustomerKG.kidehen.campaign VALUES (2, 'Test whether blanket discounts subsidise orders', 'avoid subsidising purchases that would have happened anyway', stringdate('2026-09-22')); INSERT INTO CustomerKG.kidehen.decision VALUES (1, 1, 1, 'treatment', 'send-reminder', 1, 1, stringdate('2026-09-22'), 'Usual Friday order missed once, usual order browsed on Thursday: a reminder is enough', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (2, 2, 1, 'treatment', 'send-reminder', 1, 2, stringdate('2026-09-22'), 'Missed one Friday; email consent granted, push not offered', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (3, 3, 1, 'treatment', 'send-incentive', 3, 1, stringdate('2026-09-22'), 'Six weeks lapsed, browsing a family meal without checkout: bundle incentive', 1); INSERT INTO CustomerKG.kidehen.decision VALUES (4, 4, 1, 'treatment', 'switch-channel', NULL, 5, stringdate('2026-09-22'), 'Ignored email twice: move to display retargeting with no offer', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (5, 5, 1, 'treatment', 'send-incentive', 2, 1, stringdate('2026-09-22'), 'Lapsing and price sensitive: free side', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (6, 6, 1, 'treatment', 'switch-channel', NULL, 4, stringdate('2026-09-22'), 'Repeated push without response: move to paid social with no offer', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (7, 7, 1, 'treatment', 'send-incentive', 4, 2, stringdate('2026-09-22'), 'Lapsing: ten percent off by email', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (8, 8, 1, 'treatment', 'suppress', NULL, NULL, stringdate('2026-09-22'), 'Four messages without response and push consent withdrawn: stop spend for now', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (9, 9, 1, 'treatment', 'send-incentive', 3, 1, stringdate('2026-09-22'), 'Lapsed gold member browsing a family meal: bundle incentive', 1); INSERT INTO CustomerKG.kidehen.decision VALUES (10, 10, 1, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (11, 11, 1, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (12, 12, 1, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (13, 13, 1, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (14, 14, 1, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (15, 15, 2, 'treatment', 'send-incentive', 4, 1, stringdate('2026-09-22'), 'Habitual Friday customer given the standard discount to test subsidy', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (16, 16, 2, 'treatment', 'send-incentive', 4, 1, stringdate('2026-09-22'), 'Habitual Saturday customer given the standard discount to test subsidy', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (17, 17, 2, 'treatment', 'send-incentive', 5, 3, stringdate('2026-09-22'), 'Habitual Friday customer given a dessert offer by SMS', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (18, 18, 2, 'treatment', 'send-incentive', 4, 2, stringdate('2026-09-22'), 'Habitual Sunday customer given the standard discount by email', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (19, 19, 2, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision VALUES (20, 20, 2, 'holdout', 'no-action', NULL, NULL, stringdate('2026-09-22'), 'Randomised holdout: no contact', 0); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (1, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (1, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (2, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (2, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (3, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (3, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (3, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (3, 4); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (3, 5); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (4, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (4, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (5, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (5, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (5, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (6, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (6, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (7, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (7, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (7, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (8, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (8, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (9, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (9, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (9, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (9, 4); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (9, 5); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (10, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (10, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (11, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (11, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (12, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (12, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (13, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (13, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (14, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (14, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (15, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (15, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (15, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (16, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (16, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (16, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (17, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (17, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (17, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (18, 1); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (18, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (18, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (19, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (19, 3); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (20, 2); INSERT INTO CustomerKG.kidehen.decision_guardrail VALUES (20, 3); INSERT INTO CustomerKG.kidehen.context_item VALUES (1, 1, 'customer', 'usual_order_day', 'Friday; skipped last week'); INSERT INTO CustomerKG.kidehen.context_item VALUES (2, 1, 'business', 'inventory', 'Weekly Friday Combo in stock'); INSERT INTO CustomerKG.kidehen.context_item VALUES (3, 1, 'decision', 'prior_offer', 'None in the last 30 days'); INSERT INTO CustomerKG.kidehen.context_item VALUES (4, 1, 'control', 'contact_frequency', '0 of 3 contacts used in 14 days'); INSERT INTO CustomerKG.kidehen.context_item VALUES (5, 3, 'customer', 'behaviour', 'Browsed a family meal six times without checkout'); INSERT INTO CustomerKG.kidehen.context_item VALUES (6, 3, 'business', 'margin', 'Family Meal Bundle margin is 31 percent'); INSERT INTO CustomerKG.kidehen.context_item VALUES (7, 3, 'decision', 'prior_offer', '10 percent off ignored five weeks ago'); INSERT INTO CustomerKG.kidehen.context_item VALUES (8, 3, 'control', 'approval', 'Discount of 20 percent needs human approval: granted'); INSERT INTO CustomerKG.kidehen.context_item VALUES (9, 8, 'customer', 'consent', 'Push consent withdrawn on 2026-09-10'); INSERT INTO CustomerKG.kidehen.context_item VALUES (10, 8, 'business', 'channel_constraint', 'Email contacts are capped at 3 per 14 days'); INSERT INTO CustomerKG.kidehen.context_item VALUES (11, 8, 'decision', 'prior_response', 'Four messages, no response'); INSERT INTO CustomerKG.kidehen.context_item VALUES (12, 8, 'control', 'action', 'Suppress and revisit after 30 days'); INSERT INTO CustomerKG.kidehen.context_item VALUES (13, 15, 'customer', 'lifecycle', 'Active, orders every Friday'); INSERT INTO CustomerKG.kidehen.context_item VALUES (14, 15, 'business', 'objective', 'Avoid subsidising habitual orders'); INSERT INTO CustomerKG.kidehen.context_item VALUES (15, 15, 'decision', 'prior_offer', '10 percent off redeemed three times'); INSERT INTO CustomerKG.kidehen.context_item VALUES (16, 15, 'control', 'discount_cap', '10 percent sits inside the 20 percent cap'); INSERT INTO CustomerKG.kidehen.context_item VALUES (17, 19, 'customer', 'lifecycle', 'Active, orders every Friday'); INSERT INTO CustomerKG.kidehen.context_item VALUES (18, 19, 'business', 'objective', 'Measure what happens with no offer'); INSERT INTO CustomerKG.kidehen.context_item VALUES (19, 19, 'decision', 'prior_offer', 'None'); INSERT INTO CustomerKG.kidehen.context_item VALUES (20, 19, 'control', 'holdout', 'Randomised no-contact arm'); INSERT INTO CustomerKG.kidehen.outcome VALUES (1, 1, 1, 24, 9, 0, 0, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (2, 2, 1, 22, 8, 0, 0, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (3, 3, 1, 48, 15, 0, 10, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (4, 4, 0, 0, 0, 2, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (5, 5, 1, 19, 7, 0, 3, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (6, 6, 0, 0, 0, 2, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (7, 7, 1, 26, 10, 0, 3, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (8, 8, 0, 0, 0, 0, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (9, 9, 1, 52, 16, 0, 10, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (10, 10, 1, 25, 9, 0, 0, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (11, 11, 0, 0, 0, 0, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (12, 12, 0, 0, 0, 0, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (13, 13, 1, 21, 8, 0, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (14, 14, 0, 0, 0, 0, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (15, 15, 1, 23, 9, 0, 2, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (16, 16, 1, 21, 8, 0, 2, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (17, 17, 1, 25, 10, 1, 3, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (18, 18, 0, 0, 0, 0, 0, 0, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (19, 19, 1, 24, 9, 0, 0, 1, stringdate('2026-10-06')); INSERT INTO CustomerKG.kidehen.outcome VALUES (20, 20, 1, 22, 8, 0, 0, 1, stringdate('2026-10-06')); -- Part 3: IRI classes (the SPARQL keyword and angle-bracket class names are required through isql) SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/channel/%d#this" (in channel_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/product/%d#this" (in product_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/customer/%d#this" (in customer_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/signal/%d#this" (in signal_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/consent/%d#this" (in consent_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/offer/%d#this" (in offer_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/guardrail/%d#this" (in guardrail_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/campaign/%d#this" (in campaign_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/decision/%d#this" (in decision_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/context/%d#this" (in item_id integer not null); SPARQL CREATE IRI CLASS "http://demo.openlinksw.com/CustomerKG/outcome/%d#this" (in outcome_id integer not null); -- Part 4: ontology and entailment rule set -- Load customerkg-ontology-claude_sonnet_5_5-1.ttl into the graph below before you rely on entailment: -- DB.DBA.TTLP(file_to_string_output('customerkg-ontology-claude_sonnet_5_5-1.ttl'), '', 'http://demo.openlinksw.com/schemas/CustomerKG/'); -- DB.DBA.rdfs_rule_set('urn:customerkg:inference', 'http://demo.openlinksw.com/schemas/CustomerKG/'); -- Part 5: the RDF View. Keep every mapping for the graph in one statement; a second statement replaces the first. SPARQL ALTER QUAD STORAGE virtrdf:DefaultQuadStorage FROM CustomerKG.kidehen.channel AS ch FROM CustomerKG.kidehen.product AS pr FROM CustomerKG.kidehen.customer AS cu FROM CustomerKG.kidehen.identity_signal AS sg FROM CustomerKG.kidehen.consent AS co FROM CustomerKG.kidehen.offer AS ofr FROM CustomerKG.kidehen.guardrail AS gr FROM CustomerKG.kidehen.campaign AS ca FROM CustomerKG.kidehen.decision AS de FROM CustomerKG.kidehen.decision_guardrail AS dg FROM CustomerKG.kidehen.context_item AS ci FROM CustomerKG.kidehen.outcome AS ou { GRAPH { (ch.channel_id) as virtrdf:CustomerKG-channel-type . (ch.channel_id) ch.channel_name as virtrdf:CustomerKG-channel-name . (ch.channel_id) ch.channel_kind as virtrdf:CustomerKG-channel-kind . (pr.product_id) as virtrdf:CustomerKG-product-type . (pr.product_id) pr.product_name as virtrdf:CustomerKG-product-name . (pr.product_id) pr.category as virtrdf:CustomerKG-product-category . (pr.product_id) pr.margin_pct as virtrdf:CustomerKG-product-margin . (cu.customer_id) as virtrdf:CustomerKG-customer-type . (cu.customer_id) cu.full_name as virtrdf:CustomerKG-customer-name . (cu.customer_id) cu.lifecycle_stage as virtrdf:CustomerKG-customer-lifecycle . (cu.customer_id) cu.loyalty_tier as virtrdf:CustomerKG-customer-tier . (cu.customer_id) cu.home_city as virtrdf:CustomerKG-customer-city . (cu.customer_id) cu.usual_order_day as virtrdf:CustomerKG-customer-day . (sg.signal_id) as virtrdf:CustomerKG-signal-type . (sg.signal_id) sg.signal_kind as virtrdf:CustomerKG-signal-kind . (sg.signal_id) sg.signal_value as virtrdf:CustomerKG-signal-value . (sg.signal_id) sg.match_method as virtrdf:CustomerKG-signal-method . (sg.signal_id) sg.confidence as virtrdf:CustomerKG-signal-confidence . (sg.signal_id) sg.seen_date as virtrdf:CustomerKG-signal-seen . (sg.signal_id) (sg.customer_id) where (^{sg.}^.customer_id is not null) as virtrdf:CustomerKG-signal-customer . (co.consent_id) as virtrdf:CustomerKG-consent-type . (co.consent_id) co.status as virtrdf:CustomerKG-consent-status . (co.consent_id) co.updated_date as virtrdf:CustomerKG-consent-updated . (co.consent_id) (co.customer_id) as virtrdf:CustomerKG-consent-customer . (co.consent_id) (co.channel_id) as virtrdf:CustomerKG-consent-channel . (ofr.offer_id) as virtrdf:CustomerKG-offer-type . (ofr.offer_id) ofr.offer_name as virtrdf:CustomerKG-offer-name . (ofr.offer_id) ofr.offer_kind as virtrdf:CustomerKG-offer-kind . (ofr.offer_id) ofr.discount_pct as virtrdf:CustomerKG-offer-discount . (ofr.offer_id) (ofr.product_id) where (^{ofr.}^.product_id is not null) as virtrdf:CustomerKG-offer-product . (gr.guardrail_id) as virtrdf:CustomerKG-guardrail-type . (gr.guardrail_id) gr.rule_name as virtrdf:CustomerKG-guardrail-name . (gr.guardrail_id) gr.rule_kind as virtrdf:CustomerKG-guardrail-kind . (gr.guardrail_id) gr.limit_value as virtrdf:CustomerKG-guardrail-limit . (gr.guardrail_id) (gr.offer_id) where (^{gr.}^.offer_id is not null) as virtrdf:CustomerKG-guardrail-offer . (ca.campaign_id) as virtrdf:CustomerKG-campaign-type . (ca.campaign_id) ca.campaign_name as virtrdf:CustomerKG-campaign-name . (ca.campaign_id) ca.goal as virtrdf:CustomerKG-campaign-goal . (ca.campaign_id) ca.start_date as virtrdf:CustomerKG-campaign-start . (de.decision_id) as virtrdf:CustomerKG-decision-type . (de.decision_id) de.arm as virtrdf:CustomerKG-decision-arm . (de.decision_id) de.action_kind as virtrdf:CustomerKG-decision-action . (de.decision_id) de.decided_date as virtrdf:CustomerKG-decision-date . (de.decision_id) de.rationale as virtrdf:CustomerKG-decision-rationale . (de.decision_id) de.approved_by_human as virtrdf:CustomerKG-decision-approved . (de.decision_id) (de.customer_id) as virtrdf:CustomerKG-decision-customer . (de.decision_id) (de.campaign_id) as virtrdf:CustomerKG-decision-campaign . (de.decision_id) (de.offer_id) where (^{de.}^.offer_id is not null) as virtrdf:CustomerKG-decision-offer . (de.decision_id) (de.channel_id) where (^{de.}^.channel_id is not null) as virtrdf:CustomerKG-decision-channel . (dg.decision_id) (dg.guardrail_id) as virtrdf:CustomerKG-decision-guardrail . (ci.item_id) as virtrdf:CustomerKG-context-type . (ci.item_id) ci.context_type as virtrdf:CustomerKG-context-kind . (ci.item_id) ci.context_key as virtrdf:CustomerKG-context-key . (ci.item_id) ci.context_value as virtrdf:CustomerKG-context-value . (ci.item_id) (ci.decision_id) as virtrdf:CustomerKG-context-decision . (ou.outcome_id) as virtrdf:CustomerKG-outcome-type . (ou.outcome_id) ou.ordered as virtrdf:CustomerKG-outcome-ordered . (ou.outcome_id) ou.revenue_usd as virtrdf:CustomerKG-outcome-revenue . (ou.outcome_id) ou.margin_usd as virtrdf:CustomerKG-outcome-margin . (ou.outcome_id) ou.media_cost_usd as virtrdf:CustomerKG-outcome-media . (ou.outcome_id) ou.discount_cost_usd as virtrdf:CustomerKG-outcome-discount . (ou.outcome_id) ou.repeat_visit_30d as virtrdf:CustomerKG-outcome-repeat . (ou.outcome_id) ou.window_end as virtrdf:CustomerKG-outcome-window . (ou.outcome_id) (ou.decision_id) as virtrdf:CustomerKG-outcome-decision . } } ; -- Part 6: access. The view inherits the SQL privileges of its tables. GRANT SELECT ON CustomerKG.kidehen.channel TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.channel TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.channel TO "demo"; GRANT SELECT ON CustomerKG.kidehen.channel TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.product TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.product TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.product TO "demo"; GRANT SELECT ON CustomerKG.kidehen.product TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.customer TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.customer TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.customer TO "demo"; GRANT SELECT ON CustomerKG.kidehen.customer TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.identity_signal TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.identity_signal TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.identity_signal TO "demo"; GRANT SELECT ON CustomerKG.kidehen.identity_signal TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.consent TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.consent TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.consent TO "demo"; GRANT SELECT ON CustomerKG.kidehen.consent TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.offer TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.offer TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.offer TO "demo"; GRANT SELECT ON CustomerKG.kidehen.offer TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.guardrail TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.guardrail TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.guardrail TO "demo"; GRANT SELECT ON CustomerKG.kidehen.guardrail TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.campaign TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.campaign TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.campaign TO "demo"; GRANT SELECT ON CustomerKG.kidehen.campaign TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.decision TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.decision TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.decision TO "demo"; GRANT SELECT ON CustomerKG.kidehen.decision TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.decision_guardrail TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.decision_guardrail TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.decision_guardrail TO "demo"; GRANT SELECT ON CustomerKG.kidehen.decision_guardrail TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.context_item TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.context_item TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.context_item TO "demo"; GRANT SELECT ON CustomerKG.kidehen.context_item TO "vdb"; GRANT SELECT ON CustomerKG.kidehen.outcome TO "SPARQL"; GRANT SELECT ON CustomerKG.kidehen.outcome TO PUBLIC; GRANT SELECT ON CustomerKG.kidehen.outcome TO "demo"; GRANT SELECT ON CustomerKG.kidehen.outcome TO "vdb"; -- Part 7: URL rewrite rules, generated by RDFVIEW_GENERATE_DATA_RULES with iri_path_segment=CustomerKG and include_ontology_rules=1. -- Without them the entity IRIs return 404. Run through isql or SELECT exec() one statement at a time. DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_rule2', 1, '(/[^#]*)', vector('path'), 1, '/sparql?query=DESCRIBE+%%3Chttp%%3A//^{URIQADefaultHost}^%U%%23this%%3E+FROM+%%3Chttp%%3A//^{URIQADefaultHost}^/CustomerKG%%23%%3E&format=%U', vector('path', '*accept*'), null, '(text/rdf.n3)|(application/rdf.xml)|(text/n3)|(application/json)|(text/turtle)', 2, null ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_rule4', 1, '/CustomerKG/stat([^#]*)', vector('path'), 1, '/sparql?query=DESCRIBE+%%3Chttp%%3A//^{URIQADefaultHost}^/CustomerKG/stat%%23%%3E+%%3Fo+FROM+%%3Chttp%%3A//^{URIQADefaultHost}^/CustomerKG%%23%%3E+WHERE+{+%%3Chttp%%3A//^{URIQADefaultHost}^/CustomerKG/stat%%23%%3E+%%3Fp+%%3Fo+}&format=%U', vector('*accept*'), null, '(text/rdf.n3)|(application/rdf.xml)|(text/n3)|(application/json)|(text/turtle)', 2, null ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_rule6', 1, '/CustomerKG/objects/([^#]*)', vector('path'), 1, '/sparql?query=DESCRIBE+%%3Chttp%%3A//^{URIQADefaultHost}^/CustomerKG/objects/%U%%3E+FROM+%%3Chttp%%3A//^{URIQADefaultHost}^/CustomerKG%%23%%3E&format=%U', vector('path', '*accept*'), null, '(text/rdf.n3)|(application/rdf.xml)|(text/n3)|(application/json)|(text/turtle)', 2, null ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_rule1', 1, '([^#]*)', vector('path'), 1, '/describe/?url=http%%3A//^{URIQADefaultHost}^%U%%23this&graph=http%%3A//^{URIQADefaultHost}^/CustomerKG%%23&distinct=0', vector('path'), null, null, 2, 303 ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_rule7', 1, '/CustomerKG/stat([^#]*)', vector('path'), 1, '/describe/?url=http%%3A//^{URIQADefaultHost}^/CustomerKG/stat%%23&graph=http%%3A//^{URIQADefaultHost}^/CustomerKG%%23', vector('path'), null, null, 2, 303 ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_rule5', 1, '/CustomerKG/objects/(.*)', vector('path'), 1, '/services/rdf/object.binary?path=%%2FCustomerKG%%2Fobjects%%2F%U&accept=%U', vector('path', '*accept*'), null, null, 2, null ); DB.DBA.URLREWRITE_CREATE_RULELIST ( 'customerkg_rule_list1', 1, vector ( 'customerkg_rule1', 'customerkg_rule7', 'customerkg_rule5', 'customerkg_rule2', 'customerkg_rule4', 'customerkg_rule6')); DB.DBA.VHOST_REMOVE (lpath=>'/CustomerKG'); DB.DBA.VHOST_DEFINE (lpath=>'/CustomerKG', ppath=>'/', vsp_user=>'dba', is_dav=>0, is_brws=>0, opts=>vector ('url_rewrite', 'customerkg_rule_list1') ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_owl_rule2', 1, '(/[^#]*)', vector('path'), 1, '/sparql?query=DESCRIBE+%%3Chttp%%3A//^{URIQADefaultHost}^%U%%3E+FROM+%%3Chttp%%3A//^{URIQADefaultHost}^/schemas/CustomerKG%%23%%3E&format=%U', vector('path', '*accept*'), null, '(text/rdf.n3)|(application/rdf.xml)|(text/n3)|(application/json)|(text/turtle)', 2, null ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'customerkg_owl_rule1', 1, '([^#]*)', vector('path'), 1, '/describe/?url=http://^{URIQADefaultHost}^%U', vector('path'), null, null, 2, 303 ); DB.DBA.URLREWRITE_CREATE_RULELIST ( 'customerkg_owl_rule_list1', 1, vector ( 'customerkg_owl_rule1', 'customerkg_owl_rule2')); DB.DBA.VHOST_REMOVE (lpath=>'/schemas/CustomerKG'); DB.DBA.VHOST_DEFINE (lpath=>'/schemas/CustomerKG', ppath=>'/', vsp_user=>'dba', is_dav=>0, is_brws=>0, opts=>vector ('url_rewrite', 'customerkg_owl_rule_list1') ); -- Part 8: identity reconciliation graph. Inverse-functional-property and owl:sameAs reasoning over a physical graph that -- carries facts derived from the view plus records from other systems. Query it with the pragmas shown in the page. -- 1. Vocabulary: declare the identifying property inverse functional, in its own graph DB.DBA.TTLP(file_to_string_output('customerkg-identity-vocabulary-claude_sonnet_5_5-1.ttl'), '', 'http://demo.openlinksw.com/schemas/CustomerKG/identity/'); -- The Turtle loaded by that call: @prefix ckg: . @prefix owl: . @prefix rdfs: . @prefix schema: . @prefix xsd: . a owl:Ontology ; rdfs:label "CustomerKG identity reconciliation vocabulary"@en . ckg:emailHash a owl:InverseFunctionalProperty, owl:DatatypeProperty ; rdfs:isDefinedBy ; rdfs:label "email hash"@en ; rdfs:comment "A pseudonymous hash of an email address. Two records that carry the same hash describe the same person, so the property is declared inverse functional and a reasoner derives owl:sameAs between them."@en ; rdfs:domain schema:Person ; rdfs:range xsd:string . -- 2. Rule set: derive reasoning rules from that vocabulary DB.DBA.rdfs_rule_set('urn:customerkg:identity-inference', 'http://demo.openlinksw.com/schemas/CustomerKG/identity/'); -- 3. Identity graph, part one: facts derived from the live RDF View (nothing is retyped) SPARQL PREFIX ckg: PREFIX schema: INSERT INTO GRAPH { ?c ckg:emailHash ?v } WHERE { GRAPH { ?s a ckg:IdentitySignal ; ckg:signalKind "email" ; ckg:signalValue ?v ; ckg:resolvesTo ?c } }; SPARQL PREFIX ckg: PREFIX schema: INSERT INTO GRAPH { ?c a schema:Person ; schema:name ?n } WHERE { GRAPH { ?c a ckg:Customer ; schema:name ?n } }; -- 4. Identity graph, part two: records from other systems, one explicit owl:sameAs, one record that matches nobody SPARQL PREFIX ckg: PREFIX schema: PREFIX owl: INSERT DATA INTO GRAPH { a schema:Person ; schema:name "A. Quinn (CRM export)" ; ckg:emailHash "hem:a1f3" . a schema:Person ; schema:name "Avery Q. (app profile)" ; ckg:emailHash "hem:a1f3" . a schema:Person ; schema:name "B. Moreno (CRM export)" ; ckg:emailHash "hem:b2c4" . a schema:Person ; schema:name "Unmatched (CRM export)" ; ckg:emailHash "hem:ffff" . a schema:Person ; schema:name "Loyalty member LY-10001" ; owl:sameAs . };