code wiki / _hdl_build / nx_research_gate.nx
nx_research_gate.nx source
↩ module page · 98 lines · 5085 B
1// nx_research_gate.nx -- THE RESEARCHER REGRESSION GATE (testing capability, not a feature). Re-verifies the
2// invariants of the whole self-growing researcher system across EVERY index in the search-sources manifest, so a
3// regression in any organ (grow/register/federated/...) is caught mechanically. Checks, per source: (A) the index
4// LOADS; (B) ALIGNMENT idx.n_rows == docmap line count (the rowid->doc contract grow guarantees); (C) a smoke
5// query returns postings (the engine answers). Plus global: (D) at least one source; (E) a dark/common term
6// ("the") is found somewhere. Prints GREEN/RED per source + a verdict; exit 0 iff all GREEN. Read-only, no floats.
7// expect_exit: 0 license_tier: ORIGINAL
8import "nx_search_inverted_persist.nx"
9
10const GT_ROWIDS: i64 = 4096
11const GT_SRC: i64 = 8192
12
13func gt_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
14func gt_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 }
15func gt_scan(buf: *u8, i: i64, end: i64) -> i64 {
16 var p: i64=i; var stop: i64=0
17 while stop==0 { if p>=end { stop=1 } else { if buf[p]==(32 as u8) { stop=1 } else { if buf[p]==(10 as u8) { stop=1 } else { p=p+1 } } } }
18 return p
19}
20func gt_line_end(buf: *u8, i: i64, end: i64) -> i64 {
21 var p: i64=i; var stop: i64=0
22 while stop==0 { if p>=end { stop=1 } else { if buf[p]==(10 as u8) { stop=1 } else { p=p+1 } } }
23 return p
24}
25func gt_count_lines(path: *u8) -> i64 {
26 let lenbox: *i64 = sys_mmap(16) as *i64
27 let buf: *u8 = sys_read_file(path, lenbox)
28 if buf == 0 as *u8 { return 0 - 1 }
29 let total: i64 = lenbox[0]
30 var nd: i64 = 0; var start: i64 = 0; var i: i64 = 0
31 while i < total {
32 if buf[i] == (10 as u8) { if i > start { nd = nd + 1 } start = i + 1 }
33 i = i + 1
34 }
35 return nd
36}
37
38func main() -> i64 {
39 gt_puts("=== nx_research_gate: re-verify researcher invariants across all indexes (regression gate) ===\n" as *u8)
40 let mbox: *i64 = sys_mmap(16) as *i64
41 let man: *u8 = sys_read_file("knowledge/index/search_sources.txt" as *u8, mbox)
42 if man == 0 as *u8 { gt_puts(" verdict=RED: no manifest (run nx_search_register)\n" as *u8); sys_exit(1); return 1 }
43 let mlen: i64 = mbox[0]
44
45 let res: *NxInvQueryResult = sys_mmap(64) as *NxInvQueryResult
46 let rowids: *i64 = sys_mmap(8*GT_ROWIDS) as *i64
47 var nsrc: i64 = 0; var green: i64 = 0; var red: i64 = 0
48 var total_docs: i64 = 0; var smoke_total: i64 = 0
49 var i: i64 = 0
50 while i < mlen {
51 let e1: i64 = gt_scan(man, i, mlen)
52 let label_ptr: i64 = (man as i64) + i; let label_len: i64 = e1 - i
53 var j: i64 = e1; if j<mlen { if man[j]==(32 as u8) { man[j]=0 as u8; j=j+1 } }
54 let idx_ptr: i64 = (man as i64) + j
55 let e2: i64 = gt_scan(man, j, mlen)
56 var k: i64 = e2; if k<mlen { if man[k]==(32 as u8) { man[k]=0 as u8; k=k+1 } }
57 let dmap_ptr: i64 = (man as i64) + k
58 let e3: i64 = gt_scan(man, k, mlen); if e3<mlen { if man[e3]==(32 as u8) { man[e3]=0 as u8 } }
59 var e: i64 = gt_line_end(man, e3, mlen); if e<mlen { e=e+1 }
60
61 if e1 > i {
62 nsrc = nsrc + 1
63 var ok: i64 = 1
64 let idx: *NxInvIndex = nx_inv_load(idx_ptr as *u8)
65 var nrows: i64 = 0 - 1
66 var ndocs: i64 = 0 - 1
67 if idx == 0 as *NxInvIndex { ok = 0 }
68 else {
69 nrows = idx.n_rows
70 ndocs = gt_count_lines(dmap_ptr as *u8)
71 if nrows != ndocs { ok = 0 } // ALIGNMENT invariant
72 else {
73 total_docs = total_docs + ndocs
74 nx_inv_query_term(idx, "the" as *u8, 3, rowids, GT_ROWIDS, res) // smoke
75 smoke_total = smoke_total + res.postings_count
76 }
77 }
78 sys_write(1, " [" as *u8, 3); sys_write(1, label_ptr as *u8, label_len); gt_puts("] " as *u8)
79 gt_puts("rows="); gt_num(nrows); gt_puts(" docs="); gt_num(ndocs)
80 if ok == 1 { gt_puts(" GREEN\n" as *u8); green = green + 1 } else { gt_puts(" RED\n" as *u8); red = red + 1 }
81 }
82 i = e
83 }
84
85 gt_puts(" sources="); gt_num(nsrc); gt_puts(" GREEN="); gt_num(green); gt_puts(" RED="); gt_num(red)
86 gt_puts(" total_docs="); gt_num(total_docs); gt_puts(" smoke('the')_postings="); gt_num(smoke_total); gt_puts("\n" as *u8)
87
88 var verdict_red: i64 = 0
89 if nsrc <= 0 { verdict_red = 1 }
90 if red > 0 { verdict_red = 1 }
91 if smoke_total <= 0 { verdict_red = 1 }
92 if verdict_red == 0 {
93 gt_puts(" GATE GREEN: every index aligned (rows==docs) + queryable; researcher system invariants hold\n" as *u8)
94 sys_exit(0); return 0
95 }
96 gt_puts(" GATE RED: a researcher invariant FAILED (see RED sources above)\n" as *u8)
97 sys_exit(1); return 1
98}