File size: 8,371 Bytes
7cc8e29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
-- ============================================================
-- ALGORITHM_REGISTRY β€” The Multi-Root Algorithm Layer
-- ============================================================
-- Level 2.5 in the computational fabric.
-- An ALGORITHM is a named root-set that fires together across
-- one or more ayat to execute a single operational pattern.
--
-- Q28:4 is ONE algorithm (Pharaoh extraction).
-- Q63:1-11 is ONE algorithm (munafiq deception).
-- Q12:57-66 is ONE algorithm (Yusuf kayl distribution).
-- The Radhanite operation runs MULTIPLE algorithms simultaneously.
--
-- This replaces the root-at-a-time fabric scan with a
-- multi-root fabric scan keyed on named algorithms.
-- ============================================================

-- ============================================================
-- 1. algorithm_registry β€” master metadata
-- ============================================================
CREATE TABLE IF NOT EXISTS algorithm_registry (
    algo_id           TEXT PRIMARY KEY,       -- ALG-PHARAOH-EXTRACTION
    algo_name         TEXT NOT NULL,          -- human-readable name
    algo_class        TEXT NOT NULL,          -- OPERATOR | NARRATIVE | BINARY_PAIR | REFRAIN | DESCRIPTION | ECONOMIC | ESCHATOLOGICAL
    description       TEXT,                   -- structural description (no etymologies)
    primary_ayah      TEXT,                   -- canonical source (Q28:4)
    root_count        INTEGER DEFAULT 0,      -- auto-populated from algorithm_root_map
    ayah_count        INTEGER DEFAULT 0,      -- auto-populated from algorithm_ayah_map
    surah_count       INTEGER DEFAULT 0,      -- auto-populated from algorithm_ayah_map
    cross_refs        TEXT,                   -- JSON array of related algo_ids and table refs
    status            TEXT DEFAULT 'DRAFT',   -- DRAFT | VERIFIED | SEALED
    created_date      TEXT DEFAULT (datetime('now')),
    notes             TEXT,
    quf_q             TEXT,
    quf_u             TEXT,
    quf_f             TEXT,
    quf_pass          TEXT,
    quf_date          TEXT,
    quf_token         TEXT,
    CHECK (algo_id LIKE 'ALG-%'),
    CHECK (algo_class IN ('OPERATOR','NARRATIVE','BINARY_PAIR','REFRAIN','DESCRIPTION','ECONOMIC','ESCHATOLOGICAL','MORPHOLOGICAL'))
);

CREATE INDEX IF NOT EXISTS idx_algo_class ON algorithm_registry(algo_class);
CREATE INDEX IF NOT EXISTS idx_algo_status ON algorithm_registry(status);

-- ============================================================
-- 2. algorithm_root_map β€” N:M link (algo ↔ roots)
-- ============================================================
CREATE TABLE IF NOT EXISTS algorithm_root_map (
    map_id            INTEGER PRIMARY KEY AUTOINCREMENT,
    algo_id           TEXT NOT NULL,
    root_letters      TEXT NOT NULL,          -- must exist in roots table
    role              TEXT DEFAULT 'PRIMARY', -- PRIMARY | SUPPORT | BINARY_A | BINARY_B | INVERSION
    token_count       INTEGER,                -- auto-filled from quran_word_roots at insert time
    notes             TEXT,
    created_date      TEXT DEFAULT (datetime('now')),
    UNIQUE (algo_id, root_letters),
    FOREIGN KEY (algo_id) REFERENCES algorithm_registry(algo_id) ON DELETE CASCADE,
    CHECK (role IN ('PRIMARY','SUPPORT','BINARY_A','BINARY_B','INVERSION','OBJECT','INSTRUMENT'))
);

CREATE INDEX IF NOT EXISTS idx_arm_algo ON algorithm_root_map(algo_id);
CREATE INDEX IF NOT EXISTS idx_arm_root ON algorithm_root_map(root_letters);

-- ============================================================
-- 3. algorithm_ayah_map β€” N:M link (algo ↔ ayat)
-- ============================================================
CREATE TABLE IF NOT EXISTS algorithm_ayah_map (
    map_id            INTEGER PRIMARY KEY AUTOINCREMENT,
    algo_id           TEXT NOT NULL,
    surah             INTEGER NOT NULL,
    ayah_start        INTEGER NOT NULL,
    ayah_end          INTEGER,                -- NULL = single ayah
    is_primary        INTEGER DEFAULT 0,      -- 1 = canonical source
    instance_note     TEXT,                   -- e.g. "Pharaoh instance" vs "Rome instance"
    created_date      TEXT DEFAULT (datetime('now')),
    FOREIGN KEY (algo_id) REFERENCES algorithm_registry(algo_id) ON DELETE CASCADE,
    CHECK (surah BETWEEN 1 AND 114),
    CHECK (ayah_start > 0),
    CHECK (ayah_end IS NULL OR ayah_end >= ayah_start)
);

CREATE INDEX IF NOT EXISTS idx_aam_algo ON algorithm_ayah_map(algo_id);
CREATE INDEX IF NOT EXISTS idx_aam_surah ON algorithm_ayah_map(surah);
CREATE INDEX IF NOT EXISTS idx_aam_primary ON algorithm_ayah_map(is_primary) WHERE is_primary = 1;

-- ============================================================
-- TRIGGERS β€” auto-populate counts + contamination shield
-- ============================================================

-- Update root_count on algorithm_registry when algorithm_root_map changes
CREATE TRIGGER IF NOT EXISTS trg_arm_insert_count
AFTER INSERT ON algorithm_root_map
BEGIN
    UPDATE algorithm_registry
    SET root_count = (SELECT COUNT(*) FROM algorithm_root_map WHERE algo_id = NEW.algo_id)
    WHERE algo_id = NEW.algo_id;
END;

CREATE TRIGGER IF NOT EXISTS trg_arm_delete_count
AFTER DELETE ON algorithm_root_map
BEGIN
    UPDATE algorithm_registry
    SET root_count = (SELECT COUNT(*) FROM algorithm_root_map WHERE algo_id = OLD.algo_id)
    WHERE algo_id = OLD.algo_id;
END;

-- Update ayah_count + surah_count on algorithm_registry when algorithm_ayah_map changes
CREATE TRIGGER IF NOT EXISTS trg_aam_insert_count
AFTER INSERT ON algorithm_ayah_map
BEGIN
    UPDATE algorithm_registry
    SET
        ayah_count = (
            SELECT COALESCE(SUM(COALESCE(ayah_end, ayah_start) - ayah_start + 1), 0)
            FROM algorithm_ayah_map WHERE algo_id = NEW.algo_id
        ),
        surah_count = (
            SELECT COUNT(DISTINCT surah) FROM algorithm_ayah_map WHERE algo_id = NEW.algo_id
        )
    WHERE algo_id = NEW.algo_id;
END;

CREATE TRIGGER IF NOT EXISTS trg_aam_delete_count
AFTER DELETE ON algorithm_ayah_map
BEGIN
    UPDATE algorithm_registry
    SET
        ayah_count = (
            SELECT COALESCE(SUM(COALESCE(ayah_end, ayah_start) - ayah_start + 1), 0)
            FROM algorithm_ayah_map WHERE algo_id = OLD.algo_id
        ),
        surah_count = (
            SELECT COUNT(DISTINCT surah) FROM algorithm_ayah_map WHERE algo_id = OLD.algo_id
        )
    WHERE algo_id = OLD.algo_id;
END;

-- Auto-fill token_count on algorithm_root_map insert (from quran_word_roots)
CREATE TRIGGER IF NOT EXISTS trg_arm_fill_tokens
AFTER INSERT ON algorithm_root_map
FOR EACH ROW
WHEN NEW.token_count IS NULL
BEGIN
    UPDATE algorithm_root_map
    SET token_count = (SELECT COUNT(*) FROM quran_word_roots WHERE root = NEW.root_letters)
    WHERE map_id = NEW.map_id;
END;

-- Contamination shield β€” block banned terms in description/notes
CREATE TRIGGER IF NOT EXISTS trg_algo_contamination_desc
BEFORE INSERT ON algorithm_registry
FOR EACH ROW
WHEN NEW.description IS NOT NULL AND (
    LOWER(NEW.description) LIKE '%borrowed from%' OR
    LOWER(NEW.description) LIKE '%loan from%' OR
    LOWER(NEW.description) LIKE '%loanword%' OR
    LOWER(NEW.description) LIKE '%cognate with%' OR
    LOWER(NEW.description) LIKE '%semitic%' OR
    LOWER(NEW.description) LIKE '%proto-indo-european%' OR
    LOWER(NEW.description) LIKE '%from greek%' OR
    LOWER(NEW.description) LIKE '%from latin%' OR
    LOWER(NEW.description) LIKE '%from sanskrit%' OR
    LOWER(NEW.description) LIKE '%from persian%' OR
    LOWER(NEW.description) LIKE '%farsi%'
)
BEGIN
    SELECT RAISE(ABORT, 'CONTAMINATION: banned term in algorithm description');
END;

CREATE TRIGGER IF NOT EXISTS trg_algo_contamination_notes
BEFORE INSERT ON algorithm_registry
FOR EACH ROW
WHEN NEW.notes IS NOT NULL AND (
    LOWER(NEW.notes) LIKE '%borrowed from%' OR
    LOWER(NEW.notes) LIKE '%loan from%' OR
    LOWER(NEW.notes) LIKE '%loanword%' OR
    LOWER(NEW.notes) LIKE '%cognate with%' OR
    LOWER(NEW.notes) LIKE '%semitic%' OR
    LOWER(NEW.notes) LIKE '%proto-indo-european%' OR
    LOWER(NEW.notes) LIKE '%from greek%' OR
    LOWER(NEW.notes) LIKE '%from latin%' OR
    LOWER(NEW.notes) LIKE '%from sanskrit%' OR
    LOWER(NEW.notes) LIKE '%from persian%' OR
    LOWER(NEW.notes) LIKE '%farsi%'
)
BEGIN
    SELECT RAISE(ABORT, 'CONTAMINATION: banned term in algorithm notes');
END;