code wiki / _hdl_build / nx_dataframe_gate.nx

nx_dataframe_gate.nx source

↩ module page · 142 lines · 7035 B

1import "nx_gate_gn.nx" 2// nx_dataframe_gate.nx -- GATE for the aggregation front door (nx_dataframe). Known-answer tests on a fixed 3// column so every reduction, predicate scan, quantile, GROUP BY, and inner join is proven EXACT (integer- 4// reproducible). Anti-false-green: a deliberately-wrong expected value is NOT used; every assert is the true 5// hand-computed answer. expect_exit: 0 license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "_hdl_build/nx_dataframe.nx" 8import "nx_gate_verdict.nx" 9 10func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11 12func main() -> i64 { 13 gp("=== nx_dataframe_gate ===\n" as *u8) 14 var pass: i64 = 0 15 var fail: i64 = 0 16 17 // column = [5, 2, 9, 2, 7, 5] (n=6) sum=30 min=2 max=9 mean=5 (30/6) sorted=[2,2,5,5,7,9] 18 let col: *i64 = sys_mmap(6 * 8) as *i64 19 col[0]=5; col[1]=2; col[2]=9; col[3]=2; col[4]=7; col[5]=5 20 let n: i64 = 6 21 22 // T1 reductions 23 var t1: i64 = 1 24 if df_count(col, n) != 6 { t1 = 0 } 25 if df_sum(col, n) != 30 { t1 = 0 } 26 if df_min(col, n) != 2 { t1 = 0 } 27 if df_max(col, n) != 9 { t1 = 0 } 28 if t1 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T1 FAIL reductions\n" as *u8) } 29 30 // T2 mean + remainder + milli mean (30/6 = 5 exact; milli = 5000) 31 var t2: i64 = 1 32 let rem: *i64 = sys_mmap(8) as *i64 33 if df_mean(col, n, rem) != 5 { t2 = 0 } 34 if rem[0] != 0 { t2 = 0 } 35 if df_mean_milli(col, n) != 5000 { t2 = 0 } 36 if t2 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T2 FAIL mean\n" as *u8) } 37 38 // T3 mean with remainder on a non-divisible column [1,2,3,4] sum=10 n=4 mean=2 rem=2 milli=2500 39 let c2: *i64 = sys_mmap(4 * 8) as *i64 40 c2[0]=1; c2[1]=2; c2[2]=3; c2[3]=4 41 var t3: i64 = 1 42 if df_mean(c2, 4, rem) != 2 { t3 = 0 } 43 if rem[0] != 2 { t3 = 0 } 44 if df_mean_milli(c2, 4) != 2500 { t3 = 0 } 45 if t3 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T3 FAIL mean-remainder\n" as *u8) } 46 47 // T4 variance + stddev on [2,4,4,4,5,5,7,9]: mean=5, var=4, stddev=2 (textbook) 48 let c3: *i64 = sys_mmap(8 * 8) as *i64 49 c3[0]=2; c3[1]=4; c3[2]=4; c3[3]=4; c3[4]=5; c3[5]=5; c3[6]=7; c3[7]=9 50 var t4: i64 = 1 51 let vm: i64 = df_var_milli(c3, 8) // 4 * 1000 = 4000 52 if vm != 4000 { t4 = 0 } 53 if df_isqrt(vm / 1000) != 2 { t4 = 0 } // sqrt(4) = 2 54 if df_isqrt(9) != 3 { t4 = 0 } 55 if df_isqrt(10) != 3 { t4 = 0 } // floor 56 if t4 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T4 FAIL variance/stddev\n" as *u8) } 57 58 // T5 predicate scans on col [5,2,9,2,7,5]: >=5 -> {5,9,7,5}=4 count, sum=26 ; ==2 -> 2 count 59 var t5: i64 = 1 60 if df_filter_count(col, n, 4, 5) != 4 { t5 = 0 } // >=5 61 if df_filter_sum(col, n, 4, 5) != 26 { t5 = 0 } 62 if df_filter_count(col, n, 0, 2) != 2 { t5 = 0 } // ==2 63 if df_filter_count(col, n, 1, 5) != 2 { t5 = 0 } // <5 -> {2,2} 64 if t5 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T5 FAIL predicate scan\n" as *u8) } 65 66 // T6 quantiles on sorted [2,2,5,5,7,9]: min(q0)=2, max(q1000)=9, median(q500)=rank (500*5/1000)=2 -> cp[2]=5 67 var t6: i64 = 1 68 if df_quantile(col, n, 0) != 2 { t6 = 0 } 69 if df_quantile(col, n, 1000) != 9 { t6 = 0 } 70 if df_quantile(col, n, 500) != 5 { t6 = 0 } 71 // the source column must be UNCHANGED (quantile sorts a copy) 72 if col[0] != 5 { t6 = 0 } 73 if col[1] != 2 { t6 = 0 } 74 if t6 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T6 FAIL quantile / column-immutability\n" as *u8) } 75 76 // T7 GROUP BY: keys=[1,2,1,3,2,1] vals=[10,20,30,40,50,60] 77 // count: g1=3 g2=2 g3=1 ; sum: g1=100 g2=70 g3=40 78 let gk: *i64 = sys_mmap(6 * 8) as *i64 79 let gv: *i64 = sys_mmap(6 * 8) as *i64 80 gk[0]=1; gk[1]=2; gk[2]=1; gk[3]=3; gk[4]=2; gk[5]=1 81 gv[0]=10; gv[1]=20; gv[2]=30; gv[3]=40; gv[4]=50; gv[5]=60 82 let ok: *i64 = sys_mmap(16 * 8) as *i64 83 let oa: *i64 = sys_mmap(16 * 8) as *i64 84 var t7: i64 = 1 85 let gc: i64 = df_groupby(gk, gv, 6, 0, ok, oa, 16) // count 86 if gc != 3 { t7 = 0 } 87 // groups emitted in first-seen order: key1,key2,key3 88 if ok[0] != 1 { t7 = 0 } else { if oa[0] != 3 { t7 = 0 } } 89 if ok[1] != 2 { t7 = 0 } else { if oa[1] != 2 { t7 = 0 } } 90 if ok[2] != 3 { t7 = 0 } else { if oa[2] != 1 { t7 = 0 } } 91 let gc2: i64 = df_groupby(gk, gv, 6, 1, ok, oa, 16) // sum 92 if gc2 != 3 { t7 = 0 } 93 if oa[0] != 100 { t7 = 0 } 94 if oa[1] != 70 { t7 = 0 } 95 if oa[2] != 40 { t7 = 0 } 96 if t7 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T7 FAIL groupby\n" as *u8) } 97 98 // T8 INNER JOIN: left keys=[1,2,3] vals=[100,200,300]; right keys=[2,3,4] vals=[22,33,44] 99 // matches: (200,22),(300,33) -> 2 rows 100 let lk: *i64 = sys_mmap(3 * 8) as *i64 101 let lv: *i64 = sys_mmap(3 * 8) as *i64 102 let rk: *i64 = sys_mmap(3 * 8) as *i64 103 let rv: *i64 = sys_mmap(3 * 8) as *i64 104 lk[0]=1; lk[1]=2; lk[2]=3; lv[0]=100; lv[1]=200; lv[2]=300 105 rk[0]=2; rk[1]=3; rk[2]=4; rv[0]=22; rv[1]=33; rv[2]=44 106 let jl: *i64 = sys_mmap(8 * 8) as *i64 107 let jr: *i64 = sys_mmap(8 * 8) as *i64 108 var t8: i64 = 1 109 let jn: i64 = df_inner_join(lk, lv, 3, rk, rv, 3, jl, jr, 8) 110 if jn != 2 { t8 = 0 } 111 if jl[0] != 200 { t8 = 0 } else { if jr[0] != 22 { t8 = 0 } } 112 if jl[1] != 300 { t8 = 0 } else { if jr[1] != 33 { t8 = 0 } } 113 if t8 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T8 FAIL inner join\n" as *u8) } 114 115 // T9 empty-column safety (no crash, sane zeros) 116 var t9: i64 = 1 117 let ec: *i64 = sys_mmap(8) as *i64 118 if df_count(ec, 0) != 0 { t9 = 0 } 119 if df_sum(ec, 0) != 0 { t9 = 0 } 120 if df_mean(ec, 0, rem) != 0 { t9 = 0 } 121 if df_quantile(ec, 0, 500) != 0 { t9 = 0 } 122 if t9 == 1 { pass = pass + 1 } else { fail = fail + 1; gp("T9 FAIL empty safety\n" as *u8) } 123 124 gp("pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail); gp("\n" as *u8) 125 let log: *u8 = sys_mmap(128) 126 var lo: i64 = 0 127 let pre: *u8 = "DATAFRAME authored=organ verdict=" as *u8 128 var pi: i64 = 0; while pre[pi]!=(0 as u8){log[lo]=pre[pi];lo=lo+1;pi=pi+1} 129 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 rr: *u8="RED\n" as *u8; var ri:i64=0; while rr[ri]!=(0 as u8){log[lo]=rr[ri];lo=lo+1;ri=ri+1} } 130 let fd: i64 = sys_openat_wr("knowledge/status/dataframe.log" as *u8, 0x1A4) 131 if fd >= 0 { sys_write(fd, log, lo); sys_close(fd) } 132 133 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 134 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 135 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 136 let ctr__dry: *i64 = gv_ctr() 137 ctr__dry[0] = pass 138 ctr__dry[1] = pass + fail 139 let rc__dry: i64 = gv_verdict("DATAFRAME-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 140 sys_exit(rc__dry) 141 return rc__dry 142}