code wiki / _hdl_build / nx_self_compose.nx
nx_self_compose.nx source
↩ module page · 154 lines · 7366 B
1// nx_self_compose.nx -- AUTONOMOUS compose+derive (the rung up: the team composes its OWN
2// targets, no Claude posing them). For each seed: COMPOSE a RANDOM non-trivial target program
3// T (random op-list over {a,b,+a,+b,*a,*b}; rerolled until it depends on BOTH inputs), then
4// DERIVE a program G that nmatches T's examples (search sees only (a,b)->T(a,b) points, not T),
5// then VERIFY G == T on HELD-OUT points. So the team picks WHAT to build (random T) AND builds
6// it (derives G), zero Claude per-target. Proves the machinery is GENERAL (arbitrary targets,
7// not hardcoded) AND that specs can be team-composed. Claude authored only the grammar/eval/
8// search (substrate). license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
11const EVO_MAGIC_2862933555777941757: i64 = 2862933555777941757
12const EVO_MAGIC_3037000493: i64 = 3037000493
13const EVO_MAGIC_4000000: i64 = 4000000
14const EVO_MAGIC_2000000: i64 = 2000000
15const EVO_MAGIC_1000000000: i64 = 1000000000
16const EVO_MAGIC_2654435761: i64 = 2654435761
17const EVO_MAGIC_12345: i64 = 12345
18
19const GLEN: i64 = 4
20const EVO_P: i64 = 256
21const EVO_G: i64 = 1500
22const EVO_T: i64 = 5
23const NTRAIN: i64 = 6
24const NPTS: i64 = 10
25
26func sc_rand(s: *i64) -> i64 { s[0] = s[0] * EVO_MAGIC_2862933555777941757 + EVO_MAGIC_3037000493; return (s[0] >> 17) & 0x3fffffff }
27func sc_abs(x: i64) -> i64 { if x < 0 { return 0 - x } return x }
28func sc_pa(i: i64) -> i64 { if i==0 {return 2} if i==1 {return 4} if i==2 {return 3} if i==3 {return 5} if i==4 {return 6} if i==5 {return 1} if i==6 {return 7} if i==7 {return 3} if i==8 {return 8} return 4 }
29func sc_pb(i: i64) -> i64 { if i==0 {return 3} if i==1 {return 5} if i==2 {return 2} if i==3 {return 1} if i==4 {return 2} if i==5 {return 4} if i==6 {return 2} if i==7 {return 3} if i==8 {return 1} return 4 }
30
31// the op machine (the shared substrate eval).
32func sc_eval(gen: *i64, base: i64, a: i64, b: i64) -> i64 {
33 var acc: i64 = 0; var j: i64 = 0
34 while j < GLEN {
35 let op: i64 = gen[base + j]
36 if op == 0 { acc = a }
37 if op == 1 { acc = b }
38 if op == 2 { acc = acc + a }
39 if op == 3 { acc = acc + b }
40 if op == 4 { acc = acc * a }
41 if op == 5 { acc = acc * b }
42 j = j + 1
43 }
44 return acc
45}
46
47// COMPOSE: fill T with a random non-trivial 4-op target (depends on both a and b).
48func sc_compose(state: *i64, T: *i64) -> i64 {
49 var tries: i64 = 0
50 while tries < 200 {
51 var j: i64 = 0
52 while j < GLEN { T[j] = sc_rand(state) % 6; j = j + 1 }
53 let y00: i64 = sc_eval(T, 0, 2, 3)
54 let ya: i64 = sc_eval(T, 0, 7, 3)
55 let yb: i64 = sc_eval(T, 0, 2, 8)
56 if y00 != ya { if y00 != yb { return 1 } } // depends on a AND on b
57 tries = tries + 1
58 }
59 return 0
60}
61
62// fitness of a candidate G vs the composed target T over the TRAIN points (clamped, overflow-safe).
63func sc_fit(pop: *i64, base: i64, T: *i64) -> i64 {
64 var err: i64 = 0; var i: i64 = 0
65 while i < NTRAIN {
66 let a: i64 = sc_pa(i); let b: i64 = sc_pb(i)
67 let r: i64 = sc_eval(pop, base, a, b)
68 let y: i64 = sc_eval(T, 0, a, b)
69 var d: i64 = EVO_MAGIC_4000000
70 if r >= 0 { if r <= EVO_MAGIC_2000000 { d = sc_abs(r - y) } }
71 err = err + d; i = i + 1
72 }
73 return err
74}
75func sc_tourney(fit: *i64, state: *i64) -> i64 {
76 var bi: i64 = sc_rand(state) % EVO_P; var bd: i64 = fit[bi]; var k: i64 = 1
77 while k < EVO_T { let i: i64 = sc_rand(state) % EVO_P; if fit[i] < bd { bd = fit[i]; bi = i } k = k + 1 }
78 return bi
79}
80
81// DERIVE: search a program G nmatching T's examples; store in G, return best_err.
82func sc_derive(T: *i64, state: *i64, G: *i64) -> i64 {
83 let pop: *i64 = sys_mmap(EVO_P * GLEN * 8) as *i64
84 let nxt: *i64 = sys_mmap(EVO_P * GLEN * 8) as *i64
85 let fit: *i64 = sys_mmap(EVO_P * 8) as *i64
86 var p: i64 = 0
87 while p < EVO_P { var j: i64 = 0; while j < GLEN { pop[p*GLEN + j] = sc_rand(state) % 6; j = j + 1 } p = p + 1 }
88 var best_err: i64 = EVO_MAGIC_1000000000
89 var g: i64 = 0
90 while g < EVO_G {
91 var gbest: i64 = EVO_MAGIC_1000000000; var gbp: i64 = 0
92 p = 0
93 while p < EVO_P { let e: i64 = sc_fit(pop, p*GLEN, T); fit[p] = e; if e < gbest { gbest = e; gbp = p } p = p + 1 }
94 if gbest < best_err { best_err = gbest; var j: i64 = 0; while j < GLEN { G[j] = pop[gbp*GLEN + j]; j = j + 1 } }
95 if best_err == 0 { g = EVO_G } else {
96 var j2: i64 = 0; while j2 < GLEN { nxt[j2] = G[j2]; j2 = j2 + 1 }
97 p = 1
98 while p < EVO_P {
99 let pa: i64 = sc_tourney(fit, state) * GLEN
100 let pb: i64 = sc_tourney(fit, state) * GLEN
101 let cut: i64 = (sc_rand(state) % (GLEN - 1)) + 1
102 var jj: i64 = 0
103 while jj < GLEN { if jj < cut { nxt[p*GLEN + jj] = pop[pa + jj] } else { nxt[p*GLEN + jj] = pop[pb + jj] } jj = jj + 1 }
104 let slot: i64 = sc_rand(state) % GLEN
105 nxt[p*GLEN + slot] = sc_rand(state) % 6
106 p = p + 1
107 }
108 var c: i64 = 0; while c < EVO_P * GLEN { pop[c] = nxt[c]; c = c + 1 }
109 g = g + 1
110 }
111 }
112 return best_err
113}
114
115func sc_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
116// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
117// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
118// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
119// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
120func sc_pn(v: i64) -> i64 { nxi_out(v); return 0 }
121func sc_ops(label: *u8, gen: *i64) -> i64 {
122 sc_p(label)
123 var j: i64 = 0
124 while j < GLEN { sc_pn(gen[j]); sc_p(" " as *u8); j = j + 1 }
125 return 0
126}
127
128// one autonomous round: compose a random target, derive it, verify on all points.
129func sc_run(seed: i64) -> i64 {
130 let state: *i64 = sys_mmap(8) as *i64; state[0] = seed * EVO_MAGIC_2654435761 + EVO_MAGIC_12345
131 let T: *i64 = sys_mmap(GLEN * 8) as *i64
132 let G: *i64 = sys_mmap(GLEN * 8) as *i64
133 if sc_compose(state, T) != 1 { sc_p("seed=" as *u8); sc_pn(seed); sc_p(" COMPOSE-FAIL\n" as *u8); return 0 }
134 let de: i64 = sc_derive(T, state, G)
135 var nmatch: i64 = 0; var i: i64 = 0
136 while i < NPTS { if sc_eval(G, 0, sc_pa(i), sc_pb(i)) == sc_eval(T, 0, sc_pa(i), sc_pb(i)) { nmatch = nmatch + 1 } i = i + 1 }
137 sc_p("seed=" as *u8); sc_pn(seed); sc_ops(" composed T=[" as *u8, T); sc_ops("] derived G=[" as *u8, G)
138 sc_p("] derive_err=" as *u8); sc_pn(de); sc_p(" nmatch=" as *u8); sc_pn(nmatch); sc_p("/" as *u8); sc_pn(NPTS)
139 if nmatch == NPTS { sc_p(" GREEN\n" as *u8); return 1 }
140 sc_p(" RED\n" as *u8); return 0
141}
142
143func main() -> i64 {
144 var ok: i64 = 0
145 if sc_run(11) == 1 { ok = ok + 1 }
146 if sc_run(22) == 1 { ok = ok + 1 }
147 if sc_run(33) == 1 { ok = ok + 1 }
148 if sc_run(44) == 1 { ok = ok + 1 }
149 if sc_run(55) == 1 { ok = ok + 1 }
150 sc_p("SELFCOMPOSE: " as *u8); sc_pn(ok); sc_p("/5 random targets AUTONOMOUSLY composed + derived + verified on held-out (no Claude per-target)\n" as *u8)
151 if ok == 5 { sys_exit(0); return 0 }
152 sys_exit(1)
153 return 1
154}