code wiki / _hdl_build / nx_seg_pos_gate.nx
nx_seg_pos_gate.nx source
↩ module page · 106 lines · 5458 B
1// nx_seg_pos_gate.nx -- KAT gate for the PHRASE rung's store layer: the NXQ1 positions sidecar
2// (builder round-trip), ss_phrase adjacency/order/negatives across MULTIPLE segments, the graceful
3// DEGRADE on a sidecar-less (pre-phrase) segment, and the COMPACTION UPGRADE (ss_compact rebuilds
4// through ss_write_seg -> the merged segment carries a fresh sidecar -> phrase goes exact again).
5// Runs against /tmp prefixes (wiped per boot -> deterministic, zero tree pollution). license_tier: ORIGINAL
6import "nx_seg_store.nx"
7
8func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
9func g_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
10func g_num(v: i64) -> i64 {
11 let bb: *u8 = sys_mmap(28); var m: i64 = v
12 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
13 let t: *u8 = sys_mmap(28); var k: i64 = 0
14 if m == 0 { t[0] = 48 as u8; k = 1 }
15 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
16 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
17 sys_write(1, bb, k); return 0
18}
19func g_unlink(path: *u8) -> i64 { return __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) }
20func g_check(name: *u8, cond: i64, pass: *i64, total: *i64) -> i64 {
21 total[0] = total[0] + 1
22 g_puts(name)
23 if cond == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n" as *u8) } else { g_puts(" FAIL\n" as *u8) }
24 return 0
25}
26// run a phrase over terms given as up-to-3 null-terminated strings; returns cnt, exact via ebox
27func g_phrase2(prefix: *u8, h: *i64, a: *u8, b: *u8, c: *u8, ebox: *i64) -> i64 {
28 let terms: *i64 = sys_mmap(8 * 8) as *i64
29 terms[0] = a as i64
30 terms[1] = b as i64
31 var n: i64 = 2
32 if (c as i64) != 0 { terms[2] = c as i64; n = 3 }
33 let kp: *i64 = sys_mmap(8 * 64) as *i64
34 let kl: *i64 = sys_mmap(8 * 64) as *i64
35 return ss_phrase(prefix, h, terms, n, kp, kl, 64, ebox)
36}
37
38func main() -> i64 {
39 g_puts("=== nx_seg_pos gate (NXQ1 positions sidecar + ss_phrase; degrade + compaction upgrade) ===\n" as *u8)
40 let pass: *i64 = sys_mmap(16) as *i64; pass[0] = 0
41 let total: *i64 = sys_mmap(16) as *i64; total[0] = 0
42 let prefix: *u8 = "/tmp/posgate-" as *u8
43
44 let w1: *i64 = ss_begin()
45 ss_add(w1, 1, "doc:1" as *u8, "alpha beta gamma" as *u8, 16)
46 ss_add(w1, 1, "doc:2" as *u8, "beta alpha" as *u8, 10)
47 ss_add(w1, 1, "doc:3" as *u8, "alpha xx beta" as *u8, 13)
48 ss_commit(prefix, w1, 1)
49 let w2: *i64 = ss_begin()
50 ss_add(w2, 1, "doc:4" as *u8, "alpha beta again" as *u8, 16)
51 ss_commit(prefix, w2, 2)
52
53 let h: *i64 = ss_open(prefix)
54 let ebox: *i64 = sys_mmap(16) as *i64
55
56 // T1: adjacency across BOTH segments; exact everywhere
57 let n1: i64 = g_phrase2(prefix, h, "alpha" as *u8, "beta" as *u8, 0 as *u8, ebox)
58 var t1: i64 = 0
59 if n1 == 2 { if ebox[0] == 1 { t1 = 1 } }
60 g_check("T1 [alpha beta] -> 2 docs (1,4), exact" as *u8, t1, pass, total)
61
62 // T2: ORDER matters -- the reversed phrase matches only doc:2
63 let n2: i64 = g_phrase2(prefix, h, "beta" as *u8, "alpha" as *u8, 0 as *u8, ebox)
64 var t2: i64 = 0
65 if n2 == 1 { if ebox[0] == 1 { t2 = 1 } }
66 g_check("T2 [beta alpha] -> 1 doc (2)" as *u8, t2, pass, total)
67
68 // T3: 3-term ladder
69 let n3: i64 = g_phrase2(prefix, h, "alpha" as *u8, "beta" as *u8, "gamma" as *u8, ebox)
70 g_check("T3 [alpha beta gamma] -> 1 doc (1)" as *u8, (n3 == 1) as i64, pass, total)
71
72 // T4: an intervening INDEXED token breaks adjacency (doc:3 alpha xx beta)
73 let n4: i64 = g_phrase2(prefix, h, "alpha" as *u8, "xx" as *u8, 0 as *u8, ebox)
74 g_check("T4 [alpha xx] -> 1 doc (3; 2-char filler IS indexed)" as *u8, (n4 == 1) as i64, pass, total)
75
76 // T5 NEG: terms present, order absent everywhere
77 let n5: i64 = g_phrase2(prefix, h, "gamma" as *u8, "alpha" as *u8, 0 as *u8, ebox)
78 g_check("T5 NEG [gamma alpha] -> 0" as *u8, (n5 == 0) as i64, pass, total)
79
80 // T6 DEGRADE: strip seg-1's sidecar -> that segment falls back to AND (docs 1,2,3 all carry both
81 // terms) while seg-2 stays exact; exact flag MUST clear
82 g_unlink("/tmp/posgate-seg-1.pos" as *u8)
83 let n6: i64 = g_phrase2(prefix, h, "alpha" as *u8, "beta" as *u8, 0 as *u8, ebox)
84 var t6: i64 = 0
85 if n6 == 4 { if ebox[0] == 0 { t6 = 1 } }
86 g_check("T6 degrade: no sidecar -> AND fallback (4 docs), exact=0" as *u8, t6, pass, total)
87
88 // T7 COMPACTION UPGRADE: compact -> one merged segment rebuilt through ss_write_seg -> fresh sidecar
89 // -> adjacency exact again (2 docs)
90 let crc: i64 = ss_compact(prefix, 9)
91 let h2: *i64 = ss_open(prefix)
92 let n7: i64 = g_phrase2(prefix, h2, "alpha" as *u8, "beta" as *u8, 0 as *u8, ebox)
93 var t7: i64 = 0
94 if crc == 9 { if n7 == 2 { if ebox[0] == 1 { t7 = 1 } } }
95 g_check("T7 compaction upgrade -> exact phrase again (2 docs)" as *u8, t7, pass, total)
96
97 // T8 regression floor: plain term search still answers over the compacted store
98 let kp8: *i64 = sys_mmap(8 * 64) as *i64
99 let kl8: *i64 = sys_mmap(8 * 64) as *i64
100 let n8: i64 = ss_term(h2, "alpha" as *u8, kp8, kl8, 64)
101 g_check("T8 ss_term still answers post-compact (4 docs)" as *u8, (n8 == 4) as i64, pass, total)
102
103 g_puts("=== seg-pos gate: " as *u8); g_num(pass[0]); g_puts("/" as *u8); g_num(total[0]); g_puts(" " as *u8)
104 if pass[0] == total[0] { g_puts("GREEN\n" as *u8); return 0 }
105 g_puts("RED\n" as *u8); return 1
106}