code wiki / _hdl_build / nx_editjudge_gate.nx
nx_editjudge_gate.nx source
↩ module page · 148 lines · 8827 B
1// nx_editjudge_gate.nx -- proves the edit-compliance judge distinguishes the three outcomes that a
2// single "did it change" number would blur, and that its hue primitive is correct. Imports the same
3// lib the tool ships.
4//
5// T1 PERFECT SHIFT : ref yellow, gen green -> compliance ~1000, shifted == masked.
6// T2 NO CHANGE : ref yellow, gen STILL yellow -> compliance ~0, stayed == masked. THIS IS THE
7// EXACT FAILURE the retention loop hid; the judge MUST score it near zero.
8// T3 WRONG CHANGE : ref yellow, gen blue -> compliance ~0, drifted == masked. "changed" but not to
9// target must NOT count as compliance -- a magnitude-only judge would pass this.
10// T4 PARTIAL : half the masked pixels shifted -> compliance ~500 (orders correctly).
11// T5 EMPTY MASK : ref all gray (no from_hue garment) -> masked 0, compliance 0, NO divide fault.
12// An edit with nothing to edit is not a passing edit.
13// T6 HUE MATH : pure R/G/B/Y map to 0/120/240/60 degrees (the primitive is correct, not lucky).
14// T7 SAT GATE : a DESATURATED pixel at from_hue is excluded from the mask (a washed-out near-gray
15// cannot be trusted to carry a hue, and would poison the count).
16// T8 ORTHOGONALITY : the identical image (ref==gen) scores compliance 0 -- i.e. maximum RETENTION
17// yields minimum COMPLIANCE, which is the whole reason a second judge exists.
18// expect_exit: 0 license_tier: ORIGINAL
19import "nx_editjudge_lib.nx"
20import "nx_gate_verdict.nx"
21
22func gw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
23func gn(v: i64) -> i64 {
24 let b: *u8 = sys_mmap(28)
25 var m: i64 = v
26 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
27 let t: *u8 = sys_mmap(28)
28 var k: i64 = 0
29 if m == 0 { t[0] = (48 as u8); k = 1 }
30 while m > 0 { t[k] = ((48 + (m % 10)) as u8); m = m / 10; k = k + 1 }
31 var i: i64 = 0
32 while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
33 sys_write(1, b, k)
34 return 0
35}
36func g_fill(buf: *u8, npix: i64, r: i64, g: i64, b: i64) -> i64 {
37 var i: i64 = 0
38 while i < npix { buf[i*3] = (r as u8); buf[i*3+1] = (g as u8); buf[i*3+2] = (b as u8); i = i + 1 }
39 return 0
40}
41
42const G_FROM: i64 = 50 // yellow anchor
43const G_TO: i64 = 130 // green anchor
44
45func main() -> i64 {
46 gw("=== nx_editjudge_gate: does the judge tell change-to-target from no-change and wrong-change? ===\n" as *u8)
47 var pass: i64 = 0
48 var total: i64 = 0
49 let n: i64 = 100
50 let refy: *u8 = sys_mmap(n*3)
51 g_fill(refy, n, 235, 205, 40)
52 let mk: *i64 = sys_mmap(8)
53 let sh: *i64 = sys_mmap(8)
54 let dr: *i64 = sys_mmap(8)
55 let st: *i64 = sys_mmap(8)
56
57 // T1 PERFECT SHIFT
58 let g1: *u8 = sys_mmap(n*3); g_fill(g1, n, 40, 200, 70)
59 let c1: i64 = ej_compliance(refy, g1, n, G_FROM, G_TO, mk, sh, dr, st)
60 total = total + 1
61 if c1 >= 900 { if sh[0] == mk[0] { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
62 gw("T1 PERFECT SHIFT: yellow->green compliance=" as *u8); gn(c1); gw(" shifted=" as *u8); gn(sh[0]); gw("/" as *u8); gn(mk[0]); gw("\n" as *u8)
63
64 // T2 NO CHANGE (the hidden failure)
65 let g2: *u8 = sys_mmap(n*3); g_fill(g2, n, 235, 205, 40)
66 let c2: i64 = ej_compliance(refy, g2, n, G_FROM, G_TO, mk, sh, dr, st)
67 total = total + 1
68 if c2 <= 100 { if st[0] == mk[0] { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
69 gw("T2 NO CHANGE: yellow->yellow compliance=" as *u8); gn(c2); gw(" stayed=" as *u8); gn(st[0]); gw(" (the retention loop's blind spot)\n" as *u8)
70
71 // T3 WRONG CHANGE
72 let g3: *u8 = sys_mmap(n*3); g_fill(g3, n, 40, 60, 220)
73 let c3: i64 = ej_compliance(refy, g3, n, G_FROM, G_TO, mk, sh, dr, st)
74 total = total + 1
75 if c3 <= 100 { if dr[0] == mk[0] { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
76 gw("T3 WRONG CHANGE: yellow->blue compliance=" as *u8); gn(c3); gw(" drifted=" as *u8); gn(dr[0]); gw(" (changed, but not to target)\n" as *u8)
77
78 // T4 PARTIAL: first half green, second half yellow
79 let g4: *u8 = sys_mmap(n*3)
80 var i: i64 = 0
81 while i < n {
82 if i < n/2 { g4[i*3] = (40 as u8); g4[i*3+1] = (200 as u8); g4[i*3+2] = (70 as u8) }
83 else { g4[i*3] = (235 as u8); g4[i*3+1] = (205 as u8); g4[i*3+2] = (40 as u8) }
84 i = i + 1
85 }
86 let c4: i64 = ej_compliance(refy, g4, n, G_FROM, G_TO, mk, sh, dr, st)
87 total = total + 1
88 if c4 >= 400 { if c4 <= 600 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
89 gw("T4 PARTIAL: half shifted -> compliance=" as *u8); gn(c4); gw(" (want ~500)\n" as *u8)
90
91 // T5 EMPTY MASK: ref all mid-gray -> no saturated from_hue pixels
92 let refg: *u8 = sys_mmap(n*3); g_fill(refg, n, 128, 128, 128)
93 let c5: i64 = ej_compliance(refg, g1, n, G_FROM, G_TO, mk, sh, dr, st)
94 total = total + 1
95 if c5 == 0 { if mk[0] == 0 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
96 gw("T5 EMPTY MASK: no garment -> masked=" as *u8); gn(mk[0]); gw(" compliance=" as *u8); gn(c5); gw(" (no divide fault)\n" as *u8)
97
98 // T6 HUE MATH
99 let hr: i64 = ej_hue(255, 0, 0)
100 let hg: i64 = ej_hue(0, 255, 0)
101 let hb: i64 = ej_hue(0, 0, 255)
102 let hy: i64 = ej_hue(255, 255, 0)
103 total = total + 1
104 if hr == 0 { if hg == 120 { if hb == 240 { if hy == 60 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
105 gw("T6 HUE MATH: R=" as *u8); gn(hr); gw(" G=" as *u8); gn(hg); gw(" B=" as *u8); gn(hb); gw(" Y=" as *u8); gn(hy); gw(" (want 0/120/240/60)\n" as *u8)
106
107 // T7 SAT GATE: a near-gray pixel that is nominally yellow-hued must be excluded
108 let refgray: *u8 = sys_mmap(n*3); g_fill(refgray, n, 130, 128, 120) // hue ~ yellow but sat tiny
109 let cs: i64 = ej_sat(130, 128, 120)
110 let c7: i64 = ej_compliance(refgray, g1, n, G_FROM, G_TO, mk, sh, dr, st)
111 total = total + 1
112 if mk[0] == 0 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
113 gw("T7 SAT GATE: near-gray sat=" as *u8); gn(cs); gw(" (< " as *u8); gn(EJ_SAT_MIN); gw(") -> masked=" as *u8); gn(mk[0]); gw(" (excluded)\n" as *u8)
114
115 // T8 ORTHOGONALITY: identical image -> compliance 0 (max retention == min compliance)
116 let c8: i64 = ej_compliance(refy, refy, n, G_FROM, G_TO, mk, sh, dr, st)
117 total = total + 1
118 if c8 == 0 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
119 gw("T8 ORTHOGONALITY: ref==gen (max retention) -> compliance=" as *u8); gn(c8); gw(" (must be 0 -- the two judges are independent)\n" as *u8)
120
121 // T9 COLLATERAL: the mask-free footprint must separate a whole-frame repaint from a local edit.
122 // This is the tooth that would have caught the face-recolour WITHOUT sharing the editor's mask.
123 let fp_all: i64 = ej_footprint(refy, g1, n) // every pixel moved
124 let halfimg: *u8 = sys_mmap(n*3)
125 var q: i64 = 0
126 while q < n {
127 if q < n/4 { halfimg[q*3] = (40 as u8); halfimg[q*3+1] = (200 as u8); halfimg[q*3+2] = (70 as u8) }
128 else { halfimg[q*3] = refy[q*3]; halfimg[q*3+1] = refy[q*3+1]; halfimg[q*3+2] = refy[q*3+2] }
129 q = q + 1
130 }
131 let fp_quarter: i64 = ej_footprint(refy, halfimg, n)
132 total = total + 1
133 if fp_all >= 900 { if fp_quarter <= 300 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
134 gw("T9 COLLATERAL: whole-frame repaint footprint=" as *u8); gn(fp_all)
135 gw(" vs local edit footprint=" as *u8); gn(fp_quarter)
136 gw(" (mask-free -- catches what a shared mask blesses)\n" as *u8)
137
138 gw("\n=== nx_editjudge_gate " as *u8); gn(pass); gw("/" as *u8); gn(total)
139 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
140 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
141 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
142 let ctr__dry: *i64 = gv_ctr()
143 ctr__dry[0] = pass
144 ctr__dry[1] = total
145 let rc__dry: i64 = gv_verdict("EDITJUDGE-GATE" as *u8, ctr__dry, "the judge scores change-to-target high, no-change and wrong-change near zero (separately labelled), orders partial edits, refuses an empty mask without faulting, computes hue correctly, excludes untrustworthy near-gray pixels, and is or" as *u8)
146 sys_exit(rc__dry)
147 return rc__dry
148}