code wiki / _hdl_build / nx_analyst_data_gate.nx
nx_analyst_data_gate.nx source
↩ module page · 139 lines · 6469 B
1// nx_analyst_data_gate.nx -- GATE for the general data analyst (nx_analyst_data). Proves the profiler
2// computes correct stats on hand-built columns AND that the data-driven EXPLANATION correctly classifies
3// each column shape (constant / categorical / near-unique-id / right-skewed / has-outliers). Known-answer;
4// the report substrings are the load-bearing asserts. expect_exit: 0 license_tier: ORIGINAL
5import "nx_syscalls.nx"
6import "_hdl_build/nx_analyst_data.nx"
7import "nx_gate_verdict.nx"
8
9func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
10func gnn(v: i64) -> i64 { var m: i64=v; if m<0{gp("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o:*u8=sys_mmap(24); var i:i64=0; while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
11
12func ghas(hay: *u8, n: i64, needle: *u8) -> i64 {
13 var nl: i64 = 0
14 while needle[nl] != (0 as u8) { nl = nl + 1 }
15 if nl == 0 { return 0 }
16 var i: i64 = 0
17 while i + nl <= n {
18 var j: i64 = 0
19 var eq: i64 = 1
20 while j < nl { if hay[i + j] != needle[j] { eq = 0; break } j = j + 1 }
21 if eq == 1 { return 1 }
22 i = i + 1
23 }
24 return 0
25}
26
27func lcg(s: i64) -> i64 { return (s * 1103515245 + 12345) & 0x7fffffff }
28
29func main() -> i64 {
30 gp("=== nx_analyst_data_gate ===\n" as *u8)
31 var pass: i64 = 0
32 var fail: i64 = 0
33 let prof: *i64 = sys_mmap(16 * 8) as *i64
34 let rep: *u8 = sys_mmap(4096)
35
36 // ---- C1 categorical: 1000 rows, 5 classes (values 0..4) ----
37 let c1: *i64 = sys_mmap(1000 * 8) as *i64
38 var s: i64 = 3
39 var i: i64 = 0
40 while i < 1000 { s = lcg(s); c1[i] = s % 5; i = i + 1 }
41 ad_profile(c1, 1000, 10, prof)
42 var t1: i64 = 1
43 if prof[AD_COUNT] != 1000 { t1 = 0 }
44 if prof[AD_MIN] != 0 { t1 = 0 }
45 if prof[AD_MAX] != 4 { t1 = 0 }
46 let r1: i64 = ad_report("c1_categorical" as *u8, prof, rep, 4096)
47 if ghas(rep, r1, "categorical" as *u8) == 0 { t1 = 0 }
48 gp(rep)
49 if t1 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("C1 FAIL categorical\n" as *u8) }
50
51 // ---- C2 near-unique id: 500 rows all distinct (i*7+1) ----
52 let c2: *i64 = sys_mmap(500 * 8) as *i64
53 i = 0
54 while i < 500 { c2[i] = i * 7 + 1; i = i + 1 }
55 ad_profile(c2, 500, 10, prof)
56 var t2: i64 = 1
57 if prof[AD_COUNT] != 500 { t2 = 0 }
58 // distinct is approx (HLL); distinct_pct should be high (near 100)
59 if prof[AD_DISTINCT_PCT] < 85 { t2 = 0 }
60 let r2: i64 = ad_report("c2_id" as *u8, prof, rep, 4096)
61 if ghas(rep, r2, "id/key" as *u8) == 0 { t2 = 0 }
62 gp(rep)
63 if t2 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("C2 FAIL near-unique id\n" as *u8) }
64
65 // ---- C3 constant: 300 rows all = 42 ----
66 let c3: *i64 = sys_mmap(300 * 8) as *i64
67 i = 0
68 while i < 300 { c3[i] = 42; i = i + 1 }
69 ad_profile(c3, 300, 10, prof)
70 var t3: i64 = 1
71 if prof[AD_MIN] != 42 { t3 = 0 }
72 if prof[AD_MAX] != 42 { t3 = 0 }
73 if prof[AD_MEAN] != 42 { t3 = 0 }
74 if prof[AD_STDDEV] != 0 { t3 = 0 }
75 let r3: i64 = ad_report("c3_const" as *u8, prof, rep, 4096)
76 if ghas(rep, r3, "CONSTANT" as *u8) == 0 { t3 = 0 }
77 gp(rep)
78 if t3 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("C3 FAIL constant\n" as *u8) }
79
80 // ---- C4 right-skewed with outliers: 1000 rows mostly ~100, a few HUGE ----
81 let c4: *i64 = sys_mmap(1000 * 8) as *i64
82 s = 99
83 i = 0
84 while i < 1000 { s = lcg(s); c4[i] = 90 + (s % 20); i = i + 1 } // ~90..110
85 c4[10] = 100000
86 c4[500] = 120000
87 c4[900] = 140000 // 3 huge -> right skew + outliers
88 ad_profile(c4, 1000, 10, prof)
89 var t4: i64 = 1
90 if prof[AD_MEAN] <= prof[AD_MEDIAN] { t4 = 0 } // mean pulled above median by the tail
91 if (prof[AD_OUT_HI] + prof[AD_OUT_LO]) < 3 { t4 = 0 } // at least the 3 planted outliers
92 let r4: i64 = ad_report("c4_skew" as *u8, prof, rep, 4096)
93 if ghas(rep, r4, "RIGHT-SKEWED" as *u8) == 0 { t4 = 0 }
94 if ghas(rep, r4, "outliers beyond 3 sigma" as *u8) == 0 { t4 = 0 }
95 gp(rep)
96 if t4 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("C4 FAIL skew+outliers\n" as *u8) }
97
98 // ---- C5 clean continuous: uniform, no outliers, symmetric ----
99 let c5: *i64 = sys_mmap(2000 * 8) as *i64
100 s = 555
101 i = 0
102 while i < 2000 { s = lcg(s); c5[i] = s % 1000; i = i + 1 }
103 ad_profile(c5, 2000, 10, prof)
104 let r5: i64 = ad_report("c5_uniform" as *u8, prof, rep, 4096)
105 var t5: i64 = 1
106 if ghas(rep, r5, "continuous numeric" as *u8) == 0 { t5 = 0 }
107 if ghas(rep, r5, "No 3-sigma outliers" as *u8) == 0 { t5 = 0 }
108 gp(rep)
109 if t5 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("C5 FAIL clean continuous\n" as *u8) }
110
111 // ---- C6 empty-column safety ----
112 let ec: *i64 = sys_mmap(8) as *i64
113 ad_profile(ec, 0, 10, prof)
114 var t6: i64 = 1
115 if prof[AD_COUNT] != 0 { t6 = 0 }
116 let r6: i64 = ad_report("c6_empty" as *u8, prof, rep, 4096)
117 if r6 <= 0 { t6 = 0 }
118 if t6 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("C6 FAIL empty safety\n" as *u8) }
119
120 gp("pass=" as *u8); gnn(pass); gp(" fail=" as *u8); gnn(fail); gp("\n" as *u8)
121 let log: *u8 = sys_mmap(128)
122 var lo: i64 = 0
123 let pre: *u8 = "ANALYSTDATA authored=organ verdict=" as *u8
124 var pi: i64 = 0
125 while pre[pi] != (0 as u8) { log[lo] = pre[pi]; lo = lo + 1; pi = pi + 1 }
126 if fail == 0 { let g: *u8 = "GREEN\n" as *u8; var gi: i64 = 0; while g[gi] != (0 as u8) { log[lo] = g[gi]; lo = lo + 1; gi = gi + 1 } } else { let r: *u8 = "RED\n" as *u8; var ri: i64 = 0; while r[ri] != (0 as u8) { log[lo] = r[ri]; lo = lo + 1; ri = ri + 1 } }
127 let fd: i64 = sys_openat_wr("knowledge/status/analyst_data.log" as *u8, 0x1A4)
128 if fd >= 0 { sys_write(fd, log, lo); sys_close(fd) }
129
130 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
131 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
132 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
133 let ctr__dry: *i64 = gv_ctr()
134 ctr__dry[0] = pass
135 ctr__dry[1] = pass + fail
136 let rc__dry: i64 = gv_verdict("ANALYST-DATA-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
137 sys_exit(rc__dry)
138 return rc__dry
139}