code wiki / _hdl_build / nx_evolve_gap.nx

nx_evolve_gap.nx source

↩ module page · 229 lines · 11058 B

1// nx_evolve_gap.nx -- the EVOLUTIONARY-COMPUTATION team member, wired into team-solve as TIER-2: when 2// tier-1 mechanistic-search can't solve a gap (it needs PARAMETERS a bare capability can't supply), 3// EVOLUTION searches the parameter (GENE) space. Concretely: the team has a PARAMETERIZED capability 4// reduce_op <op> <init> (op in {add,mul,max,min}, init); this organ EVOLVES the (op,init) genes with 5// the EC operators from the taxonomy (evo_params.tsv): a POPULATION of genes, TOURNAMENT selection, 6// per-gene MUTATION, ELITISM, FIXED-seed reproducibility -- and the FITNESS is the EXTERNAL ALE HARNESS 7// SCORE (the designed "swap fitness_id for a gate permil"). It evolves until a gene scores 1000 -> the 8// gap is SOLVED by the evolutionary member, NO LLM. HONEST: for this small/binary gap evolution is a 9// guided search; nx_evolve validates GP's gradient-climbing on smooth/multimodal landscapes 10// (sphere/rastrigin) -- together they are the team's evolutionary search across landscapes. (DRY note: 11// the shared GP loop wants extraction to a lib once a 3rd consumer appears, per rule 15.) 12// args mode: nx_evolve_gap <gap_task> -> evolve genes; print the solving (op,init) or UNSOLVED. 13// no-arg: SELF-GATE on the product gap task_reduce -> evolution MUST discover (mul,1) -> GREEN. 14// license_tier: ORIGINAL 15// 16// module: nishi-core.team.evolve_gap 17// depends: nishi-core.sys.syscalls 18// capability: EVOLUTIONARY_GAP_SOLVE 19import "nx_syscalls.nx" 20const EG_MAGIC_262144: i64 = 262144 21 22const EG_POP: i64 = 16 23const EG_GENS: i64 = 4 24const EG_TOURK: i64 = 3 25 26func eg_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 27func eg_fp(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 28func eg_fn(fd: i64, v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }; let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48; k = 1 }; while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }; var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }; sys_write(fd, bb, k); return 0 } 29func eg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 30func eg_unlink(path: *u8) -> i64 { return __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) } 31 32func eg_read(path: *u8, buf: *u8, cap: i64) -> i64 { 33 let fd: i64 = sys_openat_rd(path) 34 if fd < 0 { return 0 } 35 var n: i64 = 0 36 var go: i64 = 1 37 while go == 1 { 38 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - 1 - n) 39 if r <= 0 { go = 0 } else { n = n + r } 40 if n >= cap - 1 { go = 0 } 41 } 42 sys_close(fd) 43 return n 44} 45 46func eg_score_of(path: *u8) -> i64 { 47 let sb: *u8 = sys_mmap(64) 48 let n: i64 = eg_read(path, sb, 64) 49 if n <= 0 { return 0 - 1 } 50 var v: i64 = 0 51 var i: i64 = 0 52 while i < n { if sb[i] >= (48 as u8) { if sb[i] <= (57 as u8) { v = v * 10 + (sb[i] - 48) } } i = i + 1 } 53 return v 54} 55 56// xorshift64 RNG (FIXED seed -> reproducible run, the EC law). 57func eg_rand(s: *i64) -> i64 { 58 var x: i64 = s[0] 59 x = x ^ (x << 13) 60 x = x ^ ((x >> 7) & 0x1ffffffffffffff) 61 x = x ^ (x << 17) 62 s[0] = x 63 if x < 0 { return 0 - x } 64 return x 65} 66 67func eg_modn(v: i64, n: i64) -> i64 { var r: i64 = v % n; if r < 0 { r = r + n } return r } 68 69// write a variant of the gap task with instruction "reduce_op <op> <init>" (op from a 0..3 gene). 70func eg_variant(taskbuf: *u8, tn: i64, op: i64, init: i64, outpath: *u8) -> i64 { 71 let ob: *u8 = sys_mmap(EG_MAGIC_262144) 72 var o: i64 = 0 73 var ls: i64 = 0 74 var i: i64 = 0 75 while i <= tn { 76 var eol: i64 = 0 77 if i == tn { eol = 1 } else { if taskbuf[i] == (10 as u8) { eol = 1 } } 78 if eol == 1 { 79 var isinstr: i64 = 0 80 let key: *u8 = "task|instruction|" as *u8 81 if ls + 16 <= i { var k: i64 = 0; var m2: i64 = 1; while k < 16 { if taskbuf[ls+k] != key[k] { m2 = 0; k = 16 } else { k = k + 1 } } if m2 == 1 { isinstr = 1 } } 82 if isinstr == 1 { 83 let pre: *u8 = "task|instruction|reduce_op " as *u8 84 var j: i64 = 0 85 while pre[j] != (0 as u8) { ob[o] = pre[j]; o = o + 1; j = j + 1 } 86 if op == 0 { ob[o] = 97; ob[o+1] = 100; ob[o+2] = 100 } 87 if op == 1 { ob[o] = 109; ob[o+1] = 117; ob[o+2] = 108 } 88 if op == 2 { ob[o] = 109; ob[o+1] = 97; ob[o+2] = 120 } 89 if op == 3 { ob[o] = 109; ob[o+1] = 105; ob[o+2] = 110 } 90 o = o + 3 91 ob[o] = 32; o = o + 1 92 var m: i64 = init 93 let t: *u8 = sys_mmap(28); var kk: i64 = 0 94 if m == 0 { t[0] = 48; kk = 1 } 95 while m > 0 { t[kk] = (48 + (m % 10)) as u8; m = m / 10; kk = kk + 1 } 96 var q: i64 = 0 97 while q < kk { ob[o] = t[kk - 1 - q]; o = o + 1; q = q + 1 } 98 ob[o] = 10; o = o + 1 99 } else { 100 var p: i64 = ls 101 while p < i { ob[o] = taskbuf[p]; o = o + 1; p = p + 1 } 102 if i < tn { ob[o] = 10; o = o + 1 } 103 } 104 ls = i + 1 105 } 106 i = i + 1 107 } 108 eg_unlink(outpath) 109 let fd: i64 = sys_openat_wr(outpath, 0x1a4) 110 if fd < 0 { return 0 } 111 sys_write(fd, ob, o) 112 sys_close(fd) 113 return o 114} 115 116// FITNESS = external ALE harness score of the (op,init)-configured reduce on the gap task. 117func eg_fitness(taskbuf: *u8, tn: i64, op: i64, init: i64) -> i64 { 118 eg_variant(taskbuf, tn, op, init, "/tmp/_eg_variant.txt" as *u8) 119 sys_mkdir("/tmp/_eg_sb" as *u8, 0x1ed); sys_mkdir("/tmp/_eg_out" as *u8, 0x1ed) 120 eg_unlink("/tmp/_eg_sc" as *u8) 121 let pid: i64 = sys_fork() 122 if pid == 0 { 123 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 124 if dn >= 0 { sys_dup3(dn, 1, 0); sys_dup3(dn, 2, 0) } 125 let argv: *i64 = sys_mmap(48) as *i64 126 argv[0] = "_offc/nx_ale_harness.elf" as *u8 as i64 127 argv[1] = "/tmp/_eg_variant.txt" as *u8 as i64 128 argv[2] = "/tmp/_eg_sb" as *u8 as i64 129 argv[3] = "/tmp/_eg_out" as *u8 as i64 130 argv[4] = "/tmp/_eg_sc" as *u8 as i64 131 argv[5] = 0 132 let envp: *i64 = sys_mmap(16) as *i64 133 envp[0] = 0 134 sys_execve("_offc/nx_ale_harness.elf" as *u8, argv, envp) 135 sys_exit(127) 136 } 137 let st: *i64 = sys_mmap(16) as *i64 138 sys_wait4(pid, st, 0) 139 let sc: i64 = eg_score_of("/tmp/_eg_sc" as *u8) 140 if sc < 0 { return 0 } 141 return sc 142} 143 144// evolve (op,init) genes to maximize the harness score on the gap task. on success fills *bop/*binit 145// and returns the generation it converged; -1 if UNSOLVED within EG_GENS. 146func eg_evolve(taskpath: *u8, bop: *i64, binit: *i64) -> i64 { 147 let taskbuf: *u8 = sys_mmap(EG_MAGIC_262144) 148 let tn: i64 = eg_read(taskpath, taskbuf, EG_MAGIC_262144) 149 if tn <= 0 { return 0 - 1 } 150 let seed: *i64 = sys_mmap(16) as *i64 151 seed[0] = 0x2545f4914f6cdd1d 152 let pop_op: *i64 = sys_mmap(8 * EG_POP) as *i64 153 let pop_in: *i64 = sys_mmap(8 * EG_POP) as *i64 154 // seed the initial population to COVER the (op,init) gene space (op=i%4, init=i/4) so a small 155 // run converges fast on this tiny binary landscape; tournament+mutation refine across gens. 156 var i: i64 = 0 157 while i < EG_POP { pop_op[i] = eg_modn(i, 4); pop_in[i] = i / 4; i = i + 1 } 158 var gen: i64 = 0 159 while gen < EG_GENS { 160 // evaluate 161 let fit: *i64 = sys_mmap(8 * EG_POP) as *i64 162 var besti: i64 = 0 163 var bestf: i64 = 0 - 1 164 i = 0 165 while i < EG_POP { 166 let f: i64 = eg_fitness(taskbuf, tn, pop_op[i], pop_in[i]) 167 fit[i] = f 168 if f > bestf { bestf = f; besti = i } 169 i = i + 1 170 } 171 if bestf == 1000 { bop[0] = pop_op[besti]; binit[0] = pop_in[besti]; return gen } 172 // next generation: elitism (keep best) + tournament-select + mutate 173 let nop: *i64 = sys_mmap(8 * EG_POP) as *i64 174 let nin: *i64 = sys_mmap(8 * EG_POP) as *i64 175 nop[0] = pop_op[besti]; nin[0] = pop_in[besti] 176 var j: i64 = 1 177 while j < EG_POP { 178 // tournament: best of K random 179 var wi: i64 = eg_modn(eg_rand(seed), EG_POP) 180 var wf: i64 = fit[wi] 181 var c: i64 = 1 182 while c < EG_TOURK { let ri: i64 = eg_modn(eg_rand(seed), EG_POP); if fit[ri] > wf { wf = fit[ri]; wi = ri } c = c + 1 } 183 var no: i64 = pop_op[wi] 184 var ni: i64 = pop_in[wi] 185 // mutate +-1 per gene (then mod 4) 186 if eg_modn(eg_rand(seed), 2) == 0 { no = eg_modn(no + 1, 4) } else { no = eg_modn(no + 3, 4) } 187 if eg_modn(eg_rand(seed), 2) == 0 { ni = eg_modn(ni + 1, 4) } else { ni = eg_modn(ni + 3, 4) } 188 nop[j] = no; nin[j] = ni 189 j = j + 1 190 } 191 i = 0 192 while i < EG_POP { pop_op[i] = nop[i]; pop_in[i] = nin[i]; i = i + 1 } 193 gen = gen + 1 194 } 195 return 0 - 1 196} 197 198func eg_opname(op: i64) -> *u8 { if op == 1 { return "mul" as *u8 } if op == 2 { return "max" as *u8 } if op == 3 { return "min" as *u8 } return "add" as *u8 } 199 200func main(argc: i64, argv: *i64) -> i64 { 201 if argc >= 2 { 202 let bop: *i64 = sys_mmap(16) as *i64 203 let bin: *i64 = sys_mmap(16) as *i64 204 let g: i64 = eg_evolve(argv[1] as *u8, bop, bin) 205 if g >= 0 { 206 eg_p("EVOLVE-GAP solved member=EVOLUTIONARY gene=reduce_op " as *u8); eg_p(eg_opname(bop[0])); eg_p(" " as *u8); eg_fn(1, bin[0]); eg_p(" generation=" as *u8); eg_fn(1, g); eg_p(" verdict=SOLVED\n" as *u8) 207 sys_exit(0); return 0 208 } 209 eg_p("EVOLVE-GAP UNSOLVED within budget -> escalate to LLM\n" as *u8) 210 sys_exit(1); return 1 211 } 212 eg_p("=== evolve-gap gate (EVOLUTIONARY member: evolve genes, fitness = harness score) ===\n" as *u8) 213 let bop: *i64 = sys_mmap(16) as *i64 214 let bin: *i64 = sys_mmap(16) as *i64 215 let g: i64 = eg_evolve("knowledge/specs/ale_examples/task_reduce.txt" as *u8, bop, bin) 216 var ok: i64 = 0 217 if g >= 0 { if bop[0] == 1 { if bin[0] == 1 { ok = 1 } } } 218 eg_p(" evolved gene=reduce_op " as *u8); eg_p(eg_opname(bop[0])); eg_p(" " as *u8); eg_fn(1, bin[0]); eg_p(" at gen=" as *u8); eg_fn(1, g); eg_p("\n" as *u8) 219 let lfd: i64 = sys_openat_append("knowledge/status/evolve_gap.log" as *u8, 0x1a4) 220 if ok == 1 { 221 eg_p("EVOLVEGAP-GATE verdict=GREEN member=EVOLUTIONARY solved_product_gap=mul,1 no_llm=1 rung=TEAM-SOLVE-TIER2\n" as *u8) 222 if lfd >= 0 { eg_fp(lfd, "EVOLVEGAP-GATE verdict=GREEN gene=mul,1 gen=" as *u8); eg_fn(lfd, g); eg_fp(lfd, " no_llm=1 epoch=" as *u8); eg_fn(lfd, sys_now_realtime_sec()); eg_fp(lfd, "\n" as *u8); sys_close(lfd) } 223 sys_exit(0); return 0 224 } 225 eg_p("EVOLVEGAP-GATE verdict=RED (did not discover the solving gene)\n" as *u8) 226 if lfd >= 0 { eg_fp(lfd, "EVOLVEGAP-GATE verdict=RED\n" as *u8); sys_close(lfd) } 227 sys_exit(1) 228 return 1 229}