code wiki / _hdl_build / nx_infinibug.nx
nx_infinibug.nx source
↩ module page · 265 lines · 11862 B
1// nx_infinibug.nx -- INFINIGEN-FOR-CODE (worldclass/bugforge lane, 2026-07-24). Operator pointed at
2// Infinigen (arXiv 2306.09310): a PROCEDURAL generator with NO static assets -- every scene is emitted
3// from seeded random rules, and ground truth comes FREE from the generator. This is that idea ported
4// from photorealistic worlds to VERIFIED CODE REPAIR: it procedurally emits a "world" of novel pure
5// integer functions from a seeded grammar with difficulty knobs, so the bug-instance supply is
6// INFINITE and CURRICULUM-CONTROLLABLE instead of the 35 hand-written functions the disk scan finds.
7//
8// COMPOSITION (rule 15 -- no duplicated machinery): infinibug ONLY generates the world (function
9// source files); the PROVEN nx_bugforge miner then extracts ground-truth-labeled (buggy, oracle-fixed,
10// F2P+P2P) instances from that dir exactly as it mines real code. Infinigen generates, bugforge
11// harvests. This also proves bugforge is source-AGNOSTIC (real corpus OR procedural world, same loop).
12//
13// DETERMINISTIC: seeded LCG (reproducible curriculum -- seed is part of the input, like Infinigen's).
14// SELF-CLEAN under nx_assure: iterative expression builder (NO recursion, P10-R1), no alloc in loops.
15// verbs: gen <count> <seed> <difficulty 1-5> [outdir] (default outdir runtime/igworld) | selftest
16// license_tier: ORIGINAL No hw writes (Rule 26).
17import "nx_syscalls.nx"
18import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
19const IG_MAGIC_12345: i64 = 12345
20
21const IG_A: i64 = 1103515245 // LCG multiplier (glibc rand; small, ratchet-safe as a named const)
22const IG_C: i64 = 12345 // LCG increment
23const IG_SRCCAP: i64 = 8192
24const IG_PATHCAP: i64 = 256
25const IG_ZERO: i64 = 48
26const IG_MODE: i64 = 420 // 0644
27const IG_MAXG: i64 = 3 // guard-clause ceiling
28const IG_MAXT: i64 = 7 // terms-per-expression ceiling
29
30static g_rng: i64
31
32func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
33// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
34// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
35// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
36// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
37func wn(v: i64) -> i64 { nxi_out(v); return 0 }
38func bcat(b: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; var o: i64 = off; while s[i] != (0 as u8) { b[o] = s[i]; o = o + 1; i = i + 1 } return o }
39func bcatn(b: *u8, off: i64, v: i64) -> i64 {
40 var m: i64 = v
41 var o: i64 = off
42 if m < 0 { b[o] = 45 as u8; o = o + 1; m = 0 - m }
43 let t: *u8 = sys_mmap(24)
44 var k: i64 = 0
45 if m == 0 { t[0] = IG_ZERO as u8; k = 1 }
46 while m > 0 { t[k] = (IG_ZERO + (m % 10)) as u8; m = m / 10; k = k + 1 }
47 var i: i64 = 0
48 while i < k { b[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
49 return o
50}
51
52// seeded LCG -> non-negative i64 (low-bit quality is fine for a curriculum, not crypto)
53func ig_next() -> i64 { g_rng = g_rng * IG_A + IG_C; var v: i64 = g_rng; if v < 0 { v = 0 - v } return v }
54func ig_rand(n: i64) -> i64 { if n <= 0 { return 0 } return ig_next() % n }
55
56// a parameter reference only (a/b/c within arity) -- for positions that MUST be input-dependent
57func ig_param(b: *u8, o: i64, arity: i64) -> i64 { b[o] = (97 + ig_rand(arity)) as u8; return o + 1 }
58// one leaf: PARAM-BIASED (param prob ~= arity/(arity+1)) so expressions are input-dependent, not
59// constant-folded. const range 1..9 (never 0 -> no `+0`/`*0` degenerate terms).
60func ig_leaf(b: *u8, o: i64, arity: i64) -> i64 {
61 let pick: i64 = ig_rand(arity + 1)
62 if pick < arity { b[o] = (97 + pick) as u8; return o + 1 } // 'a'+idx
63 return bcatn(b, o, 1 + ig_rand(9))
64}
65// arithmetic op: + - * (all mutable by bugforge's op table)
66func ig_aop(b: *u8, o: i64) -> i64 {
67 let p: i64 = ig_rand(3)
68 var o2: i64 = bcat(b, o, " " as *u8)
69 if p == 0 { b[o2] = 43 as u8 }
70 if p == 1 { b[o2] = 45 as u8 }
71 if p == 2 { b[o2] = 42 as u8 }
72 o2 = o2 + 1
73 return bcat(b, o2, " " as *u8)
74}
75// comparison op: < > == (< and > are mutable by ltgt/gtlt)
76func ig_cop(b: *u8, o: i64) -> i64 {
77 let p: i64 = ig_rand(3)
78 if p == 0 { return bcat(b, o, " < " as *u8) }
79 if p == 1 { return bcat(b, o, " > " as *u8) }
80 return bcat(b, o, " == " as *u8)
81}
82// FLAT expression (iterative, recursion-free): leaf (aop leaf){k-1}, with ONE optional paren group.
83func ig_expr(b: *u8, o: i64, arity: i64, nterms: i64) -> i64 {
84 var oo: i64 = ig_leaf(b, o, arity)
85 var i: i64 = 1
86 // optional single parenthesized pair mid-expression to add structure at higher difficulty
87 let parenat: i64 = 1 + ig_rand(nterms)
88 while i < nterms {
89 oo = ig_aop(b, oo)
90 if i == parenat { if nterms >= 4 {
91 oo = bcat(b, oo, "(" as *u8)
92 oo = ig_leaf(b, oo, arity)
93 oo = ig_aop(b, oo)
94 oo = ig_leaf(b, oo, arity)
95 oo = bcat(b, oo, ")" as *u8)
96 } else { oo = ig_leaf(b, oo, arity) } }
97 else { oo = ig_leaf(b, oo, arity) }
98 i = i + 1
99 }
100 return oo
101}
102
103// generate one function body into src; returns length. name pre-written by caller up to " {".
104func ig_fnbody(src: *u8, o0: i64, arity: i64, diff: i64) -> i64 {
105 var o: i64 = o0
106 let nguard: i64 = 1 + ig_rand(IG_MAXG)
107 var g: i64 = 0
108 while g < nguard {
109 // guard condition: LEFT is always a parameter so the branch is input-dependent (no `if 0==3`
110 // constant-dead guards); RIGHT is a param or const.
111 o = bcat(src, o, " if " as *u8)
112 o = ig_param(src, o, arity)
113 o = ig_cop(src, o)
114 o = ig_leaf(src, o, arity)
115 o = bcat(src, o, " { return " as *u8)
116 var nt1: i64 = 2 + ig_rand(diff + 1)
117 if nt1 > IG_MAXT { nt1 = IG_MAXT }
118 o = ig_expr(src, o, arity, nt1)
119 o = bcat(src, o, " }\n" as *u8)
120 g = g + 1
121 }
122 o = bcat(src, o, " return " as *u8)
123 var nt2: i64 = 2 + ig_rand(diff + 2)
124 if nt2 > IG_MAXT { nt2 = IG_MAXT }
125 o = ig_expr(src, o, arity, nt2)
126 o = bcat(src, o, "\n}\n" as *u8)
127 return o
128}
129
130func ig_write(path: *u8, buf: *u8, n: i64) -> i64 {
131 let fd: i64 = sys_openat_wr(path, IG_MODE)
132 if fd < 0 { return 0 - 1 }
133 sys_write(fd, buf, n)
134 sys_close(fd)
135 return n
136}
137
138// emit one procedural function file ig_<seed>_<idx>.nx into outdir; returns 1 written
139func ig_one(outdir: *u8, seed: i64, idx: i64, diff: i64) -> i64 {
140 let src: *u8 = sys_mmap(IG_SRCCAP)
141 let fname: *u8 = sys_mmap(96)
142 var no: i64 = bcat(fname, 0, "ig_" as *u8)
143 no = bcatn(fname, no, seed)
144 no = bcat(fname, no, "_" as *u8)
145 no = bcatn(fname, no, idx)
146 fname[no] = 0 as u8
147 let arity: i64 = 1 + ig_rand(3)
148 var o: i64 = bcat(src, 0, "func " as *u8)
149 o = bcat(src, o, fname)
150 o = bcat(src, o, "(a: i64" as *u8)
151 if arity >= 2 { o = bcat(src, o, ", b: i64" as *u8) }
152 if arity >= 3 { o = bcat(src, o, ", c: i64" as *u8) }
153 o = bcat(src, o, ") -> i64 {\n" as *u8)
154 o = ig_fnbody(src, o, arity, diff)
155 let path: *u8 = sys_mmap(IG_PATHCAP)
156 var po: i64 = bcat(path, 0, outdir)
157 po = bcat(path, po, "/" as *u8)
158 po = bcat(path, po, fname)
159 po = bcat(path, po, ".nx" as *u8)
160 path[po] = 0 as u8
161 if ig_write(path, src, o) < 0 { return 0 }
162 return 1
163}
164
165func ig_gen(count: i64, seed: i64, diff: i64, outdir: *u8) -> i64 {
166 g_rng = seed
167 if g_rng == 0 { g_rng = 1 }
168 var d: i64 = diff
169 if d < 1 { d = 1 }
170 if d > 5 { d = 5 }
171 // best-effort mkdir via openat is not available; assume outdir exists (caller/selftest ensures)
172 var made: i64 = 0
173 var i: i64 = 0
174 while i < count {
175 made = made + ig_one(outdir, seed, i, d)
176 i = i + 1
177 }
178 w("NX-INFINIBUG gen count=" as *u8); wn(count)
179 w(" seed=" as *u8); wn(seed)
180 w(" difficulty=" as *u8); wn(d)
181 w(" written=" as *u8); wn(made)
182 w(" dir=" as *u8); w(outdir)
183 w(" (procedural world -- now: nx_bugforge mineadd <n> " as *u8); w(outdir); w(")\n" as *u8)
184 return 0
185}
186
187func ig_selftest() -> i64 {
188 var passn: i64 = 0
189 g_rng = 42
190 // T1 determinism: same seed -> same sequence
191 g_rng = 7
192 let x1: i64 = ig_next()
193 g_rng = 7
194 let x2: i64 = ig_next()
195 if x1 == x2 { passn = passn + 1; w("T1 determinism PASS\n" as *u8) } else { w("T1 FAIL\n" as *u8) }
196 // T2 ig_rand bounded
197 g_rng = 99
198 var ok2: i64 = 1
199 var i: i64 = 0
200 while i < 50 { let r: i64 = ig_rand(10); if r < 0 { ok2 = 0 } if r > 9 { ok2 = 0 } i = i + 1 }
201 if ok2 == 1 { passn = passn + 1; w("T2 rand-bounded PASS\n" as *u8) } else { w("T2 FAIL\n" as *u8) }
202 // T3 generated body has a mutable operator + balanced parens + a guard
203 g_rng = IG_MAGIC_12345
204 let src: *u8 = sys_mmap(IG_SRCCAP)
205 var o: i64 = bcat(src, 0, "func t(a: i64, b: i64) -> i64 {\n" as *u8)
206 o = ig_fnbody(src, o, 2, 3)
207 src[o] = 0 as u8
208 var opn: i64 = 0
209 var depth: i64 = 0
210 var mindepth: i64 = 0
211 var hasif: i64 = 0
212 var hasret: i64 = 0
213 var z: i64 = 0
214 while z < o {
215 let c: i64 = src[z] as i64
216 if c == 40 { depth = depth + 1 }
217 if c == 41 { depth = depth - 1; if depth < mindepth { mindepth = depth } }
218 if c == 43 { opn = opn + 1 }
219 if c == 45 { opn = opn + 1 }
220 if c == 42 { opn = opn + 1 }
221 if c == 105 { if src[z+1] == (102 as u8) { hasif = 1 } }
222 if c == 114 { if src[z+1] == (101 as u8) { hasret = 1 } }
223 z = z + 1
224 }
225 var ok3: i64 = 0
226 if opn >= 1 { if depth == 0 { if mindepth == 0 { if hasif == 1 { if hasret == 1 { ok3 = 1 } } } } }
227 if ok3 == 1 { passn = passn + 1; w("T3 body-shape PASS (ops=" as *u8); wn(opn); w(")\n" as *u8) } else { w("T3 FAIL ops=" as *u8); wn(opn); w(" depth=" as *u8); wn(depth); w(" if=" as *u8); wn(hasif); w("\n" as *u8) }
228 // T4 two different seeds -> different first function text
229 let s1: *u8 = sys_mmap(IG_SRCCAP)
230 g_rng = 100
231 let l1: i64 = ig_fnbody(s1, 0, 2, 3)
232 let s2: *u8 = sys_mmap(IG_SRCCAP)
233 g_rng = 200
234 let l2: i64 = ig_fnbody(s2, 0, 2, 3)
235 var diff4: i64 = 0
236 if l1 != l2 { diff4 = 1 } else { var q: i64 = 0; while q < l1 { if s1[q] != s2[q] { diff4 = 1; q = l1 } else { q = q + 1 } } }
237 if diff4 == 1 { passn = passn + 1; w("T4 seed-variety PASS\n" as *u8) } else { w("T4 FAIL (identical)\n" as *u8) }
238 w("NX-INFINIBUG selftest " as *u8); wn(passn); w("/4 " as *u8)
239 if passn == 4 { w("VERDICT=GREEN\n" as *u8); return 0 }
240 w("VERDICT=RED\n" as *u8)
241 return 1
242}
243
244func main(argc: i64, argv: *i64) -> i64 {
245 var verb: *u8 = "selftest" as *u8
246 if argc > 1 { verb = argv[1] as *u8 }
247 if verb[0] == (103 as u8) {
248 if argc < 4 { w("usage: nx_infinibug gen <count> <seed> <difficulty> [outdir]\n" as *u8); return 2 }
249 var cnt: i64 = 0
250 var ci: i64 = 0
251 let ca: *u8 = argv[2] as *u8
252 while ca[ci] != (0 as u8) { if ca[ci] >= (48 as u8) { if ca[ci] <= (57 as u8) { cnt = cnt * 10 + ((ca[ci] as i64) - 48) } } ci = ci + 1 }
253 var sd: i64 = 0
254 var si: i64 = 0
255 let sa: *u8 = argv[3] as *u8
256 while sa[si] != (0 as u8) { if sa[si] >= (48 as u8) { if sa[si] <= (57 as u8) { sd = sd * 10 + ((sa[si] as i64) - 48) } } si = si + 1 }
257 var df: i64 = 3
258 if argc > 4 { var v: i64 = 0; var di: i64 = 0; let da: *u8 = argv[4] as *u8; while da[di] != (0 as u8) { if da[di] >= (48 as u8) { if da[di] <= (57 as u8) { v = v * 10 + ((da[di] as i64) - 48) } } di = di + 1 } if v > 0 { df = v } }
259 var outdir: *u8 = "runtime/igworld" as *u8
260 if argc > 5 { outdir = argv[5] as *u8 }
261 if cnt <= 0 { cnt = 8 }
262 return ig_gen(cnt, sd, df, outdir)
263 }
264 return ig_selftest()
265}