code wiki / (root) / nx_worldpipe_render_gate.nx

nx_worldpipe_render_gate.nx source

↩ module page · 234 lines · 11739 B

1// nx_worldpipe_render_gate.nx -- GATE for the rung "erosion reaches the PUBLISHED picture". 2// 3// THE SUBJECT IS NOT "DOES EROSION WORK". nx_worldpipe_erode_gate already proves that, 21/21, over the 4// full 102,400-cell population. The subject HERE is the single behavioural claim nx_worldpipe_render 5// makes and that a green erosion gate cannot make for it: that the bake changes the heights AT THE 6// EXACT POINTS THE RENDERER TURNS INTO PIXELS, and that a consumer which does not bake is untouched. 7// A capability can be proven and still never reach a surface; this gate measures the reaching. 8// 9// EVERY ASSERTION IS BOUND TO A DENOMINATOR (gv_subjects), and the denominators are the two real 10// populations: the whole hydrology grid, and the whole hero sample lattice the render loop walks. 11// No sampling. 12// 13// ANTI-VACUITY. "The picture changed" is passed by a uniform offset, by added noise, and by any bug 14// that perturbs every height equally -- so a tooth that only counts changed points is not a tooth. 15// This gate additionally requires the changes to be NON-UNIFORM (at least two distinct delta values 16// among the changed points), which a constant offset cannot satisfy. 17// 18// NEGATIVE CONTROLS, NAMED SO A CENSUS CAN FIND THEM: 19// neg-control-wp_erode-INERT-... proves the opt-in is real: before any bake every one of the 20// 102,400 cells reads exactly zero, so an importer that never 21// bakes is byte-identical. This is the "nobody else moves" claim. 22// neg-control-zero-tick-budget-... proves the instrument does not manufacture erosion: asked for a 23// zero budget it must return every sampled height to its 24// pre-bake value and report zero material moved. 25// 26// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26). 27import "nx_syscalls.nx" 28import "nx_gate_verdict.nx" 29import "nx_worldpipe.nx" 30 31// Seed and budget are the RENDERER'S, not the gate's -- a gate that exercises a different world or a 32// different budget than the thing it certifies is measuring a different subject. 33const WRG_SEED: i64 = 1 34const WRG_TICKS: i64 = 8 35// The render's hero lattice, copied from nx_worldpipe_render so these are the very points that become 36// pixels: 97 x 97 samples at 110 world units, centred by subtracting 48. 37const WRG_TN: i64 = 97 38const WRG_SP: i64 = 110 39const WRG_OFF: i64 = 48 40const WRG_ART: *u8 = "knowledge/nx_worldpipe_eroded.png" 41 42func wrg_hero_x(i: i64) -> i64 { return (i - WRG_OFF)*WRG_SP } 43 44// Independent recomputation of the derived talus, written HERE so the lib's answer is checked against 45// a second implementation of the same definition rather than against itself. This catches the failure 46// that matters -- a derivation that silently returns a constant, or reads the wrong surface -- and it 47// is deliberately the ONLY duplicated arithmetic in this file. 48func wrg_talus_oracle() -> i64 { 49 let gn: i64 = HYW 50 let n: i64 = gn * gn 51 let g: *i64 = sys_mmap(n*8) as *i64 52 var y: i64 = 0 53 while y < gn { 54 var x: i64 = 0 55 while x < gn { g[y*gn + x] = wp_flow_h(x*HYCELL - HYSPAN, y*HYCELL - HYSPAN); x = x + 1 } 56 y = y + 1 57 } 58 var sum: i64 = 0 59 var y2: i64 = 0 60 while y2 < gn { 61 var x2: i64 = 0 62 while x2 < gn { 63 let k: i64 = y2*gn + x2 64 let h: i64 = g[k] 65 var m: i64 = 0 66 if x2 > 0 { let da: i64 = wp_iabs(h - g[k-1]); if da > m { m = da } } 67 if x2 < gn - 1 { let db: i64 = wp_iabs(h - g[k+1]); if db > m { m = db } } 68 if y2 > 0 { let dc: i64 = wp_iabs(h - g[k-gn]); if dc > m { m = dc } } 69 if y2 < gn - 1 { let dd: i64 = wp_iabs(h - g[k+gn]); if dd > m { m = dd } } 70 sum = sum + m 71 x2 = x2 + 1 72 } 73 y2 = y2 + 1 74 } 75 return sum / n 76} 77 78// Fill dst with wp_height at every hero lattice point, in render order. 79func wrg_sample_hero(dst: *i64) -> i64 { 80 var gz: i64 = 0 81 while gz < WRG_TN { 82 var gx: i64 = 0 83 while gx < WRG_TN { 84 dst[gz*WRG_TN + gx] = wp_height(wrg_hero_x(gx), wrg_hero_x(gz)) 85 gx = gx + 1 86 } 87 gz = gz + 1 88 } 89 return WRG_TN * WRG_TN 90} 91 92func main() -> i64 { 93 let c: *i64 = gv_ctr() 94 gv_head("=== nx_worldpipe_render_gate -- does stage-3.5 erosion reach the PUBLISHED picture? ===" as *u8) 95 96 wp_init(WRG_SEED) 97 let nspr: i64 = wp_hydro_bake() 98 gv_puts(" world: seed=" as *u8); gv_num(WRG_SEED) 99 gv_puts(" hydrology springs=" as *u8); gv_num(nspr); gv_puts("\n" as *u8) 100 101 let gn: i64 = HYW 102 let n: i64 = gn * gn 103 gv_subjects("hydrology-grid-cells-full-population" as *u8, n, c) 104 105 // ---- neg-control: the opt-in is the BAKE. Nothing has baked yet, so every cell must read zero. 106 var inert: i64 = 0 107 var y1: i64 = 0 108 while y1 < gn { 109 var x1: i64 = 0 110 while x1 < gn { 111 if wp_erode(x1*HYCELL - HYSPAN, y1*HYCELL - HYSPAN) != 0 { inert = inert + 1 } 112 x1 = x1 + 1 113 } 114 y1 = y1 + 1 115 } 116 gv_puts(" before any bake: non-zero wp_erode readings=" as *u8); gv_num(inert) 117 gv_puts(" of=" as *u8); gv_num(n); gv_puts("\n" as *u8) 118 gv_check("neg-control-wp_erode-INERT-at-EVERY-cell-before-a-bake-so-a-non-baking-consumer-is-byte-identical" as *u8, 119 inert == 0, c) 120 121 // ---- the hero lattice: the points that become pixels, sampled BEFORE the bake 122 let hn: i64 = WRG_TN * WRG_TN 123 gv_subjects("render-hero-lattice-points-full-population" as *u8, hn, c) 124 let pre: *i64 = sys_mmap(hn*8) as *i64 125 let post1: *i64 = sys_mmap(hn*8) as *i64 126 let zero: *i64 = sys_mmap(hn*8) as *i64 127 let post2: *i64 = sys_mmap(hn*8) as *i64 128 wrg_sample_hero(pre) 129 130 // ---- the derived talus, checked against an independent recomputation 131 let tl: i64 = wp_erode_talus_derived() 132 let tlo: i64 = wrg_talus_oracle() 133 gv_puts(" derived talus=" as *u8); gv_num(tl) 134 gv_puts(" independent oracle=" as *u8); gv_num(tlo); gv_puts("\n" as *u8) 135 gv_check("terrain-has-relief-so-the-derived-talus-is-a-measurement-not-a-default" as *u8, tl > 0, c) 136 gv_check("derived-talus-EQUALS-an-independent-recomputation-so-it-is-the-formula-not-a-constant" as *u8, 137 tl == tlo, c) 138 139 // ---- the bake the renderer makes 140 let tl2: i64 = wp_erode_bake_derived(WRG_TICKS) 141 let moved: i64 = wp_erode_stat(1) 142 let hi0: i64 = wp_erode_stat(2) 143 let hi1: i64 = wp_erode_stat(3) 144 gv_puts(" bake: ticks=" as *u8); gv_num(wp_erode_stat(0)) 145 gv_puts(" talus=" as *u8); gv_num(tl2) 146 gv_puts(" material_moved=" as *u8); gv_num(moved) 147 gv_puts(" hypsometric_permil " as *u8); gv_num(hi0) 148 gv_puts(" -> " as *u8); gv_num(hi1); gv_puts("\n" as *u8) 149 gv_check("bake-at-the-renderers-budget-MOVED-material" as *u8, moved > 0, c) 150 gv_check("bake_derived-reports-the-same-talus-it-derived" as *u8, tl2 == tl, c) 151 152 wrg_sample_hero(post1) 153 var changed: i64 = 0 154 var firstd: i64 = 0 155 var distinct2: i64 = 0 156 var i2: i64 = 0 157 while i2 < hn { 158 let d: i64 = post1[i2] - pre[i2] 159 if d != 0 { 160 changed = changed + 1 161 if firstd == 0 { firstd = d } else { if d != firstd { distinct2 = 1 } } 162 } 163 i2 = i2 + 1 164 } 165 var permil: i64 = 0 166 if hn > 0 { permil = changed * 1000 / hn } 167 gv_puts(" render lattice: heights changed by the bake=" as *u8); gv_num(changed) 168 gv_puts(" of=" as *u8); gv_num(hn) 169 gv_puts(" permil=" as *u8); gv_num(permil) 170 gv_puts(" second_distinct_delta=" as *u8); gv_num(distinct2); gv_puts("\n" as *u8) 171 gv_check("THE-RUNG-erosion-changes-the-heights-at-the-points-the-renderer-turns-into-pixels" as *u8, 172 changed > 0, c) 173 gv_check("anti-vacuity-the-deltas-are-NON-UNIFORM-so-a-constant-offset-or-a-global-perturbation-cannot-pass" as *u8, 174 distinct2 == 1, c) 175 176 // The paired cell: the SAME detector must FIRE on the baked world and stay SILENT on the unbaked 177 // one. The silent side is the pre-bake full-grid census taken above -- reused rather than 178 // re-measured, because by this point the world IS baked and a second reading here would be a 179 // reading of the wrong state dressed up as a control. 180 var sees_after: i64 = 0 181 if changed > 0 { sees_after = 1 } 182 var sees_before: i64 = 0 183 if inert != 0 { sees_before = 1 } 184 gv_bite("bite-render-sampler-sees-erosion-ONLY-after-a-bake" as *u8, sees_after, sees_before, c) 185 186 // ---- neg-control: a zero-tick budget must return every sampled height to its pre-bake value 187 let tl3: i64 = wp_erode_bake_derived(0) 188 let moved0: i64 = wp_erode_stat(1) 189 wrg_sample_hero(zero) 190 var restored: i64 = 0 191 var i4: i64 = 0 192 while i4 < hn { if zero[i4] == pre[i4] { restored = restored + 1 } i4 = i4 + 1 } 193 gv_puts(" zero-tick budget: material_moved=" as *u8); gv_num(moved0) 194 gv_puts(" lattice points back at their pre-bake height=" as *u8); gv_num(restored) 195 gv_puts(" of=" as *u8); gv_num(hn); gv_puts(" talus=" as *u8); gv_num(tl3); gv_puts("\n" as *u8) 196 gv_check("neg-control-zero-tick-budget-moves-NO-material" as *u8, moved0 == 0, c) 197 gv_check("neg-control-zero-tick-budget-restores-EVERY-lattice-point-so-the-organ-cannot-manufacture-erosion" as *u8, 198 restored == hn, c) 199 200 // ---- determinism: the published picture must be reproducible by anybody else 201 wp_erode_bake_derived(WRG_TICKS) 202 wrg_sample_hero(post2) 203 var same: i64 = 0 204 var i5: i64 = 0 205 while i5 < hn { if post2[i5] == post1[i5] { same = same + 1 } i5 = i5 + 1 } 206 gv_puts(" determinism: lattice points identical across two bakes=" as *u8); gv_num(same) 207 gv_puts(" of=" as *u8); gv_num(hn); gv_puts("\n" as *u8) 208 gv_check("two-bakes-at-one-seed-and-budget-agree-at-EVERY-lattice-point" as *u8, same == hn, c) 209 210 // ---- the artifact, as a PRECONDITION not a verdict: if the renderer has never been run there is 211 // nothing to look at, and "I could not look" is not "it is broken". 212 let afd: i64 = sys_openat_rd(WRG_ART) 213 var have: i64 = 0 214 var abytes: i64 = 0 215 var amagic: i64 = 0 216 if afd >= 0 { 217 let hdr: *u8 = sys_mmap(16) 218 let got: i64 = sys_read(afd, hdr, 8) 219 abytes = sys_lseek(afd, 0, 2) 220 sys_close(afd) 221 have = 1 222 if got == 8 { if hdr[0] == (137 as u8) { if hdr[1] == (80 as u8) { if hdr[2] == (78 as u8) { if hdr[3] == (71 as u8) { amagic = 1 } } } } } 223 } 224 gv_puts(" artifact " as *u8); gv_puts(WRG_ART) 225 gv_puts(": present=" as *u8); gv_num(have) 226 gv_puts(" bytes=" as *u8); gv_num(abytes) 227 gv_puts(" png_signature=" as *u8); gv_num(amagic); gv_puts("\n" as *u8) 228 if gv_need("knowledge/nx_worldpipe_eroded.png (run nx_worldpipe_render first)" as *u8, have, c) == 1 { 229 gv_check("the-rendered-artifact-on-disk-carries-a-real-PNG-signature" as *u8, amagic == 1, c) 230 } 231 232 return gv_verdict("nx_worldpipe_render_gate" as *u8, c, 233 "The rung is REACH, not correctness: erosion was proven by nx_worldpipe_erode_gate and was still inert in production because no consumer baked. Every tooth here is bound to a full population -- 102,400 hydrology cells and 9,409 hero lattice points, the very points the renderer turns into pixels -- and the two negative controls are the load-bearing ones: an unbaked world reads exactly zero at every cell (so no other importer moves), and a zero-tick budget restores every sampled height (so the organ cannot manufacture the erosion it reports). Scope, declared: this gate measures HEIGHTS, not pixels; that the PNG on disk decodes and that the live page serves it are proven outside, by nx_page_verify." as *u8) 234}