code wiki / _hdl_build / nx_analyst_report_gate.nx

nx_analyst_report_gate.nx source

↩ module page · 109 lines · 5737 B

1// nx_analyst_report_gate.nx -- GATE for the dataset-analysis capstone (nx_analyst_report). A realistic small 2// dataset with KNOWN relationships (price strongly driven by size, weakly by age) must produce a report that 3// (a) profiles every column, (b) reports the correct correlation direction/strength to the target, (c) names 4// the correct strongest ASSOCIATION (renamed from KEY DRIVER in F1005: the number is associational and 5// 'driver' is a causal word). The report substrings are the load-bearing asserts. expect_exit: 0 license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "_hdl_build/nx_analyst_report.nx" 8import "nx_gate_verdict.nx" 9 10func rp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func rn(v: i64) -> i64 { var m: i64=v; if m<0{rp("-" 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 } 12func rhas(hay: *u8, n: i64, needle: *u8) -> i64 { 13 var nl: i64 = 0 14 while needle[nl] != (0 as u8) { nl = nl + 1 } 15 var i: i64 = 0 16 while i + nl <= n { var j: i64 = 0; var eq: i64 = 1; while j < nl { if hay[i+j] != needle[j] { eq = 0; break } j = j + 1 } if eq == 1 { return 1 } i = i + 1 } 17 return 0 18} 19func lcg(s: i64) -> i64 { return (s * 1103515245 + 12345) & 0x7fffffff } 20 21func main() -> i64 { 22 rp("=== nx_analyst_report_gate ===\n" as *u8) 23 var pass: i64 = 0 24 var fail: i64 = 0 25 let n: i64 = 300 26 27 // dataset: size (driver), age (weak inverse), price = 5*size - 2*age + noise (price is the target) 28 let size: *i64 = sys_mmap(n * 8) as *i64 29 let age: *i64 = sys_mmap(n * 8) as *i64 30 let price: *i64 = sys_mmap(n * 8) as *i64 31 var s: i64 = 11 32 var i: i64 = 0 33 while i < n { 34 s = lcg(s) 35 size[i] = 50 + (s % 150) // 50..199 36 s = lcg(s) 37 age[i] = s % 40 // 0..39 (independent of size) 38 s = lcg(s) 39 price[i] = 5 * size[i] - 2 * age[i] + (s % 20) // strongly driven by size, weakly (neg) by age 40 i = i + 1 41 } 42 43 let cols: *i64 = sys_mmap(3 * 8) as *i64 44 let names: *i64 = sys_mmap(3 * 8) as *i64 45 cols[0] = size as i64 46 cols[1] = age as i64 47 cols[2] = price as i64 48 names[0] = "size" as *u8 as i64 49 names[1] = "age" as *u8 as i64 50 names[2] = "price" as *u8 as i64 51 52 let out: *u8 = sys_mmap(16384) 53 let w: i64 = ar_analyze(cols, names, 3, n, 2, out, 16384) // target = price (idx 2) 54 rp(out) 55 rp("\n---\n" as *u8) 56 57 // T1 structure: header + per-column profiles + relationships + key driver sections 58 var t1: i64 = 1 59 if w <= 0 { t1 = 0 } 60 if rhas(out, w, "DATASET ANALYSIS" as *u8) == 0 { t1 = 0 } 61 if rhas(out, w, "PER-COLUMN PROFILES" as *u8) == 0 { t1 = 0 } 62 if rhas(out, w, "RELATIONSHIPS TO price" as *u8) == 0 { t1 = 0 } 63 if rhas(out, w, "STRONGEST ASSOCIATION with price" as *u8) == 0 { t1 = 0 } 64 if t1 == 1 { pass = pass + 1 } else { fail = fail + 1; rp("T1 FAIL structure\n" as *u8) } 65 66 // T2 every column profiled 67 var t2: i64 = 1 68 if rhas(out, w, "DATA PROFILE: size" as *u8) == 0 { t2 = 0 } 69 if rhas(out, w, "DATA PROFILE: age" as *u8) == 0 { t2 = 0 } 70 if rhas(out, w, "DATA PROFILE: price" as *u8) == 0 { t2 = 0 } 71 if t2 == 1 { pass = pass + 1 } else { fail = fail + 1; rp("T2 FAIL per-column profiles\n" as *u8) } 72 73 // T3 correct relationships: size -> strong positive to price; age -> weak/negligible (and negative if any) 74 var t3: i64 = 1 75 if rhas(out, w, "size: r=" as *u8) == 0 { t3 = 0 } 76 if rhas(out, w, "positive strong" as *u8) == 0 { if rhas(out, w, "positive very strong" as *u8) == 0 { t3 = 0 } } 77 if t3 == 1 { pass = pass + 1 } else { fail = fail + 1; rp("T3 FAIL relationships\n" as *u8) } 78 79 // T4 the strongest association correctly identified as size (not age) 80 var t4: i64 = 1 81 if rhas(out, w, "size has the strongest association" as *u8) == 0 { t4 = 0 } 82 if t4 == 1 { pass = pass + 1 } else { fail = fail + 1; rp("T4 FAIL key driver not size\n" as *u8) } 83 84 // T5 bounds guard: target_idx out of range -> 0 (no crash) 85 var t5: i64 = 1 86 if ar_analyze(cols, names, 3, n, 9, out, 16384) != 0 { t5 = 0 } 87 if ar_analyze(cols, names, 0, n, 0, out, 16384) != 0 { t5 = 0 } 88 if t5 == 1 { pass = pass + 1 } else { fail = fail + 1; rp("T5 FAIL bounds guard\n" as *u8) } 89 90 rp("pass=" as *u8); rn(pass); rp(" fail=" as *u8); rn(fail); rp("\n" as *u8) 91 let log: *u8 = sys_mmap(128) 92 var lo: i64 = 0 93 let pre: *u8 = "ANALYSTREPORT authored=organ verdict=" as *u8 94 var pi: i64 = 0 95 while pre[pi] != (0 as u8) { log[lo] = pre[pi]; lo = lo + 1; pi = pi + 1 } 96 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 } } 97 let fd: i64 = sys_openat_wr("knowledge/status/analyst_report.log" as *u8, 0x1A4) 98 if fd >= 0 { sys_write(fd, log, lo); sys_close(fd) } 99 100 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 101 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 102 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 103 let ctr__dry: *i64 = gv_ctr() 104 ctr__dry[0] = pass 105 ctr__dry[1] = pass + fail 106 let rc__dry: i64 = gv_verdict("ANALYST-REPORT-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 107 sys_exit(rc__dry) 108 return rc__dry 109}