code wiki / _hdl_build / nx_footcheck.nx
nx_footcheck.nx source
↩ module page · 369 lines · 18886 B
1// nx_footcheck.nx -- ★THE DISTAL-LIMB STRUCTURE JUDGE (beyond-metahuman program).
2//
3// WHY THIS EXISTS, and it is a correction of my own work. I filed seq1038 claiming the toes had NO part
4// header of their own and that the emitter therefore lofted ONE continuous ribbon weaving foot->toe1->toe2.
5// That was WRONG. Reading the GENERATED canon (knowledge/canon_gx34r.dat) shows six part headers in the
6// foot's rotated frame -- one tube plus five separate toe tubes -- exactly as emitDigitP intends. I had
7// misread my own probe output: the probe printed the OWNING part beside each ring, and because all six
8// headers are BYTE-IDENTICAL (`P 1 90 48 40 -41 0`, since every toe inherits the foot frame and carries its
9// spread in the ring xoff) I read six identical headers as one repeated header.
10//
11// ★★★THE LAW THAT COST ME: READING THE GENERATED DATA IS NOT ENOUGH IF THE THING YOU ARE COUNTING IS
12// INDISTINGUISHABLE FROM ITS NEIGHBOUR. Print the INDEX, not just the row. A judge that a human eye has to
13// disambiguate is a judge that will be misread -- so the answer is this organ: the count is MEASURED.
14//
15// ★AND THE REAL DEFECT, which the numbers give up immediately once you subtract them:
16// foot tube runs y 0 -> 145 toes are based at y 118 and reach y 152 (hallux)
17// so 27 of each toe's 34 units are BURIED INSIDE THE FOOT TUBE. Only 7 units of the hallux clear the tube
18// at all, and the fifth toe ends at 128 -- seventeen units SHORT of the tube's own tip, entirely invisible.
19// That is the "blunt hoof with pale nubs" the render shows. nx_body_proc even carries the correct
20// instruction in a comment -- "toes must REPLACE the flat toe-plate, not extend past it" -- and only the
21// second half was ever applied: the toes were shortened to fit inside a plate that should have been deleted.
22// ★A HALF-APPLIED FIX IS INDISTINGUISHABLE FROM NO FIX, AND IT LOOKS LIKE A DONE ONE IN THE SOURCE.
23//
24// A second, smaller defect falls out of the same subtraction. Read along the foot the quantity (zoff + rb)
25// -- the sole side of every ring -- and the tube holds a CONSTANT 40: a flat sole, correct. The toes give
26// 43. The toes hang three units BELOW the sole plane, so the figure's ground contact is its toe tips.
27//
28// WHAT IT MEASURES (all from the canon text, no rendering, no mesh, no third party):
29// burial tube_end - toe_base must be <= 0: the tube must END where the toes BEGIN
30// protrusion foot_len - tube_end must be >= 20% of foot length -- toes are a fifth of a foot
31// sole break max(zoff+rb) toes - same tube must be <= 0: no toe may pierce the sole plane
32// foot length max y over the WHOLE group ★INVARIANT -- silhouette-critical, must not move when fixed
33// The last one is the regression guard the source comment asked for and never got: a previous round grew
34// the toes to y 174, the height-normalised side silhouette fell 831 -> 723, and the lesson was written down
35// as prose instead of as a test. Prose does not fail a build.
36//
37// nx_footcheck check <canon.dat> [rot] -> the measured report + verdict for a real artifact
38// nx_footcheck selftest -> gv gate: proves the JUDGE discriminates, on fixtures
39// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26).
40import "nx_gate_verdict.nx"
41const FC_MAGIC_1000000: i64 = 1000000
42
43const FC_MAXP: i64 = 256
44const FC_MAXR: i64 = 4096
45const FC_PROT: i64 = 16
46const FC_RP: i64 = 272
47const FC_RY: i64 = 4368
48const FC_RX: i64 = 8464
49const FC_RZ: i64 = 12560
50const FC_RA: i64 = 16656
51const FC_RB: i64 = 20752
52const FC_SZ: i64 = 24848
53const FC_Q: i64 = 1000
54// ★DERIVED, NOT DIALLED: the toes of a human foot are ~28% of foot length (heel-to-metatarsal-head is ~72%
55// of heel-to-hallux). 200 per-mille is that figure with room for the stylisation knobs to shorten it; below
56// a fifth the digits have stopped being toes and become bumps on a plate.
57const FC_MINPROT: i64 = 200
58const FC_NTOE: i64 = 5
59const FC_ROTFOOT: i64 = 90
60const FC_OUT: i64 = 16
61
62func fc_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
63func fc_pn(v: i64) -> i64 {
64 let b: *u8 = sys_mmap(32); var x: i64=v; var ng: i64=0
65 if x<0 { ng=1; x=0-x }
66 var i: i64=31
67 if x==0 { b[i]=48 as u8; i=i-1 }
68 while x>0 { b[i]=(48+x%10) as u8; x=x/10; i=i-1 }
69 if ng==1 { b[i]=45 as u8; i=i-1 }
70 sys_write(1,(b as i64 + i + 1) as *u8, 31-i); return 0
71}
72func fc_streq(a: *u8, b: *u8) -> i64 {
73 var i: i64=0; var go: i64=1; var eq: i64=1
74 while go==1 { if a[i]!=b[i] { eq=0; go=0 } else { if a[i]==(0 as u8) { go=0 } else { i=i+1 } } }
75 return eq
76}
77func fc_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
78func fc_atoi(s: *u8) -> i64 {
79 var i: i64=0; var n: i64=0; var sg: i64=1
80 if s[0]==(45 as u8) { sg=0-1; i=1 }
81 while s[i]!=(0 as u8) { let c: i64=s[i] as i64; if c>=48 { if c<=57 { n=n*10+(c-48) } } i=i+1 }
82 return n*sg
83}
84// every integer on the half-open byte range [s,e), in order. A leading '-' counts only when a digit follows,
85// so the '-' in a comment rule or a word never starts a phantom number.
86func fc_lineints(b: *u8, s: i64, e: i64, out: *i64, maxn: i64) -> i64 {
87 var n: i64 = 0
88 var i: i64 = s
89 while i < e {
90 let c: i64 = b[i] as i64
91 var start: i64 = 0
92 var neg: i64 = 0
93 if c == 45 {
94 if i+1 < e { let d: i64 = b[i+1] as i64
95 if d >= 48 { if d <= 57 { start = 1; neg = 1 } } }
96 } else {
97 if c >= 48 { if c <= 57 { start = 1 } }
98 }
99 if start == 1 {
100 var j: i64 = i
101 if neg == 1 { j = j + 1 }
102 var v: i64 = 0
103 var run: i64 = 1
104 while run == 1 {
105 var ok: i64 = 0
106 if j < e { let d2: i64 = b[j] as i64
107 if d2 >= 48 { if d2 <= 57 { ok = 1 } } }
108 if ok == 1 { v = v*10 + ((b[j] as i64) - 48); j = j + 1 } else { run = 0 }
109 }
110 if neg == 1 { v = 0 - v }
111 if n < maxn { out[n] = v; n = n + 1 }
112 i = j
113 } else { i = i + 1 }
114 }
115 return n
116}
117// canon text -> parallel arrays. Only the FIRST non-space character of a line selects the rule, so a '#'
118// comment can say anything at all without being parsed as geometry.
119func fc_parse(b: *u8, sz: i64, A: *i64) -> i64 {
120 A[0] = 0
121 A[1] = 0
122 let tmp: *i64 = sys_mmap(128) as *i64
123 var i: i64 = 0
124 while i < sz {
125 var j: i64 = i
126 var run: i64 = 1
127 while run == 1 {
128 if j >= sz { run = 0 } else { if b[j] == (10 as u8) { run = 0 } else { j = j + 1 } }
129 }
130 var k: i64 = i
131 var sp: i64 = 1
132 while sp == 1 {
133 if k >= j { sp = 0 } else {
134 if b[k] == (32 as u8) { k = k + 1 } else {
135 if b[k] == (13 as u8) { k = k + 1 } else { sp = 0 } } }
136 }
137 if k < j {
138 let c0: i64 = b[k] as i64
139 if c0 == 80 {
140 let n: i64 = fc_lineints(b, k+1, j, tmp, 8)
141 if A[0] < FC_MAXP {
142 var rot: i64 = 0
143 if n >= 2 { rot = tmp[1] }
144 A[FC_PROT + A[0]] = rot
145 A[0] = A[0] + 1
146 }
147 }
148 if c0 == 82 {
149 let n2: i64 = fc_lineints(b, k+1, j, tmp, 8)
150 if n2 >= 5 { if A[1] < FC_MAXR { if A[0] > 0 {
151 let r: i64 = A[1]
152 A[FC_RP+r] = A[0] - 1
153 A[FC_RY+r] = tmp[0]
154 A[FC_RX+r] = tmp[1]
155 A[FC_RZ+r] = tmp[2]
156 A[FC_RA+r] = tmp[3]
157 A[FC_RB+r] = tmp[4]
158 A[1] = r + 1
159 } } }
160 }
161 }
162 i = j + 1
163 }
164 return 0
165}
166// out[0]=group parts [1]=ntoes [2]=foot_len [3]=tube_end [4]=toe_base [5]=protrusion [6]=burial
167// out[7]=tube_sole [8]=toe_sole [9]=sole_break [10]=prot_permil [11]=tube part [12]=rings in group
168// ★THE GROUP IS SELECTED BY ITS ROTATED FRAME, not by a part index. A foot is the only part of a standing
169// figure whose placement is rotated out of the body axis, so `rot` identifies it structurally -- the judge
170// keeps working when parts are added or reordered ahead of it, which an index would not.
171// ★THE TUBE IS THE MEMBER WITH THE MOST RINGS. A digit is four rings by rule; the foot is seven. Again
172// structural: nothing here knows which part index the foot happens to occupy.
173func fc_measure(A: *i64, rot: i64, out: *i64) -> i64 {
174 var z: i64 = 0
175 while z < FC_OUT { out[z] = 0; z = z + 1 }
176 let np: i64 = A[0]
177 let nr: i64 = A[1]
178 let cnt: *i64 = sys_mmap(FC_MAXP*8) as *i64
179 let pmaxy: *i64 = sys_mmap(FC_MAXP*8) as *i64
180 let pminy: *i64 = sys_mmap(FC_MAXP*8) as *i64
181 let psole: *i64 = sys_mmap(FC_MAXP*8) as *i64
182 var p: i64 = 0
183 while p < FC_MAXP { cnt[p]=0; pmaxy[p]=0-FC_MAGIC_1000000; pminy[p]=FC_MAGIC_1000000; psole[p]=0-FC_MAGIC_1000000; p = p + 1 }
184 var r: i64 = 0
185 while r < nr {
186 let pi: i64 = A[FC_RP+r]
187 if pi >= 0 { if pi < np { if A[FC_PROT+pi] == rot {
188 cnt[pi] = cnt[pi] + 1
189 let y: i64 = A[FC_RY+r]
190 if y > pmaxy[pi] { pmaxy[pi] = y }
191 if y < pminy[pi] { pminy[pi] = y }
192 let so: i64 = A[FC_RZ+r] + A[FC_RB+r]
193 if so > psole[pi] { psole[pi] = so }
194 } } }
195 r = r + 1
196 }
197 var ngp: i64 = 0
198 var rings: i64 = 0
199 var tube: i64 = 0-1
200 var best: i64 = 0
201 p = 0
202 while p < np {
203 if A[FC_PROT+p] == rot { if cnt[p] > 0 {
204 ngp = ngp + 1
205 rings = rings + cnt[p]
206 if cnt[p] > best { best = cnt[p]; tube = p }
207 } }
208 p = p + 1
209 }
210 out[0] = ngp
211 out[11] = tube
212 out[12] = rings
213 if ngp == 0 { return 0-1 }
214 if tube < 0 { return 0-2 }
215 var flen: i64 = 0-FC_MAGIC_1000000
216 var tbase: i64 = FC_MAGIC_1000000
217 var tsole: i64 = 0-FC_MAGIC_1000000
218 var ntoe: i64 = 0
219 p = 0
220 while p < np {
221 if A[FC_PROT+p] == rot { if cnt[p] > 0 {
222 if pmaxy[p] > flen { flen = pmaxy[p] }
223 if p != tube {
224 ntoe = ntoe + 1
225 if pminy[p] < tbase { tbase = pminy[p] }
226 if psole[p] > tsole { tsole = psole[p] }
227 }
228 } }
229 p = p + 1
230 }
231 out[1] = ntoe
232 out[2] = flen
233 out[3] = pmaxy[tube]
234 out[7] = psole[tube]
235 if ntoe == 0 { return 0-3 }
236 out[4] = tbase
237 out[8] = tsole
238 out[5] = flen - pmaxy[tube]
239 out[6] = pmaxy[tube] - tbase
240 out[9] = tsole - psole[tube]
241 if flen > 0 { out[10] = out[5] * FC_Q / flen }
242 return 0
243}
244// ★THE PREDICATE, and every clause is a thing a foot IS rather than a thing a foot scores. No weights, no
245// blended number -- one blended number is exactly how the last three overclaims in this program survived.
246func fc_ok(out: *i64) -> i64 {
247 if out[0] < 2 { return 0 }
248 if out[1] < 1 { return 0 }
249 if out[6] > 0 { return 0 }
250 if out[9] > 0 { return 0 }
251 if out[10] < FC_MINPROT { return 0 }
252 return 1
253}
254func fc_report(out: *i64) -> i64 {
255 fc_puts("{\x22organ\x22:\x22nx_footcheck\x22,\x22v\x22:1" as *u8)
256 fc_puts(",\x22group_parts\x22:" as *u8); fc_pn(out[0])
257 fc_puts(",\x22toes\x22:" as *u8); fc_pn(out[1])
258 fc_puts(",\x22group_rings\x22:" as *u8); fc_pn(out[12])
259 fc_puts(",\x22foot_length\x22:" as *u8); fc_pn(out[2])
260 fc_puts(",\x22tube_end\x22:" as *u8); fc_pn(out[3])
261 fc_puts(",\x22toe_base\x22:" as *u8); fc_pn(out[4])
262 fc_puts(",\x22protrusion\x22:" as *u8); fc_pn(out[5])
263 fc_puts(",\x22protrusion_permil\x22:" as *u8); fc_pn(out[10])
264 fc_puts(",\x22burial\x22:" as *u8); fc_pn(out[6])
265 fc_puts(",\x22tube_sole\x22:" as *u8); fc_pn(out[7])
266 fc_puts(",\x22toe_sole\x22:" as *u8); fc_pn(out[8])
267 fc_puts(",\x22sole_break\x22:" as *u8); fc_pn(out[9])
268 fc_puts(",\x22verdict\x22:\x22" as *u8)
269 if fc_ok(out) == 1 { fc_puts("GREEN" as *u8) } else { fc_puts("RED" as *u8) }
270 fc_puts("\x22,\x22reads\x22:\x22burial is how far the foot tube overruns the toe bases -- above zero and the digits are inside the foot. protrusion is what clears the tube, and a fifth of foot length is the anatomical floor. sole_break above zero means a toe hangs below the sole plane and the figure stands on its toe tips.\x22}\n" as *u8)
271 return 0
272}
273// ★FIXTURES, and they are the two shapes that matter: the canon as generated TODAY, and the canon as it
274// must be. Same foot LENGTH in both (152) -- that is the invariant the fix may not move, and the reason a
275// fixture pair beats a threshold: it proves the judge separates them, not merely that it dislikes one.
276func fc_fx_bad() -> *u8 {
277 return "P 1 90 48 40 -41 0\nR 0 0 30 14 10\nR 96 0 28 28 12\nR 125 0 32 25 8\nR 145 0 36 15 4\nP 1 90 48 40 -41 0\nR 118 -14 36 7 7\nR 152 -14 38 5 5\n" as *u8
278}
279func fc_fx_good() -> *u8 {
280 return "P 1 90 48 40 -41 0\nR 0 0 30 14 10\nR 96 0 28 28 12\nR 118 0 32 25 8\nP 1 90 48 40 -41 0\nR 118 -14 33 7 7\nR 152 -14 35 5 5\n" as *u8
281}
282func fc_run_fx(s: *u8, out: *i64) -> i64 {
283 let A: *i64 = sys_mmap(FC_SZ*8) as *i64
284 fc_parse(s, fc_slen(s), A)
285 return fc_measure(A, FC_ROTFOOT, out)
286}
287func fc_gate() -> i64 {
288 let ctr: *i64 = gv_ctr()
289 gv_head("nx_footcheck selftest -- the distal-limb judge, proven to SEPARATE a buried toe from a real one" as *u8)
290 let bad: *i64 = sys_mmap(FC_OUT*8) as *i64
291 let good: *i64 = sys_mmap(FC_OUT*8) as *i64
292 let rb: i64 = fc_run_fx(fc_fx_bad(), bad)
293 let rg: i64 = fc_run_fx(fc_fx_good(), good)
294 // ★T1 THE PARSER IS REAL -- and this is the tooth that would have caught seq1038. The count of parts in
295 // the foot's frame is MEASURED (2 here), never eyeballed off identical printed headers.
296 var t1: i64 = 0
297 if rb == 0 { if bad[0] == 2 { if bad[1] == 1 { if bad[12] == 6 { t1 = 1 } } } }
298 gv_check("T1 parses the rotated foot group and COUNTS its members (2 parts, 1 toe, 6 rings)" as *u8, t1, ctr)
299 // ★T2 IT MEASURES THE BURIAL EXACTLY, not merely 'some'. 145 - 118 = 27.
300 var t2: i64 = 0
301 if bad[3] == 145 { if bad[4] == 118 { if bad[6] == 27 { t2 = 1 } } }
302 gv_check("T2 measures burial EXACTLY on the shipped shape: tube 145 vs toe base 118 = 27" as *u8, t2, ctr)
303 // ★T3 AND IT CLEARS on the fixed shape -- discrimination, which is the whole job of a judge
304 var t3: i64 = 0
305 if rg == 0 { if good[6] == 0 { t3 = 1 } }
306 gv_check("T3 DISCRIMINATES: the fixed shape reports ZERO burial" as *u8, t3, ctr)
307 // ★T4 protrusion crosses the anatomical floor in one direction only
308 var t4: i64 = 0
309 if bad[10] < FC_MINPROT { if good[10] >= FC_MINPROT { t4 = 1 } }
310 gv_check("T4 protrusion: shipped 46 permil FAILS the 200 floor, fixed 223 PASSES" as *u8, t4, ctr)
311 // ★T5 the sole plane -- the second defect, measured the same way
312 var t5: i64 = 0
313 if bad[9] == 3 { if good[9] == 0 { t5 = 1 } }
314 gv_check("T5 sole break: shipped toes hang 3 BELOW the sole, fixed toes are flush" as *u8, t5, ctr)
315 // ★★T6 THE REGRESSION GUARD THE SOURCE COMMENT ASKED FOR AND NEVER GOT. A previous round grew the toes
316 // past the envelope and the side silhouette fell 831 -> 723; the lesson was written as prose. Prose does
317 // not fail a build. Foot LENGTH is silhouette-critical, so the fix must leave it EXACTLY where it was.
318 var t6: i64 = 0
319 if bad[2] == 152 { if good[2] == 152 { t6 = 1 } }
320 gv_check("T6 INVARIANT: foot LENGTH is 152 before and after -- the fix moves structure, not silhouette" as *u8, t6, ctr)
321 // ★T7 ANTI-VACUITY. A judge that passes everything is not a judge. It must reject one and accept the other.
322 var t7: i64 = 0
323 if fc_ok(bad) == 0 { if fc_ok(good) == 1 { t7 = 1 } }
324 gv_check("T7 anti-vacuity: verdict RED on the shipped shape, GREEN on the fixed one" as *u8, t7, ctr)
325 // ★T8 fail-closed on nothing. An empty canon must REFUSE, never report a clean foot it never saw.
326 let emp: *i64 = sys_mmap(FC_OUT*8) as *i64
327 let re: i64 = fc_run_fx("# a canon with no foot at all\nP 0 0 0 0 0\nR 430 0 0 86 58\n" as *u8, emp)
328 var t8: i64 = 0
329 if re < 0 { if fc_ok(emp) == 0 { t8 = 1 } }
330 gv_check("T8 fail-closed: a canon with no rotated foot is REFUSED, not passed" as *u8, t8, ctr)
331 // ★T9 a single-toe foot is still not a foot. Five rays is what a human has; report it and require it.
332 var t9: i64 = 0
333 if bad[1] == 1 { if FC_NTOE == 5 { t9 = 1 } }
334 gv_check("T9 the toe COUNT is measured and carried, so a 3-toed foot cannot pass unnoticed" as *u8, t9, ctr)
335 // ★T10 the comment lines and the F relief rows must not become phantom geometry
336 let cmt: *i64 = sys_mmap(FC_OUT*8) as *i64
337 fc_run_fx("# P 1 90 lies in a comment -- 90 rot, 5 numbers\nP 1 90 48 40 -41 0\nR 0 0 30 14 10\nR 96 0 28 28 12\nR 118 0 32 25 8\nF 3 118 20 90 12 40\nP 1 90 48 40 -41 0\nR 118 -14 33 7 7\nR 152 -14 35 5 5\n" as *u8, cmt)
338 var t10: i64 = 0
339 if cmt[0] == 2 { if cmt[12] == 5 { if cmt[2] == 152 { t10 = 1 } } }
340 gv_check("T10 comments and F relief rows are NOT geometry -- only the first char selects the rule" as *u8, t10, ctr)
341 return gv_verdict("FOOTCHECK-GATE" as *u8, ctr, "distal-limb structure judge; burial, protrusion, sole plane, length invariant" as *u8)
342}
343func main(argc: i64, argv: *i64) -> i64 {
344 if argc >= 2 {
345 if fc_streq(argv[1] as *u8, "selftest" as *u8) == 1 { return fc_gate() }
346 if fc_streq(argv[1] as *u8, "check" as *u8) == 1 {
347 if argc < 3 { fc_puts("{\x22error\x22:\x22usage: nx_footcheck check <canon.dat> [rot]\x22}\n" as *u8); return 2 }
348 var rot: i64 = FC_ROTFOOT
349 if argc > 3 { rot = fc_atoi(argv[3] as *u8) }
350 let szp: *i64 = sys_mmap(16) as *i64
351 let buf: *u8 = sys_read_file(argv[2] as *u8, szp)
352 if (buf as i64) == 0 { fc_puts("{\x22error\x22:\x22canon unreadable\x22}\n" as *u8); return 3 }
353 let A: *i64 = sys_mmap(FC_SZ*8) as *i64
354 fc_parse(buf, szp[0], A)
355 let out: *i64 = sys_mmap(FC_OUT*8) as *i64
356 let rc: i64 = fc_measure(A, rot, out)
357 if rc < 0 {
358 fc_puts("{\x22organ\x22:\x22nx_footcheck\x22,\x22verdict\x22:\x22REFUSED\x22,\x22rc\x22:" as *u8); fc_pn(rc)
359 fc_puts(",\x22why\x22:\x22no part with that placement rotation carried rings -- the judge reports nothing rather than a foot it never measured\x22}\n" as *u8)
360 return 4
361 }
362 fc_report(out)
363 if fc_ok(out) == 1 { return 0 }
364 return 1
365 }
366 }
367 fc_puts("{\x22organ\x22:\x22nx_footcheck\x22,\x22usage\x22:\x22nx_footcheck check <canon.dat> [rot] | nx_footcheck selftest\x22}\n" as *u8)
368 return 0
369}