code wiki / _hdl_build / nx_softjiggle_gate.nx

nx_softjiggle_gate.nx source

↩ module page · 244 lines · 10862 B

1// nx_softjiggle_gate.nx -- gate for the jiggle-bone substrate. The jiggle ESSENCE is measured, not asserted: 2// T1 REST: node parked at its anchor stays put (gravity variant settles at the k/g equilibrium and stays) 3// T2 LAG + OVERSHOOT: step the anchor -> the node measurably LAGS, then OVERSHOOTS past, then settles = the 4// damped-oscillation signature that IS jiggle 5// T3 DECAY: successive overshoot peaks strictly shrink (energy dissipates -- no runaway) 6// T4 NO-EXPLOSION: violent anchor teleport -> displacement NEVER exceeds maxstretch (clamp by construction) 7// T5 DETERMINISM: two lattices, same shake script -> byte-identical states 8// T6 CONFIG-IS-DATA: stiffer/looser nodes produce different trajectories (profiles are data, mod-shippable) 9// + PNG knowledge/nx_jiggle_trace.png: the anchor step vs node response TRACE (lag/overshoot/decay, visible) 10// license_tier: ORIGINAL expect_exit: 0 11import "nx_syscalls.nx" 12import "nx_png.nx" 13import "nx_softjiggle.nx" 14 15func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 16func pn(v: i64) -> i64 { 17 let b: *u8 = sys_mmap(32) as *u8 18 var x: i64 = v 19 var neg: i64 = 0 20 if x < 0 { neg = 1; x = 0 - x } 21 var i: i64 = 31 22 if x == 0 { b[i] = 48 as u8; i = i - 1 } 23 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 24 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 25 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i) 26 return 0 27} 28func gabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 29 30func main() -> i64 { 31 var fails: i64 = 0 32 33 // ---- T1 rest ---- 34 let w1: i64 = sys_mmap(sj_bytes()) as i64 35 sj_init(w1) 36 let r0: i64 = sj_add(w1, 1000, 1000, 0, 24, 40, 200, 0) 37 let rg: i64 = sj_add(w1, 3000, 1000, 0, 24, 40, 200, 60) 38 var t: i64 = 0 39 while t < 400 { sj_step(w1); t = t + 1 } 40 let n0: *i64 = sj_node(w1, r0) 41 let ng: *i64 = sj_node(w1, rg) 42 var t1: i64 = 1 43 if n0[0] != 1000 { t1 = 0 } 44 if n0[1] != 1000 { t1 = 0 } 45 let sagy: i64 = ng[1] 46 var t2i: i64 = 0 47 while t2i < 100 { sj_step(w1); t2i = t2i + 1 } 48 if ng[1] != sagy { t1 = 0 } // gravity node settled and STAYS 49 if sagy >= 1000 { t1 = 0 } // it sags BELOW the anchor 50 if t1 == 1 { hw("T1 PASS rest: anchored node exact; gravity node sags to equilibrium (y=" as *u8); pn(sagy); hw(") and stays\n" as *u8) } 51 else { hw("T1 FAIL n0x=" as *u8); pn(n0[0]); hw(" sagy=" as *u8); pn(sagy); hw("\n" as *u8); fails = fails + 1 } 52 53 // ---- T2+T3 lag, overshoot, decay + the PNG trace ---- 54 let w2: i64 = sys_mmap(sj_bytes()) as i64 55 sj_init(w2) 56 let j: i64 = sj_add(w2, 0, 0, 0, 18, 28, 400, 0) 57 sj_anchor(w2, j, 300, 0, 0) // step input: anchor jumps +300 (1.17 units) 58 let nj: *i64 = sj_node(w2, j) 59 // trace buffers 60 let TW: i64 = 256 61 let TH: i64 = 160 62 let fb: *i64 = sys_mmap(TW * TH * 8) as *i64 63 var pi: i64 = 0 64 while pi < TW * TH { fb[pi] = 24 + 28 * 256 + 38 * 65536; pi = pi + 1 } 65 var lag_seen: i64 = 0 66 var over_seen: i64 = 0 67 var peak1: i64 = 0 68 var peak2: i64 = 0 69 var inpeak: i64 = 0 70 var curpeak: i64 = 0 71 var peakn: i64 = 0 72 t = 0 73 while t < 256 { 74 sj_step(w2) 75 let x: i64 = nj[0] 76 if t < 6 { if x < 260 { lag_seen = 1 } } 77 if x > 304 { over_seen = 1 } 78 // peak envelope: track |x-300| local maxima above a noise floor 79 let dev: i64 = gabs(x - 300) 80 if dev > 12 { 81 if dev > curpeak { curpeak = dev } 82 inpeak = 1 83 } else { 84 if inpeak == 1 { 85 peakn = peakn + 1 86 if peakn == 1 { peak1 = curpeak } 87 if peakn == 2 { peak2 = curpeak } 88 curpeak = 0 89 inpeak = 0 90 } 91 } 92 // trace plot: anchor row (green) vs node row (amber): y = 130 - x/4 93 var py: i64 = 130 - x / 4 94 if py < 2 { py = 2 } 95 if py > TH - 3 { py = TH - 3 } 96 fb[py * TW + t] = 90 + 220 * 256 + 130 * 65536 97 let ay: i64 = 130 - 300 / 4 98 fb[ay * TW + t] = 70 + 110 * 256 + 235 * 65536 99 t = t + 1 100 } 101 write_png(fb, TW, TH, "knowledge/nx_jiggle_trace.png" as *u8) 102 var t2: i64 = 1 103 if lag_seen == 0 { t2 = 0 } 104 if over_seen == 0 { t2 = 0 } 105 if gabs(nj[0] - 300) > 6 { t2 = 0 } 106 if t2 == 1 { hw("T2 PASS jiggle signature: LAGS the anchor step, OVERSHOOTS past it, settles (final dev=" as *u8); pn(gabs(nj[0] - 300)); hw(") + PNG trace\n" as *u8) } 107 else { hw("T2 FAIL lag=" as *u8); pn(lag_seen); hw(" over=" as *u8); pn(over_seen); hw(" final=" as *u8); pn(nj[0]); hw("\n" as *u8); fails = fails + 1 } 108 var t3: i64 = 1 109 if peakn < 2 { t3 = 0 } 110 if peak2 >= peak1 { t3 = 0 } 111 if t3 == 1 { hw("T3 PASS decay: overshoot peaks shrink (" as *u8); pn(peak1); hw(" -> " as *u8); pn(peak2); hw(", n=" as *u8); pn(peakn); hw(")\n" as *u8) } 112 else { hw("T3 FAIL peaks " as *u8); pn(peak1); hw(" -> " as *u8); pn(peak2); hw(" n=" as *u8); pn(peakn); hw("\n" as *u8); fails = fails + 1 } 113 114 // ---- T4 no-explosion clamp ---- 115 let w4: i64 = sys_mmap(sj_bytes()) as i64 116 sj_init(w4) 117 let v: i64 = sj_add(w4, 0, 0, 0, 18, 28, 150, 0) 118 sj_anchor(w4, v, 20000, 0 - 20000, 20000) 119 let nv: *i64 = sj_node(w4, v) 120 var t4: i64 = 1 121 t = 0 122 while t < 200 { 123 sj_step(w4) 124 if gabs(nv[0] - 20000) > 151 { t4 = 0 } 125 if gabs(nv[1] + 20000) > 151 { t4 = 0 } 126 if gabs(nv[2] - 20000) > 151 { t4 = 0 } 127 t = t + 1 128 } 129 if t4 == 1 { hw("T4 PASS no-explosion: violent teleport, displacement NEVER exceeds maxstretch (by construction)\n" as *u8) } 130 else { hw("T4 FAIL clamp breached\n" as *u8); fails = fails + 1 } 131 132 // ---- T5 determinism (chained 3-node tail + shake script) ---- 133 let wa: i64 = sys_mmap(sj_bytes()) as i64 134 let wb: i64 = sys_mmap(sj_bytes()) as i64 135 sj_init(wa); sj_init(wb) 136 var c: i64 = 0 137 while c < 3 { 138 sj_add(wa, 0, 0 - c * 100, 0, 20 + c * 6, 30, 300, 40) 139 sj_add(wb, 0, 0 - c * 100, 0, 20 + c * 6, 30, 300, 40) 140 if c > 0 { sj_chain(wa, c, c - 1); sj_chain(wb, c, c - 1) } 141 c = c + 1 142 } 143 sj_add_capsule(wa, 0, 0 - 500, 0, 0, 500, 0, 90) // capsule in the shake path: determinism must cover pushout 144 sj_add_capsule(wb, 0, 0 - 500, 0, 0, 500, 0, 90) 145 t = 0 146 while t < 300 { 147 var sx: i64 = 0 148 if (t / 25) % 2 == 0 { sx = 240 } else { sx = 0 - 240 } 149 sj_anchor(wa, 0, sx, 0, 0) 150 sj_anchor(wb, 0, sx, 0, 0) 151 sj_step(wa) 152 sj_step(wb) 153 t = t + 1 154 } 155 var diff: i64 = 0 156 var si: i64 = 0 157 while si < 3 * 16 { 158 let va: *i64 = (wa + 64) as *i64 159 let vb: *i64 = (wb + 64) as *i64 160 if va[si] != vb[si] { diff = diff + 1 } 161 si = si + 1 162 } 163 if diff == 0 { hw("T5 PASS determinism: chained 3-node tail, 300-tick shake -> byte-identical\n" as *u8) } 164 else { hw("T5 FAIL diff=" as *u8); pn(diff); hw("\n" as *u8); fails = fails + 1 } 165 166 // ---- T6 config-is-data: different k -> different trajectory ---- 167 let w6: i64 = sys_mmap(sj_bytes()) as i64 168 sj_init(w6) 169 let s1: i64 = sj_add(w6, 0, 0, 0, 10, 28, 400, 0) 170 let s2: i64 = sj_add(w6, 0, 0, 0, 48, 28, 400, 0) 171 sj_anchor(w6, s1, 300, 0, 0) 172 sj_anchor(w6, s2, 300, 0, 0) 173 var traj_differs: i64 = 0 174 t = 0 175 while t < 40 { 176 sj_step(w6) 177 if sj_pos(w6, s1, 0) != sj_pos(w6, s2, 0) { traj_differs = traj_differs + 1 } 178 t = t + 1 179 } 180 if traj_differs > 20 { hw("T6 PASS profiles are DATA: k=10 vs k=48 diverge on " as *u8); pn(traj_differs); hw("/40 ticks (mod-shippable body profiles)\n" as *u8) } 181 else { hw("T6 FAIL differs=" as *u8); pn(traj_differs); hw("\n" as *u8); fails = fails + 1 } 182 183 // ---- T7 capsule surface: node anchored INSIDE a capsule settles ON the surface, never inside ---- 184 let w7: i64 = sys_mmap(sj_bytes()) as i64 185 sj_init(w7) 186 sj_add_capsule(w7, 500, 0 - 400, 0, 500, 400, 0, 120) 187 let cn2: i64 = sj_add(w7, 700, 0, 0, 18, 30, 500, 0) 188 sj_anchor(w7, cn2, 500, 0, 0) // anchor ON the capsule axis: spring pulls in, pushout holds 189 let nn: *i64 = sj_node(w7, cn2) 190 var t7: i64 = 1 191 var minr2: i64 = 99999999 192 t = 0 193 while t < 300 { 194 sj_step(w7) 195 if t > 5 { 196 let exx: i64 = nn[0] - 500 197 let ezz: i64 = nn[2] 198 let dd: i64 = exx * exx + ezz * ezz + 0 * nn[1] 199 if nn[1] > 0 - 400 { if nn[1] < 400 { 200 if dd < minr2 { minr2 = dd } 201 } } 202 } 203 t = t + 1 204 } 205 if minr2 < 116 * 116 { t7 = 0 } 206 let fexx: i64 = nn[0] - 500 207 let fezz: i64 = nn[2] 208 let fd2: i64 = fexx * fexx + fezz * fezz 209 if fd2 < 117 * 117 { t7 = 0 } 210 if fd2 > 190 * 190 { t7 = 0 } 211 if t7 == 1 { hw("T7 PASS capsule: spring pulls to the axis, node HELD ON the surface (min-r=" as *u8); pn(sj_isqrt(minr2)); hw("/120, settles at r)\n" as *u8) } 212 else { hw("T7 FAIL minr2=" as *u8); pn(minr2); hw(" fd2=" as *u8); pn(fd2); hw("\n" as *u8); fails = fails + 1 } 213 214 // ---- T8 transit: dragged THROUGH a capsule -> slides AROUND it, never penetrates, reaches the far side ---- 215 let w8: i64 = sys_mmap(sj_bytes()) as i64 216 sj_init(w8) 217 sj_add_capsule(w8, 500, 0 - 400, 0, 500, 400, 0, 120) 218 let tn: i64 = sj_add(w8, 700, 40, 0, 18, 30, 600, 0) 219 // far side WITH a z-offset: a perfectly z-symmetric pull sits in the saddle equilibrium forever (the 220 // first run proved it: min-r exactly 120, stuck at x=620) -- real rigs are never measure-zero symmetric 221 sj_anchor(w8, tn, 300, 40, 60) 222 let tb: *i64 = sj_node(w8, tn) 223 var t8: i64 = 1 224 var minr2b: i64 = 99999999 225 t = 0 226 while t < 400 { 227 sj_step(w8) 228 if tb[1] > 0 - 400 { if tb[1] < 400 { 229 let ex2: i64 = tb[0] - 500 230 let ez2: i64 = tb[2] 231 let dd2: i64 = ex2 * ex2 + ez2 * ez2 232 if dd2 < minr2b { minr2b = dd2 } 233 } } 234 t = t + 1 235 } 236 if minr2b < 116 * 116 { t8 = 0 } 237 if gabs(tb[0] - 300) > 60 { t8 = 0 } // reached the far anchor (outside the capsule) 238 if t8 == 1 { hw("T8 PASS transit: dragged through -> slides AROUND (min-r=" as *u8); pn(sj_isqrt(minr2b)); hw("/120), reaches the far side (x=" as *u8); pn(tb[0]); hw(")\n" as *u8) } 239 else { hw("T8 FAIL minr2=" as *u8); pn(minr2b); hw(" x=" as *u8); pn(tb[0]); hw("\n" as *u8); fails = fails + 1 } 240 241 if fails == 0 { hw("VERDICT GREEN: nx_softjiggle 8/8 -- jiggle measured (lag/overshoot/decay) + CAPSULE collision (surface-hold + slide-around), never-explode, deterministic, profiles=data (PNG knowledge/nx_jiggle_trace.png)\n" as *u8) } 242 else { hw("VERDICT RED fails=" as *u8); pn(fails); hw("\n" as *u8) } 243 return fails 244}