code wiki / _hdl_build / nx_gramdec_gate.nx

nx_gramdec_gate.nx source

↩ module page · 231 lines · 9861 B

1// nx_gramdec_gate.nx -- NB10 gate: grammar-constrained decode (nx_gramdec_lib) teeth. 2// T1-T8 = automaton ruler teeth (no model). T9 = LIVE no-op equivalence: on an already-grammatical 3// greedy generation the constrained decode must be BIT-EXACT (prefix) with nsv_generate, zero 4// rejections, accept-stop. T10 = LIVE mask-fires (anti-vacuity + escape): an else-if-baited prompt 5// must (a) make the UNCONSTRAINED model emit `else if` (proves the bait bites -- the vacuity guard), 6// (b) under the mask produce grammar-VALID output with >=1 rejection and NO `else if`. 7// MUTATION PROOF (rung 5): flip GD_NEG_ALLOW_ELSEIF=1 in nx_gramdec_lib.nx, rebuild, run -> T3 8// accepts the else-if text and T10 sees the escape -> verdict=RED exit 1. Restore -> GREEN. 9// argv: [model.gguf] [probe] (default model /home/elderwesto/nx_stage/nx_15b_model.gguf; 10// "probe" prints raw outputs for tooth calibration instead of judging). 11// license_tier: ORIGINAL No hw writes (Rule 26). 12import "nx_gramdec_lib.nx" 13 14const GG_MAXNEW: i64 = 120 15const GG_OCAP: i64 = 4000 16 17func gg_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 18func gg_wn(v: i64) -> i64 { 19 var m: i64 = v 20 if m < 0 { gg_w("-" as *u8); m = 0 - m } 21 let t: *u8 = sys_mmap(24) 22 var k: i64 = 0 23 if m == 0 { t[0] = 48 as u8; k = 1 } 24 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 25 let o: *u8 = sys_mmap(24) 26 var i: i64 = 0 27 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 28 sys_write(1, o, k) 29 return 0 30} 31func gg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 32func gg_cat(b: *u8, off: i64, s: *u8) -> i64 { 33 var i: i64 = 0 34 var o: i64 = off 35 while s[i] != (0 as u8) { b[o] = s[i]; o = o + 1; i = i + 1 } 36 return o 37} 38func gg_find(hay: *u8, hn: i64, needle: *u8, from: i64) -> i64 { 39 let m: i64 = gg_slen(needle) 40 if m == 0 { return 0 - 1 } 41 var i: i64 = from 42 while i + m <= hn { 43 var j: i64 = 0 44 var ok: i64 = 1 45 while j < m { if hay[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } } 46 if ok == 1 { return i } 47 i = i + 1 48 } 49 return 0 - 1 50} 51 52static gg_pass: i64 53static gg_total: i64 54 55func gg_tooth(name: *u8, got: i64) -> i64 { 56 gg_total = gg_total + 1 57 gg_w(" T" as *u8) 58 gg_wn(gg_total) 59 gg_w(" " as *u8) 60 gg_w(name) 61 if got == 1 { gg_w(": PASS\n" as *u8); gg_pass = gg_pass + 1 } else { gg_w(": FAIL\n" as *u8) } 62 return 0 63} 64// validate a NUL-terminated literal through the whole-text ruler 65func gg_val(s: *u8) -> i64 { let n: i64 = gg_slen(s); return gd_validate(s, n) } 66 67// build the CLEAN round-1 sgn prompt (exact episode shape, cand2, no FNCASE rows) 68func gg_prompt_clean(pb: *u8) -> i64 { 69 var o: i64 = 0 70 o = gg_cat(pb, o, "Fix each buggy NishiLang function. Output only the corrected function on one line.\n" as *u8) 71 o = gg_cat(pb, o, "Buggy: func min2(a: i64, b: i64) -> i64 { return b }\n" as *u8) 72 o = gg_cat(pb, o, "Fixed: func min2(a: i64, b: i64) -> i64 { if a < b { return a } return b }\n" as *u8) 73 o = gg_cat(pb, o, "Buggy: func abs1(x: i64) -> i64 { return x }\n" as *u8) 74 o = gg_cat(pb, o, "Fixed: func abs1(x: i64) -> i64 { if x < 0 { return 0 - x } return x }\n" as *u8) 75 o = gg_cat(pb, o, "Buggy: func sgn(x: i64) -> i64 { return 0 }\n" as *u8) 76 o = gg_cat(pb, o, "Fixed: " as *u8) 77 return o 78} 79// build the ELSE-IF BAIT prompt (few-shots in else-if style -> greedy model copies the style) 80func gg_prompt_bait(pb: *u8) -> i64 { 81 var o: i64 = 0 82 o = gg_cat(pb, o, "Fix each buggy NishiLang function. Output only the corrected function on one line.\n" as *u8) 83 o = gg_cat(pb, o, "Buggy: func min2(a: i64, b: i64) -> i64 { return b }\n" as *u8) 84 o = gg_cat(pb, o, "Fixed: func min2(a: i64, b: i64) -> i64 { if a < b { return a } else { return b } }\n" as *u8) 85 o = gg_cat(pb, o, "Buggy: func clamp1(x: i64) -> i64 { return x }\n" as *u8) 86 o = gg_cat(pb, o, "Fixed: func clamp1(x: i64) -> i64 { if x < 0 { return 0 } else if x > 1 { return 1 } else { return x } }\n" as *u8) 87 o = gg_cat(pb, o, "Buggy: func sgn(x: i64) -> i64 { return 0 }\n" as *u8) 88 o = gg_cat(pb, o, "Fixed: " as *u8) 89 return o 90} 91// run one generation. which=0 -> nsv_generate (raw), 1 -> gdx_generate (masked). Greedy. 92// pb/plen prompt; tx out buffer; mt meta. returns text length. 93static gg_pb: *u8 94static gg_plen: i64 95func gg_gen(which: i64, tx: *u8, mt: *i64) -> i64 { 96 let gp: *i64 = sys_mmap(16 * 8) as *i64 97 gp[0] = gg_pb as i64 98 gp[1] = gg_plen 99 gp[2] = GG_MAXNEW 100 gp[3] = 1 101 gp[4] = tx as i64 102 gp[5] = GG_OCAP 103 gp[6] = mt as i64 104 gp[7] = 0 - 1 105 gp[8] = 0 106 gp[9] = 0 107 gp[10] = 0 108 gp[11] = 0 109 gp[12] = 0 110 if which == 1 { return gdx_generate(gp) } 111 return nsv_generate(gp) 112} 113 114func main(argc: i64, argv: *i64) -> i64 { 115 gg_w("nx_gramdec gate -- NB10 grammar-constrained decode: automaton ruler + live mask teeth\n\n" as *u8) 116 gg_pass = 0 117 gg_total = 0 118 // --- automaton teeth (no model) --- 119 gg_tooth("accepts correct early-return fn" as *u8, gg_val("func sgn(x: i64) -> i64 { if x > 0 { return 1 } if x < 0 { return 0 - 1 } return 0 }" as *u8)) 120 gg_tooth("accepts legal } else { form" as *u8, gg_val("func f(x: i64) -> i64 { if x > 0 { return 1 } else { return 0 } }" as *u8)) 121 var r3: i64 = 0 122 if gg_val("func f(x: i64) -> i64 { if x > 0 { return 1 } else if x < 0 { return 2 } return 0 }" as *u8) == 0 { r3 = 1 } 123 gg_tooth("rejects else-if chain" as *u8, r3) 124 var r4: i64 = 0 125 if gg_val("func f(x: i64) -> i64 { return abs(x) }" as *u8) == 0 { r4 = 1 } 126 gg_tooth("rejects helper call abs()" as *u8, r4) 127 var r5: i64 = 0 128 if gg_val("func f(x: i64) -> i64 { return -x }" as *u8) == 0 { r5 = 1 } 129 gg_tooth("rejects unary minus on identifier" as *u8, r5) 130 gg_tooth("accepts negative literal return -1" as *u8, gg_val("func f(x: i64) -> i64 { if x < 0 { return -1 } return 1 }" as *u8)) 131 var r7: i64 = 0 132 if gg_val("func f(x: i64) -> i64 { if x > 0 { return 1 }" as *u8) == 0 { r7 = 1 } 133 gg_tooth("rejects truncated fn (open brace)" as *u8, r7) 134 // string literal body: poke the quote byte (34) -- never a bare "" in source 135 let sb: *u8 = sys_mmap(256) 136 var so: i64 = 0 137 so = gg_cat(sb, so, "func f(x: i64) -> i64 { return " as *u8) 138 sb[so] = 34 as u8 139 so = so + 1 140 so = gg_cat(sb, so, "x" as *u8) 141 sb[so] = 34 as u8 142 so = so + 1 143 so = gg_cat(sb, so, " }" as *u8) 144 sb[so] = 0 as u8 145 var r8: i64 = 0 146 if gd_validate(sb, so) == 0 { r8 = 1 } 147 gg_tooth("rejects string literal in body" as *u8, r8) 148 // --- live model teeth --- 149 var mpath: *u8 = "/home/elderwesto/nx_stage/nx_15b_model.gguf" as *u8 150 if argc >= 2 { mpath = argv[1] as *u8 } 151 var probe: i64 = 0 152 if argc >= 3 { let pv: *u8 = argv[2] as *u8; if pv[0] == (112 as u8) { probe = 1 } } 153 let irc: i64 = nsv_init_i8(mpath) 154 if irc != 0 { 155 gg_w("model init FAILED -> live teeth cannot run\n" as *u8) 156 gg_tooth("live no-op equivalence" as *u8, 0) 157 gg_tooth("live mask-fires on bait" as *u8, 0) 158 gg_w("\nNX-GRAMDEC-GATE passed " as *u8) 159 gg_wn(gg_pass) 160 gg_w("/" as *u8) 161 gg_wn(gg_total) 162 gg_w(" verdict=RED\n" as *u8) 163 return 1 164 } 165 gg_pb = sys_mmap(4096) 166 let tx1: *u8 = sys_mmap(4096) 167 let tx2: *u8 = sys_mmap(4096) 168 let mt1: *i64 = sys_mmap(64) as *i64 169 let mt2: *i64 = sys_mmap(64) as *i64 170 // T9: no-op equivalence on the clean sgn prompt 171 gg_plen = gg_prompt_clean(gg_pb) 172 let l1: i64 = gg_gen(0, tx1, mt1) 173 let l2: i64 = gg_gen(1, tx2, mt2) 174 if probe == 1 { 175 gg_w("PROBE clean raw (" as *u8) 176 gg_wn(l1) 177 gg_w("B):\n" as *u8) 178 if l1 > 0 { sys_write(1, tx1, l1) } 179 gg_w("\nPROBE clean gdx (" as *u8) 180 gg_wn(l2) 181 gg_w("B, rej=" as *u8) 182 gg_wn(mt2[6]) 183 gg_w(", fin=" as *u8) 184 gg_wn(mt2[7]) 185 gg_w("):\n" as *u8) 186 if l2 > 0 { sys_write(1, tx2, l2) } 187 gg_w("\n" as *u8) 188 } 189 var eq: i64 = 0 190 if l2 > 0 { if l2 <= l1 { 191 var zi: i64 = 0 192 eq = 1 193 while zi < l2 { if tx2[zi] != tx1[zi] { eq = 0; zi = l2 } else { zi = zi + 1 } } 194 } } 195 var t9: i64 = 0 196 if eq == 1 { if mt2[6] == 0 { if mt2[7] == 1 { if gd_validate(tx2, l2) == 1 { t9 = 1 } } } } 197 gg_tooth("live no-op equivalence (prefix bit-exact, 0 rej, accept-stop)" as *u8, t9) 198 // T10: bait -- raw must emit else-if (vacuity guard); masked must not, with >=1 rejection 199 gg_plen = gg_prompt_bait(gg_pb) 200 let b1: i64 = gg_gen(0, tx1, mt1) 201 let b2: i64 = gg_gen(1, tx2, mt2) 202 if probe == 1 { 203 gg_w("PROBE bait raw (" as *u8) 204 gg_wn(b1) 205 gg_w("B):\n" as *u8) 206 if b1 > 0 { sys_write(1, tx1, b1) } 207 gg_w("\nPROBE bait gdx (" as *u8) 208 gg_wn(b2) 209 gg_w("B, rej=" as *u8) 210 gg_wn(mt2[6]) 211 gg_w(", fin=" as *u8) 212 gg_wn(mt2[7]) 213 gg_w("):\n" as *u8) 214 if b2 > 0 { sys_write(1, tx2, b2) } 215 gg_w("\n" as *u8) 216 } 217 var baited: i64 = 0 218 if gg_find(tx1, b1, "else if" as *u8, 0) >= 0 { baited = 1 } 219 var noesc: i64 = 0 220 if gg_find(tx2, b2, "else if" as *u8, 0) < 0 { noesc = 1 } 221 var t10: i64 = 0 222 if baited == 1 { if noesc == 1 { if mt2[6] >= 1 { if b2 > 0 { if gd_validate(tx2, b2) == 1 { t10 = 1 } } } } } 223 gg_tooth("live mask-fires on bait (raw baited, masked clean+valid, >=1 rej)" as *u8, t10) 224 gg_w("\nNX-GRAMDEC-GATE passed " as *u8) 225 gg_wn(gg_pass) 226 gg_w("/" as *u8) 227 gg_wn(gg_total) 228 if gg_pass == gg_total { gg_w(" verdict=GREEN (grammar-constrained decode: ruler sound, live mask load-bearing, no-op path bit-exact)\n" as *u8); return 0 } 229 gg_w(" verdict=RED\n" as *u8) 230 return 1 231}