-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathseed.sql
More file actions
133 lines (120 loc) · 8.11 KB
/
Copy pathseed.sql
File metadata and controls
133 lines (120 loc) · 8.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
-- Seed: a small fictional music scene.
--
-- Everything here is synthetic. Names are invented; the graph shape is chosen
-- to exercise the patterns: a known shortest path, a decoy longer path, a few
-- near-duplicate names for entity resolution, and six months of activity for
-- momentum windows.
--
-- Node ids are fixed so pattern files can assert exact results.
-- ---------------------------------------------------------------------------
-- Deterministic pseudo-embeddings.
--
-- Real systems store model-produced vectors. For a self-contained demo we
-- derive a stable vector from a seed string: same seed → same vector, and a
-- `jitter` parameter produces a *near*-identical vector — which is exactly how
-- two spellings of the same real-world entity behave under a real model.
-- ---------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION pseudo_embedding(seed text, jitter real DEFAULT 0)
RETURNS vector
LANGUAGE sql IMMUTABLE AS $$
SELECT ('[' || string_agg(
((hashtext(seed || ':' || i) % 1000)::real / 1000.0
+ jitter * ((hashtext('j:' || seed || ':' || i) % 100)::real / 100.0)
)::text, ',' ORDER BY i)
|| ']')::vector(384)
FROM generate_series(1, 384) AS i;
$$;
-- ---------------------------------------------------------------------------
-- Named cast (fixed ids used by the pattern files)
-- ---------------------------------------------------------------------------
INSERT INTO nodes (id, kind, name, name_embedding) VALUES
-- artists
('00000000-0000-0000-0000-000000000001', 'person', 'Nova Reyes', pseudo_embedding('Nova Reyes')),
('00000000-0000-0000-0000-000000000002', 'person', 'Cassette Ghost', pseudo_embedding('Cassette Ghost')),
('00000000-0000-0000-0000-000000000003', 'person', 'Mira Solano', pseudo_embedding('Mira Solano')),
('00000000-0000-0000-0000-000000000004', 'person', 'DJ Marrow', pseudo_embedding('DJ Marrow')),
('00000000-0000-0000-0000-000000000005', 'person', 'Low Tide Collective', pseudo_embedding('Low Tide Collective')),
('00000000-0000-0000-0000-000000000006', 'person', 'Iris Vann', pseudo_embedding('Iris Vann')),
-- near-duplicates of 2 and 4: same underlying entity, different spelling.
-- Embeddings are jittered copies of the original — near-identical, as a
-- real model would produce.
('00000000-0000-0000-0000-000000000012', 'person', 'Casette Ghost', pseudo_embedding('Cassette Ghost', 0.02)),
('00000000-0000-0000-0000-000000000014', 'person', 'Marrow', pseudo_embedding('DJ Marrow', 0.03)),
-- venues / orgs
('00000000-0000-0000-0000-000000000021', 'venue', 'The Velvet Room', pseudo_embedding('The Velvet Room')),
('00000000-0000-0000-0000-000000000022', 'venue', 'Warehouse North', pseudo_embedding('Warehouse North')),
('00000000-0000-0000-0000-000000000023', 'org', 'Night Signal Records', pseudo_embedding('Night Signal Records')),
-- works
('00000000-0000-0000-0000-000000000031', 'work', 'Glasshouse EP', pseudo_embedding('Glasshouse EP')),
('00000000-0000-0000-0000-000000000032', 'work', 'Midnight Protocol', pseudo_embedding('Midnight Protocol'));
-- Filler population: 40 session artists, deterministic names.
INSERT INTO nodes (id, kind, name, name_embedding)
SELECT ('00000000-0000-0000-0001-' || lpad(i::text, 12, '0'))::uuid,
'person',
'Session Artist ' || lpad(i::text, 2, '0'),
pseudo_embedding('Session Artist ' || i)
FROM generate_series(1, 40) AS i;
-- ---------------------------------------------------------------------------
-- Edges.
--
-- The traversal story (patterns 01/02):
-- Nova Reyes ↔ Cassette Ghost ↔ The Velvet Room ↔ Mira Solano (3 hops)
-- plus a decoy 5-hop route Nova → DJ Marrow → Warehouse North →
-- Low Tide Collective → Iris Vann → Mira Solano, so shortest-path has to
-- actually pick the short one.
-- ---------------------------------------------------------------------------
INSERT INTO edges (src, tgt, kind, direction, confidence) VALUES
-- short route
('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002', 'collaborated_with', 'bidirectional', 0.95),
('00000000-0000-0000-0000-000000000002', '00000000-0000-0000-0000-000000000021', 'performed_at', 'directed', 0.90),
('00000000-0000-0000-0000-000000000003', '00000000-0000-0000-0000-000000000021', 'performed_at', 'directed', 0.90),
-- decoy long route
('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000004', 'collaborated_with', 'bidirectional', 0.80),
('00000000-0000-0000-0000-000000000004', '00000000-0000-0000-0000-000000000022', 'performed_at', 'directed', 0.85),
('00000000-0000-0000-0000-000000000005', '00000000-0000-0000-0000-000000000022', 'performed_at', 'directed', 0.70),
('00000000-0000-0000-0000-000000000005', '00000000-0000-0000-0000-000000000006', 'collaborated_with', 'bidirectional', 0.75),
('00000000-0000-0000-0000-000000000006', '00000000-0000-0000-0000-000000000003', 'collaborated_with', 'bidirectional', 0.85),
-- label / works context
('00000000-0000-0000-0000-000000000023', '00000000-0000-0000-0000-000000000002', 'manages', 'directed', 0.90),
('00000000-0000-0000-0000-000000000002', '00000000-0000-0000-0000-000000000031', 'created', 'directed', 1.00),
('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000031', 'created', 'directed', 1.00),
('00000000-0000-0000-0000-000000000004', '00000000-0000-0000-0000-000000000032', 'created', 'directed', 1.00);
-- Filler edges: each session artist collaborates with the next two (a chain
-- with local clustering), and every fifth one performed at Warehouse North.
INSERT INTO edges (src, tgt, kind, direction, confidence)
SELECT ('00000000-0000-0000-0001-' || lpad(i::text, 12, '0'))::uuid,
('00000000-0000-0000-0001-' || lpad((i + o)::text, 12, '0'))::uuid,
'collaborated_with', 'bidirectional', 0.5 + (i % 5) / 10.0
FROM generate_series(1, 38) AS i, (VALUES (1), (2)) AS hop(o)
WHERE i + o <= 40;
INSERT INTO edges (src, tgt, kind, direction, confidence)
SELECT ('00000000-0000-0000-0001-' || lpad(i::text, 12, '0'))::uuid,
'00000000-0000-0000-0000-000000000022', 'performed_at', 'directed', 0.8
FROM generate_series(5, 40, 5) AS i;
-- Bridge the filler chain into the named cast so the graph is connected.
INSERT INTO edges (src, tgt, kind, direction, confidence) VALUES
('00000000-0000-0000-0001-000000000001', '00000000-0000-0000-0000-000000000005', 'collaborated_with', 'bidirectional', 0.6);
-- ---------------------------------------------------------------------------
-- Events: six months of activity, denser in the last 30 days for some nodes
-- so momentum trends differ (pattern 06). Timestamps are relative to now(),
-- so windows behave the same whenever you run the demo.
-- ---------------------------------------------------------------------------
-- Cassette Ghost: accelerating (2/mo historically, ~2/wk in the last month).
INSERT INTO events (node_id, kind, weight, created_at)
SELECT '00000000-0000-0000-0000-000000000002', 'release', 1.0, now() - (i || ' days')::interval
FROM unnest(ARRAY[2, 6, 11, 17, 24, 29, 44, 75, 106, 137, 168]) AS i;
-- Mira Solano: steady (one event a month).
INSERT INTO events (node_id, kind, weight, created_at)
SELECT '00000000-0000-0000-0000-000000000003', 'show', 1.0, now() - (i * 30 || ' days')::interval
FROM generate_series(0, 5) AS i;
-- DJ Marrow: cooling off (active months 2-6, silent since).
INSERT INTO events (node_id, kind, weight, created_at)
SELECT '00000000-0000-0000-0000-000000000004', 'show', 1.0, now() - (i || ' days')::interval
FROM unnest(ARRAY[45, 60, 74, 90, 110, 130, 155, 170]) AS i;
-- Background noise: every session artist has a smattering of events.
INSERT INTO events (node_id, kind, weight, created_at)
SELECT ('00000000-0000-0000-0001-' || lpad(i::text, 12, '0'))::uuid,
'show', 1.0,
now() - ((i * 13 + s * 41) % 180 || ' days')::interval
FROM generate_series(1, 40) AS i, generate_series(1, 3) AS s;
ANALYZE nodes; ANALYZE edges; ANALYZE events;