code wiki / _hdl_build / nx_evo_synth.nx

nx_evo_synth.nx source

↩ module page · 197 lines · 9718 B

1// nx_evo_synth.nx -- EVOLUTIONARY PROGRAM SYNTHESIS (X-AUT-006L): SELF-BUILDING CODE. 2// 3// The leap past the emitter ladder. Rungs 006g..006k made the team able to EMIT a 4// program from a hand-written DATA spec. This organ makes the team DISCOVER a 5// program by EVOLUTIONARY SEARCH -- it is given only a TARGET (a desired output for 6// a start input), NOT the answer, and SEARCHES op-list program-space until it finds 7// code that hits the target, then MATERIALIZES that discovered code as a real 8// sovereign compiled organ. Genotype (op-list genome) -> phenotype (its computed 9// result) -> fitness (distance to target) -> selection+mutation -> next generation: 10// this is genetic programming / an (1+lambda) evolution strategy, the substrate of 11// "evolutionary computation, self-building code". 12// 13// nx_evo_synth <champion_basename> <start> <target> <seed> 14// - deterministic (seeded LCG) so a run is reproducible/gateable. 15// - genome = EVO_L ops (opcode add/mul/sub + operand 1..9); pop = EVO_P; 16// gens = EVO_G; (1+lambda): elite best + lambda mutants of best each gen. 17// - prints FOUND/NEAR gen=<g> dist=<d> result=<r> genome=<ops>. 18// - WRITES runtime/_hdl_build/<champion_basename>.nx = the DISCOVERED program 19// (an op-list organ) so the gate can COMPILE+RUN it and confirm it really 20// produces the target -- the unfakeable proof the evolved code is real. 21// 22// no-false-green: different targets -> different DISCOVERED genomes, each verified by 23// compiling+running the materialized champion to the target; the champion is NOT 24// hand-written and (for non-trivial targets) NOT found at generation 0 -- the search 25// must climb. Sovereign, no gcc/.sh. HONEST SCOPE: linear op-list genomes over one 26// i64 (the 006g phenotype), distance fitness, mutation-only ES; NOT yet crossover / 27// branch+loop genomes / multi-example fitness -- but it is GENUINE program synthesis 28// by evolution, the seed of the research arc. license_tier: ORIGINAL 29import "nx_syscalls.nx" 30const EVO_MAGIC_2862933555777941757: i64 = 2862933555777941757 31const EVO_MAGIC_3037000493: i64 = 3037000493 32const EVO_MAGIC_2654435761: i64 = 2654435761 33const EVO_MAGIC_12345: i64 = 12345 34const EVO_MAGIC_1000000000: i64 = 1000000000 35const EVO_MAGIC_65536: i64 = 65536 36 37const EVO_L: i64 = 6 // ops per genome 38const EVO_P: i64 = 64 // population 39const EVO_G: i64 = 400 // max generations 40 41func evo_rand(state: *i64) -> i64 { 42 state[0] = state[0] * EVO_MAGIC_2862933555777941757 + EVO_MAGIC_3037000493 43 return (state[0] >> 17) & 0x3fffffff // 30-bit non-negative 44} 45func evo_abs(x: i64) -> i64 { if x < 0 { return 0 - x } return x } 46 47// apply a genome (EVO_L ops at base) to `start` -> result. op: 0=add 1=mul 2=sub. 48func evo_eval(pop: *i64, base: i64, start: i64) -> i64 { 49 var acc: i64 = start 50 var j: i64 = 0 51 while j < EVO_L { 52 let op: i64 = pop[base + j*2] 53 let n: i64 = pop[base + j*2 + 1] 54 if op == 0 { acc = acc + n } 55 if op == 1 { acc = acc * n } 56 if op == 2 { acc = acc - n } 57 j = j + 1 58 } 59 return acc 60} 61func evo_copy(pop: *i64, dst: i64, src: i64) -> i64 { 62 var j: i64 = 0 63 while j < EVO_L * 2 { pop[dst + j] = pop[src + j]; j = j + 1 } 64 return 0 65} 66// fill one genome slot (base) with random ops. 67func evo_randfill(pop: *i64, base: i64, state: *i64) -> i64 { 68 var j: i64 = 0 69 while j < EVO_L { 70 pop[base + j*2] = evo_rand(state) % 3 71 pop[base + j*2 + 1] = (evo_rand(state) % 9) + 1 72 j = j + 1 73 } 74 return 0 75} 76// human-readable op-list ("a5 m6 s2 ..") for the log. 77func evo_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i } 78func evo_catn(dst: *u8, off: i64, v: i64) -> i64 { 79 var o: i64 = off 80 if v < 0 { dst[o] = 45 as u8; o = o + 1; return evo_catn(dst, o, 0 - v) } 81 if v == 0 { dst[o] = 48 as u8; return o + 1 } 82 var m: i64 = v; let t: *u8 = sys_mmap(28); var k: i64 = 0 83 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 84 var i: i64 = 0 85 while i < k { dst[o+i] = t[k-1-i]; i = i + 1 } 86 return o + k 87} 88func evo_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 89func evo_atoi(s: *u8) -> i64 { 90 var n: i64 = 0; var i: i64 = 0; var neg: i64 = 0 91 if s[0] == (45 as u8) { neg = 1; i = 1 } 92 while s[i] != (0 as u8) { if s[i] >= (48 as u8) { if s[i] <= (57 as u8) { n = n * 10 + ((s[i] as i64) - 48) } } i = i + 1 } 93 if neg == 1 { return 0 - n } 94 return n 95} 96 97func main(argc: i64, argv: *i64) -> i64 { 98 if argc < 5 { evo_p("usage: nx_evo_synth <champion_basename> <start> <target> <seed>\n" as *u8); return 2 } 99 let base_name: *u8 = argv[1] as *u8 100 let start: i64 = evo_atoi(argv[2] as *u8) 101 let target: i64 = evo_atoi(argv[3] as *u8) 102 let seed: i64 = evo_atoi(argv[4] as *u8) 103 104 let state: *i64 = sys_mmap(8) as *i64 105 state[0] = seed * EVO_MAGIC_2654435761 + EVO_MAGIC_12345 // spread the seed 106 107 let glen: i64 = EVO_L * 2 108 let pop: *i64 = sys_mmap(EVO_P * glen * 8) as *i64 109 let best: *i64 = sys_mmap(glen * 8) as *i64 110 111 // ---- random initial population ---- 112 var p: i64 = 0 113 while p < EVO_P { evo_randfill(pop, p * glen, state); p = p + 1 } 114 115 var best_dist: i64 = EVO_MAGIC_1000000000 116 var best_gen: i64 = 0 - 1 117 var best_res: i64 = 0 118 var found: i64 = 0 119 var g: i64 = 0 120 while g < EVO_G { 121 // evaluate population, find the generation's best 122 var gen_best_dist: i64 = EVO_MAGIC_1000000000 123 var gen_best_p: i64 = 0 124 p = 0 125 while p < EVO_P { 126 let r: i64 = evo_eval(pop, p * glen, start) 127 let d: i64 = evo_abs(r - target) 128 if d < gen_best_dist { gen_best_dist = d; gen_best_p = p } 129 p = p + 1 130 } 131 // global best (elitism: monotonic non-increasing distance) 132 if gen_best_dist < best_dist { 133 best_dist = gen_best_dist 134 var j: i64 = 0 135 while j < glen { best[j] = pop[gen_best_p * glen + j]; j = j + 1 } 136 best_gen = g 137 best_res = evo_eval(best, 0, start) 138 } 139 if best_dist == 0 { found = 1; g = EVO_G } else { 140 // reproduce: slot 0 = elite best; slots 1..P-1 = single-point mutants of best 141 var j2: i64 = 0 142 while j2 < glen { pop[j2] = best[j2]; j2 = j2 + 1 } 143 p = 1 144 while p < EVO_P { 145 var jj: i64 = 0 146 while jj < glen { pop[p*glen + jj] = best[jj]; jj = jj + 1 } 147 let mi: i64 = evo_rand(state) % EVO_L 148 if (evo_rand(state) % 2) == 0 { 149 pop[p*glen + mi*2] = evo_rand(state) % 3 // mutate opcode 150 } else { 151 pop[p*glen + mi*2 + 1] = (evo_rand(state) % 9) + 1 // mutate operand 152 } 153 p = p + 1 154 } 155 g = g + 1 156 } 157 } 158 159 // ---- report ---- 160 if found == 1 { evo_p("EVO FOUND gen=" as *u8) } else { evo_p("EVO NEAR gen=" as *u8) } 161 let lb: *u8 = sys_mmap(64); var lo: i64 = 0 162 lo = evo_catn(lb, 0, best_gen); sys_write(1, lb, lo) 163 evo_p(" dist=" as *u8); lo = evo_catn(lb, 0, best_dist); sys_write(1, lb, lo) 164 evo_p(" result=" as *u8); lo = evo_catn(lb, 0, best_res); sys_write(1, lb, lo) 165 evo_p(" target=" as *u8); lo = evo_catn(lb, 0, target); sys_write(1, lb, lo) 166 evo_p(" genome=" as *u8) 167 var jg: i64 = 0 168 while jg < EVO_L { 169 let op: i64 = best[jg*2]; let n: i64 = best[jg*2+1] 170 if op == 0 { evo_p("a" as *u8) } else { if op == 1 { evo_p("m" as *u8) } else { evo_p("s" as *u8) } } 171 lo = evo_catn(lb, 0, n); sys_write(1, lb, lo); evo_p(" " as *u8) 172 jg = jg + 1 173 } 174 evo_p("\n" as *u8) 175 176 // ---- MATERIALIZE the discovered champion as a real sovereign organ ---- 177 let path: *u8 = sys_mmap(512); var po: i64 = 0 178 po = evo_cat(path, po, "runtime/_hdl_build/" as *u8); po = evo_cat(path, po, base_name); po = evo_cat(path, po, ".nx" as *u8); path[po] = 0 as u8 179 let buf: *u8 = sys_mmap(EVO_MAGIC_65536); var o: i64 = 0 180 o = evo_cat(buf, o, "// DISCOVERED BY nx_evo_synth (evolutionary program synthesis) -- this op-list was FOUND by search to hit a target, not hand-written. license_tier: ORIGINAL\n" as *u8) 181 o = evo_cat(buf, o, "import \"nx_syscalls.nx\"\nfunc main() -> i64 {\n var acc: i64 = " as *u8); o = evo_catn(buf, o, start); o = evo_cat(buf, o, "\n" as *u8) 182 jg = 0 183 while jg < EVO_L { 184 let op: i64 = best[jg*2]; let n: i64 = best[jg*2+1] 185 o = evo_cat(buf, o, " acc = acc " as *u8) 186 if op == 0 { o = evo_cat(buf, o, "+ " as *u8) } else { if op == 1 { o = evo_cat(buf, o, "* " as *u8) } else { o = evo_cat(buf, o, "- " as *u8) } } 187 o = evo_catn(buf, o, n); o = evo_cat(buf, o, "\n" as *u8) 188 jg = jg + 1 189 } 190 o = evo_cat(buf, o, " sys_write(1, \"RESULT=\" as *u8, 7)\n var mm: i64 = acc\n if mm < 0 { sys_write(1, \"-\" as *u8, 1); mm = 0 - mm }\n let t: *u8 = sys_mmap(28)\n var k: i64 = 0\n if mm == 0 { t[0] = 48 as u8; k = 1 }\n while mm > 0 { t[k] = (48 + (mm % 10)) as u8; mm = mm / 10; k = k + 1 }\n while k > 0 { k = k - 1; sys_write(1, (((t as i64)+k) as *u8), 1) }\n sys_write(1, \"\\n\" as *u8, 1)\n return 0\n}\n" as *u8) 191 let fd: i64 = sys_openat_wr(path, 420) 192 if fd < 0 { evo_p("EVO verdict=RED reason=champion-unwritable\n" as *u8); return 1 } 193 sys_write(fd, buf, o); sys_close(fd) 194 evo_p("EVO champion written: " as *u8); evo_p(path); evo_p("\n" as *u8) 195 if found == 1 { return 0 } 196 return 0 197}