code wiki / (root) / nx_canon_solver_gate.nx

nx_canon_solver_gate.nx source

↩ module page · 205 lines · 9693 B

1// nx_canon_solver_gate.nx -- GATE for the canon→constraint bridge (B1a, /world/procgen plan). Fixtures are 2// synthetic mini-canons ASSEMBLED AT RUNTIME with exactly-known typed placements, so the three outcomes are 3// asserted EXACTLY: CLEAN (deltas 0), ADJUSTED (the lint fires on precisely the planted defect and moves it 4// the right DIRECTION), INCONSISTENT (refused, worst named). gv-based. The REAL canon runs as a parse census 5// behind gv_need (its part indices are not yet identity-verified -- stated, not assumed). 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_part_solver_lib.nx" 9import "nx_gate_verdict.nx" 10 11func gc_wfile(path: *u8, s: *u8) -> i64 { 12 let fd: i64 = sys_openat_wr(path, 0x1a4) 13 if fd < 0 { return 0 } 14 sys_write(fd, s, ps_slen(s)) 15 sys_close(fd) 16 return 1 17} 18// run the bridge INLINE (same logic as the CLI: parse canon text -> part rows + rules -> solve). 19// Returns solver verdict; deltas checked by the caller via ps_x/y/z vs the known typed values. 20func gc_run(canon: *u8, rules: *u8) -> i64 { 21 let conf: *u8 = sys_mmap(65536) 22 // parse the canon the same way the organ does -- P rows only, fixed known layout for fixtures 23 // (fixture canons here use ONLY single-line P/R rows, so a tiny reader suffices; the organ's own 24 // reader is exercised end-to-end by the registered CLI -- this gate proves the SOLVE contract) 25 var o: i64 = 0 26 var i: i64 = 0 27 let n: i64 = ps_slen(canon) 28 var np: i64 = 0 29 while i < n { 30 if (canon[i] as i64) == 80 { 31 // P mirror rot ox oy oz ... 32 let pos: *i64 = sys_mmap(16) as *i64 33 pos[0] = i + 1 34 var e: i64 = i 35 var fe: i64 = 1 36 while fe == 1 { if e >= n { fe = 0 } else { if (canon[e] as i64) == 10 { fe = 0 } else { e = e + 1 } } } 37 gc_rd(canon, pos, e) 38 gc_rd(canon, pos, e) 39 let ox: i64 = gc_rd(canon, pos, e) 40 let oy: i64 = gc_rd(canon, pos, e) 41 let oz: i64 = gc_rd(canon, pos, e) 42 o = gc_cats(conf, o, "part p" as *u8) 43 o = gc_catn(conf, o, np) 44 o = gc_cats(conf, o, " " as *u8) 45 o = gc_catn(conf, o, ox) 46 o = gc_cats(conf, o, " " as *u8) 47 o = gc_catn(conf, o, oy) 48 o = gc_cats(conf, o, " " as *u8) 49 o = gc_catn(conf, o, oz) 50 o = gc_cats(conf, o, " 10\n" as *u8) 51 np = np + 1 52 i = e 53 } 54 i = i + 1 55 } 56 var q: i64 = 0 57 while rules[q] != (0 as u8) { conf[o] = rules[q]; o = o + 1; q = q + 1 } 58 if ps_load(conf, o) != 0 { return 0 - 9 } 59 return ps_solve() 60} 61func gc_rd(b: *u8, pos: *i64, end: i64) -> i64 { 62 var i: i64 = pos[0] 63 var go: i64 = 1 64 while go == 1 { 65 if i >= end { go = 0 } else { 66 let c: i64 = b[i] as i64 67 if c == 45 { go = 0 } else { if c >= 48 { if c <= 57 { go = 0 } else { i = i+1 } } else { i = i+1 } } 68 } 69 } 70 var sg: i64 = 1 71 if i < end { if (b[i] as i64) == 45 { sg = 0-1; i = i+1 } } 72 var v: i64 = 0 73 var g2: i64 = 1 74 while g2 == 1 { 75 if i >= end { g2 = 0 } else { 76 let c: i64 = b[i] as i64 77 if c >= 48 { if c <= 57 { v = v*10 + (c-48); i = i+1 } else { g2 = 0 } } else { g2 = 0 } 78 } 79 } 80 pos[0] = i 81 return v*sg 82} 83func gc_cats(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } return p } 84func gc_catn(d: *u8, o: i64, v: i64) -> i64 { 85 var p: i64 = o 86 var m: i64 = v 87 if m < 0 { d[p] = 45 as u8; p = p + 1; m = 0 - m } 88 if m == 0 { d[p] = 48 as u8; return p + 1 } 89 let t: *u8 = sys_mmap(32) 90 var k: i64 = 0 91 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 92 var i: i64 = 0 93 while i < k { d[p] = t[k-1-i]; p = p + 1; i = i + 1 } 94 return p 95} 96 97func main() -> i64 { 98 let ctr: *i64 = gv_ctr() 99 gv_head("nx_canon_solver_gate -- the canon beauty linter: CLEAN / ADJUSTED / INCONSISTENT asserted exactly" as *u8) 100 101 // mini-canon: head p0 at origin, eye-pair p1 at (33,5,40), mouth p2 at (0,-70,20) 102 let canon: *u8 = "P 0 0 0 0 0 0\nR 0 0 0 100 100\nP 1 90 33 5 40 1\nR 0 0 0 12 12\nP 0 0 0 -70 20 0\nR 0 0 0 10 8\n" as *u8 103 104 // T1 CLEAN: rules the typed canon already satisfies -> solved, every part delta 0 105 let r1: *u8 = "station p1 30 44\ninside p1 p0 80\nband p2 p0 60 90\n" as *u8 106 var t1: i64 = 0 107 if gc_run(canon, r1) == 1 { 108 if ps_x(1) == 33 { if ps_y(1) == 5 { if ps_z(1) == 40 { if ps_x(2) == 0 { if ps_z(2) == 20 { t1 = 1 } } } } } 109 } 110 gv_check("T1 CLEAN: satisfying canon passes with zero deltas (typed positions untouched)" as *u8, t1, ctr) 111 112 // T2 LINT fires on the planted defect ONLY: p2 station band [40,60] while typed z=20 113 let r2: *u8 = "station p1 30 44\nstation p2 40 60\n" as *u8 114 var t2: i64 = 0 115 if gc_run(canon, r2) == 1 { 116 if ps_z(2) >= 40 { if ps_z(2) <= 60 { 117 if ps_x(1) == 33 { if ps_y(1) == 5 { if ps_z(1) == 40 { t2 = 1 } } } 118 } } 119 } 120 gv_puts(" lint moved p2 z: 20 -> " as *u8); gv_num(ps_z(2)); gv_puts(" (band 40..60); p1 untouched\n" as *u8) 121 gv_check("T2 ADJUSTED: the planted band defect moves p2 into band, correct direction, others untouched" as *u8, t2, ctr) 122 123 // T3 INCONSISTENT: attach p1 to p0 at zero offset vs clear 400 -> refused, worst named 124 let r3: *u8 = "attach p1 p0 0 0 0\nclear p1 p0 400\n" as *u8 125 var t3: i64 = 0 126 if gc_run(canon, r3) == 0 { if ps_worst() >= 0 { t3 = 1 } } 127 gv_puts(" inconsistent worst=" as *u8); gv_puts(ps_kindname(ps_ckind(ps_worst()))); gv_puts("\n" as *u8) 128 gv_check("T3 INCONSISTENT: unsatisfiable rules refused with the worst constraint NAMED" as *u8, t3, ctr) 129 130 // T4 determinism 131 gc_run(canon, r2) 132 let z1: i64 = ps_z(2) 133 gc_run(canon, r2) 134 gv_check("T4 deterministic: identical solve on re-run" as *u8, ps_z(2) == z1, ctr) 135 136 // T6/T7 the ANCHOR-GUARD mechanism (documented placement as an immovable anchor part; `inside` 137 // moves ONLY the child): clean when the canon matches, lints ONLY the drifted part when it does not 138 let r4: *u8 = "part anchor 33 5 40 1\ninside p1 anchor 4\n" as *u8 139 var t6: i64 = 0 140 if gc_run(canon, r4) == 1 { if ps_x(1) == 33 { if ps_y(1) == 5 { if ps_z(1) == 40 { t6 = 1 } } } } 141 gv_check("T6 anchor-guard CLEAN: matching placement untouched (zero delta)" as *u8, t6, ctr) 142 let r5: *u8 = "part anchor 33 5 50 1\ninside p1 anchor 4\n" as *u8 143 var t7: i64 = 0 144 if gc_run(canon, r5) == 1 { 145 if ps_x(1) == 33 { if ps_z(1) >= 44 { if ps_z(1) <= 47 { if ps_x(2) == 0 { if ps_z(2) == 20 { t7 = 1 } } } } } 146 } 147 gv_puts(" drifted anchor: p1 z 40 -> " as *u8); gv_num(ps_z(1)); gv_puts(" (toward anchor z=50, tol 4); p2 untouched\n" as *u8) 148 gv_check("T7 anchor-guard LINTS drift: only the drifted part moves, correct direction, anchor immovable" as *u8, t7, ctr) 149 150 // T5 the REAL canon parses at census level (indices not identity-verified yet -- stated) 151 var havecanon: i64 = 0 152 let cfd: i64 = sys_openat_rd("knowledge/canon_merge2.dat" as *u8) 153 if cfd >= 0 { havecanon = 1; sys_close(cfd) } 154 if gv_need("knowledge/canon_merge2.dat" as *u8, havecanon, ctr) == 1 { 155 let lp: *i64 = sys_mmap(16) as *i64 156 let cb: *u8 = sys_read_file("knowledge/canon_merge2.dat" as *u8, lp) 157 var np2: i64 = 0 158 var nr2: i64 = 0 159 var eyec: i64 = 0 160 var eyeox: i64 = 0 161 var eyeoz: i64 = 0 162 var i2: i64 = 0 163 var bol: i64 = 1 164 while i2 < lp[0] { 165 if bol == 1 { 166 if (cb[i2] as i64) == 80 { 167 np2 = np2 + 1 168 let pos2: *i64 = sys_mmap(16) as *i64 169 pos2[0] = i2 + 1 170 var e2: i64 = i2 171 var f2: i64 = 1 172 while f2 == 1 { if e2 >= lp[0] { f2 = 0 } else { if (cb[e2] as i64) == 10 { f2 = 0 } else { e2 = e2 + 1 } } } 173 gc_rd(cb, pos2, e2) 174 gc_rd(cb, pos2, e2) 175 let ox2: i64 = gc_rd(cb, pos2, e2) 176 gc_rd(cb, pos2, e2) 177 let oz2: i64 = gc_rd(cb, pos2, e2) 178 let mat2: i64 = gc_rd(cb, pos2, e2) 179 if mat2 == 1 { eyec = eyec + 1; eyeox = ox2; eyeoz = oz2 } 180 } 181 if (cb[i2] as i64) == 82 { nr2 = nr2 + 1 } 182 } 183 if (cb[i2] as i64) == 10 { bol = 1 } else { bol = 0 } 184 i2 = i2 + 1 185 } 186 gv_puts(" canon_merge2: P rows=" as *u8); gv_num(np2) 187 gv_puts(" R rows=" as *u8); gv_num(nr2) 188 gv_puts(" eye-rows(mat=1)=" as *u8); gv_num(eyec) 189 gv_puts(" eye ox=" as *u8); gv_num(eyeox) 190 gv_puts(" oz=" as *u8); gv_num(eyeoz) 191 gv_puts("\n" as *u8) 192 var t5: i64 = 0 193 if np2 >= 5 { if np2 <= 256 { if nr2 > np2 { t5 = 1 } } } 194 gv_check("T5 the real face canon parses at census level (parts in solver range, rings present)" as *u8, t5, ctr) 195 // the 3-way identity, asserted mechanically: exactly ONE mat=1 row, at the documented 66mm 196 // interpupillary (ox 19 permil) and the sec56 forward offset (oz 50) 197 var t8: i64 = 0 198 if eyec == 1 { if eyeox == 19 { if eyeoz == 50 { t8 = 1 } } } 199 gv_check("T8 EYE IDENTITY gate-proven: one mat=1 part at ox=19 (66mm IPD) oz=50 (sec56 fix)" as *u8, t8, ctr) 200 } 201 202 let rc: i64 = gv_verdict("CANON-SOLVER-GATE" as *u8, ctr, "the canon lints against beauty/anatomy rules: CLEAN, ADJUSTED with named deltas, or refused" as *u8) 203 sys_exit(rc) 204 return rc 205}