code wiki / _hdl_build / nx_synth_test.nx

nx_synth_test.nx source

↩ module page · 97 lines · 4085 B

1// nx_synth_test.nx -- watch the team WRITE programs from specs. Each target is given 2// ONLY as input/output examples; the synthesizer discovers a program, which is then 3// checked on HELD-OUT inputs (so it generalizes -- not memorised). I wrote no 4// program here; the search wrote all of them. Known answer: every target synthesized 5// + held-out-verified -> exit 0. 6 7import "nx_synth.nx" 8 9func sy_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func sy_num(v: i64) -> i64 { 11 let b: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 12 let t: *u8 = sys_mmap(28); var k: i64 = 0 13 if m == 0 { t[0] = 48; k = 1 } 14 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 } 15 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 16 sys_write(1, b, k); return 0 17} 18func sy_opname(o: i64) -> *u8 { 19 if o == OP_ADD { return "add" as *u8 } 20 if o == OP_SUB { return "sub" as *u8 } 21 if o == OP_MUL { return "mul" as *u8 } 22 return "shl" as *u8 23} 24func sy_describe(op: *i64, a: *i64, b: *i64, L: i64) -> i64 { 25 var t: i64 = 0 26 while t < L { 27 sy_puts(" s" as *u8); sy_num(t + 2); sy_puts("=" as *u8); sy_puts(sy_opname(op[t])) 28 sy_puts("(s" as *u8); sy_num(a[t]); sy_puts("," as *u8) 29 if op[t] == OP_SHL { sy_puts("#" as *u8); sy_num(b[t]) } else { sy_puts("s" as *u8); sy_num(b[t]) } 30 sy_puts(")" as *u8) 31 t = t + 1 32 } 33 return 0 34} 35 36// the targets -- the synthesizer NEVER sees these formulas, only their outputs. 37func sy_target(id: i64, x: i64) -> i64 { 38 if id == 0 { return x * 7 } 39 if id == 1 { return x * x } 40 if id == 2 { return x * x + x } 41 if id == 3 { return x + 1 } 42 if id == 4 { return x + x } 43 return 0 44} 45func sy_name(id: i64) -> *u8 { 46 if id == 0 { return "f(x)=x*7" as *u8 } 47 if id == 1 { return "f(x)=x*x" as *u8 } 48 if id == 2 { return "f(x)=x*x+x" as *u8 } 49 if id == 3 { return "f(x)=x+1" as *u8 } 50 return "f(x)=2x" as *u8 51} 52 53func main() -> i64 { 54 sy_puts("=== the team WRITES programs from input/output examples (synthesis) ===\n" as *u8) 55 let ex_x: *i64 = sys_mmap(8 * 32) as *i64 56 let ex_y: *i64 = sys_mmap(8 * 32) as *i64 57 let op: *i64 = sys_mmap(8 * 4) as *i64 58 let a: *i64 = sys_mmap(8 * 4) as *i64 59 let b: *i64 = sys_mmap(8 * 4) as *i64 60 61 var written: i64 = 0 62 var generalized: i64 = 0 63 let ntargets: i64 = 5 64 var id: i64 = 0 65 while id < ntargets { 66 // spec = 24 examples x=0..23 (kept small so x*x fits sane ranges). 67 var nex: i64 = 0 68 var x: i64 = 0 69 while x < 24 { ex_x[nex] = x; ex_y[nex] = sy_target(id, x); nex = nex + 1; x = x + 1 } 70 71 let L: i64 = synth_find(ex_x, ex_y, nex, op, a, b) // WRITE the program 72 sy_puts(" " as *u8); sy_puts(sy_name(id)); sy_puts(" ->" as *u8) 73 if L == 0 { sy_puts(" (not found in bound)\n" as *u8); id = id + 1; } 74 else { 75 written = written + 1 76 sy_describe(op, a, b, L) 77 // verify on HELD-OUT inputs x=30..49 (never in the spec). 78 var ok: i64 = 1 79 var hx: i64 = 30 80 let syc: *i64 = sys_mmap(8 * 8) 81 while hx < 50 { if synth_eval(op, a, b, L, hx, syc) != sy_target(id, hx) { ok = 0 } hx = hx + 1 } 82 if ok == 1 { generalized = generalized + 1; sy_puts(" [held-out OK]\n" as *u8) } 83 else { sy_puts(" [OVERFIT -- held-out FAIL]\n" as *u8) } 84 id = id + 1 85 } 86 } 87 88 sy_puts("----------------------------------------------------------------\n" as *u8) 89 sy_puts(" programs WRITTEN by search: " as *u8); sy_num(written); sy_puts("/" as *u8); sy_num(ntargets) 90 sy_puts(" generalized (held-out): " as *u8); sy_num(generalized); sy_puts("/" as *u8); sy_num(ntargets); sy_puts("\n" as *u8) 91 sy_puts(" the team discovered each program from the goal -- I wrote no program here.\n" as *u8) 92 93 if written != ntargets { sys_exit(1); return 1 } 94 if generalized != ntargets { sys_exit(2); return 2 } 95 sys_exit(0) 96 return 0 97}