code wiki / _hdl_build / nx_phys3d_gate.nx

nx_phys3d_gate.nx source

↩ module page · 238 lines · 10776 B

1// nx_phys3d_gate.nx -- gate for the unified sovereign rigid-body core (the 07-01 census's named gap). 2// The CLASSIC engine proofs, all integer-deterministic: 3// T1 integrator exactness (free fall matches the loop-computed analytic sum EXACTLY) 4// T2 restitution: e=0.5 bounce apex ~1/4 of drop height; e=0 body RESTS on the ground and stays 5// T3 THE STACK: 8 dynamic boxes on a static ground -- 1200 ticks, bounded drift, ALL ASLEEP at the end 6// T4 friction is real: mu=0.78 slider STOPS; mu=0 slider KEEPS SLIDING (same push, same ticks) 7// T5 determinism: two worlds, same script -> all body slots IDENTICAL after 500 ticks 8// T6 elastic head-on equal masses: velocities SWAP integer-exact (e=1) 9// T7 inelastic head-on (e=0): both stop (momentum symmetric) 10// license_tier: ORIGINAL expect_exit: 0 11import "nx_syscalls.nx" 12import "nx_phys3d.nx" 13 14func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 15func pn(v: i64) -> i64 { 16 let b: *u8 = sys_mmap(32) as *u8 17 var x: i64 = v 18 var neg: i64 = 0 19 if x < 0 { neg = 1; x = 0 - x } 20 var i: i64 = 31 21 if x == 0 { b[i] = 48 as u8; i = i - 1 } 22 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 23 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 24 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i) 25 return 0 26} 27func gabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 28// static ground slab: top surface at y=0 29func mk_ground(base: i64) -> i64 { return ph_add(base, 1, 0, 0 - 512, 0, 100000, 512, 100000, 0, 0, 200) } 30 31func main() -> i64 { 32 var fails: i64 = 0 33 34 // ---- T1 integrator exactness: free fall, no contacts ---- 35 let w1: i64 = sys_mmap(ph_bytes()) as i64 36 ph_init(w1) 37 let s1: i64 = ph_add(w1, 0, 0, 500000, 0, 64, 64, 64, 256, 0, 0) 38 var refy: i64 = 500000 39 var refv: i64 = 0 40 var t: i64 = 0 41 while t < 60 { 42 ph_step(w1) 43 refv = refv - 178 44 refy = refy + refv / 256 45 t = t + 1 46 } 47 let b1: *i64 = ph_body(w1, s1) 48 if b1[2] == refy { hw("T1 PASS integrator exact: 60-tick free fall matches the analytic sum bit-for-bit (y=" as *u8); pn(b1[2]); hw(")\n" as *u8) } 49 else { hw("T1 FAIL y=" as *u8); pn(b1[2]); hw(" ref=" as *u8); pn(refy); hw("\n" as *u8); fails = fails + 1 } 50 51 // ---- T2 restitution: bounce ratio + rest ---- 52 let w2: i64 = sys_mmap(ph_bytes()) as i64 53 ph_init(w2) 54 mk_ground(w2) 55 let sb: i64 = ph_add(w2, 0, 0, 512, 0, 64, 64, 64, 256, 128, 0) // drop from 2m (512 fx256), e=0.5 56 let bb: *i64 = ph_body(w2, sb) 57 // apex = max height AFTER the first impact (v goes positive) -- no fragile descent detection: the 58 // bounce tick's y is naturally LOWER than the previous falling tick's y (that false-tripped phase-2) 59 var apex1: i64 = 0 60 var bounced: i64 = 0 61 t = 0 62 while t < 600 { 63 ph_step(w2) 64 if bb[5] > 0 { bounced = 1 } 65 if bounced == 1 { if bb[2] > apex1 { apex1 = bb[2] } } 66 t = t + 1 67 } 68 // apex of the first rebound with e=0.5 should be ~1/4 of the drop (energy ~ e^2): window [1/8, 1/2.5] 69 var t2: i64 = 1 70 if apex1 * 8 < 512 { t2 = 0 } 71 if apex1 * 5 > 512 * 2 { t2 = 0 } 72 // e=0 rest: fresh sphere, must settle to r above ground (64) within slop and STAY 73 let sr: i64 = ph_add(w2, 0, 1000, 512, 0, 64, 64, 64, 256, 0, 0) 74 var t3i: i64 = 0 75 while t3i < 300 { ph_step(w2); t3i = t3i + 1 } 76 let br: *i64 = ph_body(w2, sr) 77 let resty: i64 = br[2] 78 if gabs(resty - 64) > PH_SLOP + 3 { t2 = 0 } 79 var t3j: i64 = 0 80 while t3j < 100 { ph_step(w2); t3j = t3j + 1 } 81 if br[2] != resty { t2 = 0 } 82 if t2 == 1 { hw("T2 PASS restitution: e=.5 rebound apex=" as *u8); pn(apex1); hw("/512 (~1/4 drop); e=0 rests at r+-slop and STAYS\n" as *u8) } 83 else { hw("T2 FAIL apex=" as *u8); pn(apex1); hw(" resty=" as *u8); pn(resty); hw("\n" as *u8); fails = fails + 1 } 84 85 // ---- T3 THE STACK: 8 boxes, 1200 ticks, bounded drift, all asleep ---- 86 let w3: i64 = sys_mmap(ph_bytes()) as i64 87 ph_init(w3) 88 mk_ground(w3) 89 var k: i64 = 0 90 while k < 8 { 91 ph_add(w3, 1, 0, 64 + k * 128, 0, 64, 64, 64, 256, 0, 200) 92 k = k + 1 93 } 94 t = 0 95 while t < 1200 { ph_step(w3); t = t + 1 } 96 var t3: i64 = 1 97 var awake_n: i64 = 0 98 var maxdrift: i64 = 0 99 k = 0 100 while k < 8 { 101 let bk: *i64 = ph_body(w3, 1 + k) 102 let dy: i64 = gabs(bk[2] - (64 + k * 128)) 103 let dx: i64 = gabs(bk[1]) 104 let dz: i64 = gabs(bk[3]) 105 if dy > maxdrift { maxdrift = dy } 106 if dx > maxdrift { maxdrift = dx } 107 if dz > maxdrift { maxdrift = dz } 108 if bk[14] == 1 { awake_n = awake_n + 1 } 109 k = k + 1 110 } 111 // structural asserts (a slop-per-interface sag is physical for a penalty/impulse solver; what must hold: 112 // order preserved, gaps sane, no lateral wander, and the stack goes to SLEEP) 113 var order_ok: i64 = 1 114 var lateral: i64 = 0 115 k = 0 116 while k < 7 { 117 let lo: *i64 = ph_body(w3, 1 + k) 118 let hi: *i64 = ph_body(w3, 2 + k) 119 let gap: i64 = hi[2] - lo[2] 120 // WARM-START LANDED (2026-07-03): the bound tightens back to the honest [100,150] -- accumulated 121 // impulses hold column weight instead of re-fighting it, so interfaces must rest near the true 122 // 128-slop, not quantization-freeze 50 deep. (The parked-rung history lives in the git/memory trail.) 123 if gap < 100 { order_ok = 0 } 124 if gap > 150 { order_ok = 0 } 125 k = k + 1 126 } 127 k = 0 128 while k < 8 { 129 let bk2: *i64 = ph_body(w3, 1 + k) 130 if gabs(bk2[1]) > lateral { lateral = gabs(bk2[1]) } 131 if gabs(bk2[3]) > lateral { lateral = gabs(bk2[3]) } 132 k = k + 1 133 } 134 if order_ok == 0 { t3 = 0 } 135 if lateral > 12 { t3 = 0 } 136 if awake_n != 0 { t3 = 0 } 137 // diagnostics (always printed -- evidence for any future tuning) 138 let d0: *i64 = ph_body(w3, 1) 139 let d7: *i64 = ph_body(w3, 8) 140 hw(" [t3-diag] box0 y=" as *u8); pn(d0[2]); hw(" vy=" as *u8); pn(d0[5]); hw(" awake=" as *u8); pn(d0[14]) 141 hw(" | box7 y=" as *u8); pn(d7[2]); hw(" vy=" as *u8); pn(d7[5]); hw(" awake=" as *u8); pn(d7[14]) 142 hw(" | ydrift=" as *u8); pn(maxdrift); hw(" lateral=" as *u8); pn(lateral); hw("\n" as *u8) 143 hw(" [t3-gaps]" as *u8) 144 k = 0 145 while k < 7 { 146 let glo: *i64 = ph_body(w3, 1 + k) 147 let ghi: *i64 = ph_body(w3, 2 + k) 148 hw(" " as *u8); pn(ghi[2] - glo[2]) 149 k = k + 1 150 } 151 hw("\n" as *u8) 152 if t3 == 1 { hw("T3 PASS THE STACK: 8 boxes 1200 ticks -- order kept, gaps sane, lateral=" as *u8); pn(lateral); hw(", ALL ASLEEP (sag=" as *u8); pn(maxdrift); hw(")\n" as *u8) } 153 else { hw("T3 FAIL order=" as *u8); pn(order_ok); hw(" lateral=" as *u8); pn(lateral); hw(" awake=" as *u8); pn(awake_n); hw("\n" as *u8); fails = fails + 1 } 154 155 // ---- T4 friction real: mu-slider stops, mu0-slider slides ---- 156 let w4: i64 = sys_mmap(ph_bytes()) as i64 157 ph_init(w4) 158 mk_ground(w4) 159 let f1: i64 = ph_add(w4, 1, 0, 64, 0, 64, 64, 64, 256, 0, 200) 160 t = 0 161 ph_set_vel(w4, f1, 4000, 0, 0) 162 let f2: i64 = ph_add(w4, 1, 0, 64, 100000, 64, 64, 64, 256, 0, 0) 163 ph_set_vel(w4, f2, 4000, 0, 0) 164 while t < 400 { ph_step(w4); t = t + 1 } 165 let bf1: *i64 = ph_body(w4, f1) 166 let bf2: *i64 = ph_body(w4, f2) 167 var t4: i64 = 1 168 if gabs(bf1[4]) > 40 { t4 = 0 } 169 if gabs(bf2[4]) < 3000 { t4 = 0 } 170 if t4 == 1 { hw("T4 PASS friction real: mu=.78 slider STOPPED (v=" as *u8); pn(bf1[4]); hw("), mu=0 keeps sliding (v=" as *u8); pn(bf2[4]); hw(")\n" as *u8) } 171 else { hw("T4 FAIL v_mu=" as *u8); pn(bf1[4]); hw(" v_0=" as *u8); pn(bf2[4]); hw("\n" as *u8); fails = fails + 1 } 172 173 // ---- T5 determinism: identical worlds -> identical states ---- 174 let wa: i64 = sys_mmap(ph_bytes()) as i64 175 let wb: i64 = sys_mmap(ph_bytes()) as i64 176 ph_init(wa); ph_init(wb) 177 mk_ground(wa); mk_ground(wb) 178 k = 0 179 while k < 6 { 180 ph_add(wa, 1, 0, 64 + k * 128, 0, 64, 64, 64, 256, 0, 200) 181 ph_add(wb, 1, 0, 64 + k * 128, 0, 64, 64, 64, 256, 0, 200) 182 k = k + 1 183 } 184 let pa: i64 = ph_add(wa, 0, 0 - 2000, 800, 0, 64, 64, 64, 256, 128, 100) 185 let pb: i64 = ph_add(wb, 0, 0 - 2000, 800, 0, 64, 64, 64, 256, 128, 100) 186 ph_set_vel(wa, pa, 6000, 2000, 300) 187 ph_set_vel(wb, pb, 6000, 2000, 300) 188 t = 0 189 while t < 500 { ph_step(wa); ph_step(wb); t = t + 1 } 190 var diff: i64 = 0 191 var si: i64 = 0 192 while si < 8 * 16 { 193 let va: *i64 = (wa + 64) as *i64 194 let vb: *i64 = (wb + 64) as *i64 195 if va[si] != vb[si] { diff = diff + 1 } 196 si = si + 1 197 } 198 if diff == 0 { hw("T5 PASS determinism: two worlds, 500 ticks incl stack impact -> ALL body slots IDENTICAL\n" as *u8) } 199 else { hw("T5 FAIL diff-slots=" as *u8); pn(diff); hw("\n" as *u8); fails = fails + 1 } 200 201 // ---- T6 elastic swap (e=1, equal masses, head-on) ---- 202 let w6: i64 = sys_mmap(ph_bytes()) as i64 203 ph_init(w6) 204 let e1: i64 = ph_add(w6, 0, 0 - 300, 64, 0, 64, 64, 64, 256, 256, 0) 205 let e2: i64 = ph_add(w6, 0, 300, 64, 0, 64, 64, 64, 256, 256, 0) 206 ph_set_vel(w6, e1, 2000, 0, 0) 207 ph_set_vel(w6, e2, 0 - 2000, 0, 0) 208 t = 0 209 while t < 60 { ph_step(w6); t = t + 1 } 210 let be1: *i64 = ph_body(w6, e1) 211 let be2: *i64 = ph_body(w6, e2) 212 var t6: i64 = 1 213 if gabs(be1[4] + 2000) > 64 { t6 = 0 } 214 if gabs(be2[4] - 2000) > 64 { t6 = 0 } 215 if t6 == 1 { hw("T6 PASS elastic head-on swap: v1=" as *u8); pn(be1[4]); hw(" v2=" as *u8); pn(be2[4]); hw(" (+-2000 within rounding)\n" as *u8) } 216 else { hw("T6 FAIL v1=" as *u8); pn(be1[4]); hw(" v2=" as *u8); pn(be2[4]); hw("\n" as *u8); fails = fails + 1 } 217 218 // ---- T7 inelastic head-on: both stop ---- 219 let w7: i64 = sys_mmap(ph_bytes()) as i64 220 ph_init(w7) 221 let i1: i64 = ph_add(w7, 0, 0 - 300, 64, 0, 64, 64, 64, 256, 0, 0) 222 let i2: i64 = ph_add(w7, 0, 300, 64, 0, 64, 64, 64, 256, 0, 0) 223 ph_set_vel(w7, i1, 2000, 0, 0) 224 ph_set_vel(w7, i2, 0 - 2000, 0, 0) 225 t = 0 226 while t < 60 { ph_step(w7); t = t + 1 } 227 let bi1: *i64 = ph_body(w7, i1) 228 let bi2: *i64 = ph_body(w7, i2) 229 var t7: i64 = 1 230 if gabs(bi1[4]) > 32 { t7 = 0 } 231 if gabs(bi2[4]) > 32 { t7 = 0 } 232 if t7 == 1 { hw("T7 PASS inelastic head-on: both stop (v1=" as *u8); pn(bi1[4]); hw(" v2=" as *u8); pn(bi2[4]); hw(")\n" as *u8) } 233 else { hw("T7 FAIL v1=" as *u8); pn(bi1[4]); hw(" v2=" as *u8); pn(bi2[4]); hw("\n" as *u8); fails = fails + 1 } 234 235 if fails == 0 { hw("VERDICT GREEN: nx_phys3d 7/7 -- unified deterministic rigid-body core (integrate/bounce/STACK/friction/replay/elastic/inelastic)\n" as *u8) } 236 else { hw("VERDICT RED fails=" as *u8); pn(fails); hw("\n" as *u8) } 237 return fails 238}