nx_surface_plane_coherence.nx source
↩ module page · 376 lines · 14453 B
1// nx_surface_plane_coherence.nx -- Tier 6 floor=bed spatial-impossibility.
2//
3// CAPABILITY_COMPLETENESS: FULL
4//
5// User feedback 2026-05-16 (image #4 hint): "she is on the floor
6// and bed at the same time which is impossible." AI image-gen
7// often merges distinct horizontal surfaces (floor + bed-top +
8// table-top) into one plane at one height -- a body lying flat
9// across the image rests on what the AI labels as both floor and
10// mattress simultaneously, when physically a bed sits 18-24"
11// above the floor.
12//
13// Substrate's check:
14// - Caller provides N surface records with kind + y-coordinate
15// (top edge of surface in image pixels)
16// - For each pair where kinds are DIFFERENT distinct horizontal
17// surfaces: |y_top_a - y_top_b| must exceed min_height_diff
18// - If two named-different surfaces appear at SAME height
19// (within tolerance): IMPLAUSIBLE_SAME_HEIGHT
20//
21// Surface-kind taxonomy: FLOOR / BED_TOP / TABLE_TOP / CHAIR_SEAT
22// / COUNTER_TOP / DESK_TOP / SHELF / WALL / CEILING / OTHER.
23// Pairs of HORIZONTAL surfaces (FLOOR / BED / TABLE / CHAIR /
24// COUNTER / DESK / SHELF) get the height-diff check. WALL/CEILING
25// are vertical/overhead; substrate skips them.
26//
27// genealogy_id: substrate_surface_plane_coherence_2026_05_16
28// lineage_id: tier_6_spatial_impossibility_v1
29
30import "nx_syscalls.nx"
31import "nx_runtime.nx"
32import "nx_tier.nx"
33const NX_MAGIC_1920: i64 = 1920
34const NX_MAGIC_1080: i64 = 1080
35
36const NX_SPC_Q10: nx_int = 1024
37
38// ===== sealed-enum: surface kind =================================
39
40const NX_SURFACE_UNKNOWN: nx_int = 0
41const NX_SURFACE_FLOOR: nx_int = 1
42const NX_SURFACE_BED_TOP: nx_int = 2
43const NX_SURFACE_TABLE_TOP: nx_int = 3
44const NX_SURFACE_CHAIR_SEAT: nx_int = 4
45const NX_SURFACE_COUNTER_TOP: nx_int = 5
46const NX_SURFACE_DESK_TOP: nx_int = 6
47const NX_SURFACE_SHELF: nx_int = 7
48const NX_SURFACE_WALL: nx_int = 8
49const NX_SURFACE_CEILING: nx_int = 9
50const NX_SURFACE_OTHER: nx_int = 10
51const NX_SURFACE_N_KINDS: nx_int = 11
52
53func nx_surface_kind_is_valid(k: nx_int) -> nx_int {
54 if k < 0 { return 0 }
55 if k >= NX_SURFACE_N_KINDS { return 0 }
56 return 1
57}
58
59// Horizontal-surface bitmask: substrate applies height-diff check
60// only to pairs where BOTH kinds are horizontal.
61func _spc_is_horizontal(kind: nx_int) -> nx_int {
62 if kind == NX_SURFACE_FLOOR { return 1 }
63 if kind == NX_SURFACE_BED_TOP { return 1 }
64 if kind == NX_SURFACE_TABLE_TOP { return 1 }
65 if kind == NX_SURFACE_CHAIR_SEAT { return 1 }
66 if kind == NX_SURFACE_COUNTER_TOP { return 1 }
67 if kind == NX_SURFACE_DESK_TOP { return 1 }
68 if kind == NX_SURFACE_SHELF { return 1 }
69 return 0
70}
71
72// ===== sealed-enum: aggregate verdict ============================
73
74const NX_SPC_VERDICT_COHERENT: nx_int = 0
75const NX_SPC_VERDICT_IMPLAUSIBLE_SAME_HEIGHT: nx_int = 1
76const NX_SPC_VERDICT_INVERTED_ORDER: nx_int = 2 // e.g. bed below floor
77const NX_SPC_VERDICT_NO_HORIZONTAL_SURFACES: nx_int = 3
78const NX_SPC_VERDICT_MULTIPLE_FAILURES: nx_int = 4
79
80// ===== caller bounds =============================================
81
82const NX_SPC_MAX_SURFACES: nx_int = 32
83
84// Default min height differential in pixels (caller may override).
85// Tuned for ~1080-tall images; subject domain extension allows
86// override via caller-supplied threshold.
87const NX_SPC_DEFAULT_MIN_DIFF: nx_int = 40
88
89// ===== surface record ============================================
90
91struct NxSurfaceRecord {
92 surface_id: nx_int,
93 kind: nx_int,
94 y_top: nx_int, // top edge in image pixels (smaller = higher)
95 y_bottom: nx_int, // bottom edge (for table/bed thickness)
96 bbox_x0: nx_int,
97 bbox_x1: nx_int,
98}
99
100const NX_SURFACE_RECORD_BYTES: nx_size = 48
101
102// ===== pair-violation record =====================================
103
104struct NxSurfacePairViolation {
105 surface_a_id: nx_int,
106 surface_b_id: nx_int,
107 kind_a: nx_int,
108 kind_b: nx_int,
109 y_a: nx_int,
110 y_b: nx_int,
111 diff: nx_int,
112 kind: nx_int, // 0=SAME_HEIGHT, 1=INVERTED_ORDER
113}
114
115const NX_SPC_PAIR_VIOLATION_BYTES: nx_size = 64
116
117// ===== expected vertical order ===================================
118//
119// For physically plausible scenes, certain surface kinds must be
120// ABOVE others. Returns 1 if kind A should be ABOVE kind B
121// (smaller image y), 0 otherwise / unknown.
122//
123// In an image, "above" = smaller y. A bed is physically above
124// the floor in 3D, so the bed-top has smaller image-y if both are
125// visible at the same horizontal position.
126
127func _spc_expected_above(a: nx_int, b: nx_int) -> nx_int {
128 // BED_TOP above FLOOR
129 if a == NX_SURFACE_BED_TOP {
130 if b == NX_SURFACE_FLOOR { return 1 }
131 }
132 // TABLE_TOP above FLOOR
133 if a == NX_SURFACE_TABLE_TOP {
134 if b == NX_SURFACE_FLOOR { return 1 }
135 }
136 // CHAIR_SEAT above FLOOR
137 if a == NX_SURFACE_CHAIR_SEAT {
138 if b == NX_SURFACE_FLOOR { return 1 }
139 }
140 // COUNTER_TOP / DESK_TOP / SHELF above FLOOR
141 if a == NX_SURFACE_COUNTER_TOP {
142 if b == NX_SURFACE_FLOOR { return 1 }
143 }
144 if a == NX_SURFACE_DESK_TOP {
145 if b == NX_SURFACE_FLOOR { return 1 }
146 }
147 if a == NX_SURFACE_SHELF {
148 if b == NX_SURFACE_FLOOR { return 1 }
149 }
150 return 0
151}
152
153// ===== result struct =============================================
154
155struct NxSpcResult {
156 n_surfaces: nx_int,
157 n_horizontal: nx_int,
158 n_same_height: nx_int,
159 n_inverted_order: nx_int,
160 n_total_violations: nx_int,
161 violations: *NxSurfacePairViolation,
162 verdict: nx_int,
163}
164
165const NX_SPC_RESULT_BYTES: nx_size = 56
166
167// ===== check =====================================================
168
169func nx_surface_plane_check(
170 surfaces: *NxSurfaceRecord, n_surfaces: nx_int,
171 min_height_diff: nx_int) -> *NxSpcResult {
172
173 let r_ptr: *u8 = sys_mmap(NX_SPC_RESULT_BYTES)
174 let r: *NxSpcResult = r_ptr as *NxSpcResult
175 r.n_surfaces = n_surfaces
176 r.n_horizontal = 0
177 r.n_same_height = 0
178 r.n_inverted_order = 0
179 r.n_total_violations = 0
180
181 var thr: nx_int = min_height_diff
182 if thr <= 0 { thr = NX_SPC_DEFAULT_MIN_DIFF }
183 if n_surfaces <= 0 {
184 r.verdict = NX_SPC_VERDICT_NO_HORIZONTAL_SURFACES
185 return r
186 }
187
188 // Allocate violation list.
189 let n_pairs_max: nx_int = (n_surfaces * (n_surfaces - 1)) / 2
190 let viol_bytes: nx_size = (n_pairs_max as nx_size) * NX_SPC_PAIR_VIOLATION_BYTES
191 if n_pairs_max <= 0 {
192 r.violations = 0 as *NxSurfacePairViolation
193 } else {
194 r.violations = (sys_mmap(viol_bytes)) as *NxSurfacePairViolation
195 }
196 var viol_n: nx_int = 0
197
198 // Count horizontal surfaces.
199 var i: nx_int = 0
200 while i < n_surfaces {
201 let s: *NxSurfaceRecord =
202 (surfaces as *u8 + (i as nx_size) * NX_SURFACE_RECORD_BYTES) as *NxSurfaceRecord
203 if _spc_is_horizontal(s.kind) == 1 {
204 r.n_horizontal = r.n_horizontal + 1
205 }
206 i = i + 1
207 }
208 if r.n_horizontal < 2 {
209 // Not enough horizontal surfaces for a meaningful check.
210 r.verdict = NX_SPC_VERDICT_COHERENT
211 return r
212 }
213
214 // Pairwise scan.
215 var a: nx_int = 0
216 while a < n_surfaces {
217 let sa: *NxSurfaceRecord =
218 (surfaces as *u8 + (a as nx_size) * NX_SURFACE_RECORD_BYTES) as *NxSurfaceRecord
219 if _spc_is_horizontal(sa.kind) == 1 {
220 var b: nx_int = a + 1
221 while b < n_surfaces {
222 let sb: *NxSurfaceRecord =
223 (surfaces as *u8 + (b as nx_size) * NX_SURFACE_RECORD_BYTES) as *NxSurfaceRecord
224 if _spc_is_horizontal(sb.kind) == 1 {
225 if sa.kind != sb.kind {
226 let diff_raw: nx_int = sa.y_top - sb.y_top
227 var abs_diff: nx_int = diff_raw
228 if abs_diff < 0 { abs_diff = 0 - abs_diff }
229
230 var emit: nx_int = 0
231 var v_kind: nx_int = 0
232
233 if abs_diff < thr {
234 // SAME_HEIGHT_FAIL
235 r.n_same_height = r.n_same_height + 1
236 emit = 1
237 v_kind = 0
238 } else {
239 // Check expected order.
240 let a_above_b: nx_int = _spc_expected_above(sa.kind, sb.kind)
241 let b_above_a: nx_int = _spc_expected_above(sb.kind, sa.kind)
242 if a_above_b == 1 {
243 if sa.y_top >= sb.y_top {
244 r.n_inverted_order = r.n_inverted_order + 1
245 emit = 1
246 v_kind = 1
247 }
248 }
249 if b_above_a == 1 {
250 if sb.y_top >= sa.y_top {
251 r.n_inverted_order = r.n_inverted_order + 1
252 emit = 1
253 v_kind = 1
254 }
255 }
256 }
257
258 if emit == 1 {
259 let v: *NxSurfacePairViolation =
260 (r.violations as *u8 + (viol_n as nx_size) * NX_SPC_PAIR_VIOLATION_BYTES) as *NxSurfacePairViolation
261 v.surface_a_id = sa.surface_id
262 v.surface_b_id = sb.surface_id
263 v.kind_a = sa.kind
264 v.kind_b = sb.kind
265 v.y_a = sa.y_top
266 v.y_b = sb.y_top
267 v.diff = abs_diff
268 v.kind = v_kind
269 viol_n = viol_n + 1
270 }
271 }
272 }
273 b = b + 1
274 }
275 }
276 a = a + 1
277 }
278 r.n_total_violations = viol_n
279
280 if viol_n == 0 {
281 r.verdict = NX_SPC_VERDICT_COHERENT
282 return r
283 }
284 if viol_n == 1 {
285 if r.n_same_height == 1 {
286 r.verdict = NX_SPC_VERDICT_IMPLAUSIBLE_SAME_HEIGHT
287 return r
288 }
289 r.verdict = NX_SPC_VERDICT_INVERTED_ORDER
290 return r
291 }
292 r.verdict = NX_SPC_VERDICT_MULTIPLE_FAILURES
293 return r
294}
295
296// ===== self-test =================================================
297
298func _spc_set_surface(arr: *NxSurfaceRecord, idx: nx_int,
299 sid: nx_int, kind: nx_int,
300 y_top: nx_int, y_bot: nx_int) -> nx_int {
301 let s: *NxSurfaceRecord =
302 (arr as *u8 + (idx as nx_size) * NX_SURFACE_RECORD_BYTES) as *NxSurfaceRecord
303 s.surface_id = sid
304 s.kind = kind
305 s.y_top = y_top
306 s.y_bottom = y_bot
307 s.bbox_x0 = 0
308 s.bbox_x1 = NX_MAGIC_1920
309 return 0
310}
311
312func main() -> nx_int {
313 // ---- COHERENT: floor at y=900 (image bottom), bed_top at
314 // y=600 (250 above floor). Plausible bedroom geometry.
315 let arr_ok: *NxSurfaceRecord =
316 (sys_mmap(NX_SURFACE_RECORD_BYTES * 2)) as *NxSurfaceRecord
317 _spc_set_surface(arr_ok, 0, 1, NX_SURFACE_FLOOR, 900, NX_MAGIC_1080)
318 _spc_set_surface(arr_ok, 1, 2, NX_SURFACE_BED_TOP, 600, 800)
319 let r_ok: *NxSpcResult = nx_surface_plane_check(arr_ok, 2, 0)
320 if r_ok == (0 as *NxSpcResult) { return 1 }
321 if r_ok.verdict != NX_SPC_VERDICT_COHERENT { return 2 }
322 if r_ok.n_total_violations != 0 { return 3 }
323
324 // ---- IMPLAUSIBLE_SAME_HEIGHT: floor at y=600, bed_top at y=610
325 // (the user's image #4 example: same horizontal plane).
326 let arr_same: *NxSurfaceRecord =
327 (sys_mmap(NX_SURFACE_RECORD_BYTES * 2)) as *NxSurfaceRecord
328 _spc_set_surface(arr_same, 0, 1, NX_SURFACE_FLOOR, 600, 700)
329 _spc_set_surface(arr_same, 1, 2, NX_SURFACE_BED_TOP, 610, 700)
330 let r_same: *NxSpcResult = nx_surface_plane_check(arr_same, 2, 40)
331 if r_same.n_same_height != 1 { return 10 }
332 if r_same.verdict != NX_SPC_VERDICT_IMPLAUSIBLE_SAME_HEIGHT { return 11 }
333
334 // ---- INVERTED_ORDER: bed_top BELOW floor (impossible)
335 let arr_inv: *NxSurfaceRecord =
336 (sys_mmap(NX_SURFACE_RECORD_BYTES * 2)) as *NxSurfaceRecord
337 _spc_set_surface(arr_inv, 0, 1, NX_SURFACE_FLOOR, 500, 700)
338 _spc_set_surface(arr_inv, 1, 2, NX_SURFACE_BED_TOP, 700, 800)
339 let r_inv: *NxSpcResult = nx_surface_plane_check(arr_inv, 2, 40)
340 if r_inv.n_inverted_order != 1 { return 20 }
341 if r_inv.verdict != NX_SPC_VERDICT_INVERTED_ORDER { return 21 }
342
343 // ---- MULTIPLE_FAILURES: floor + bed at same height + table
344 // inverted below floor.
345 let arr_mul: *NxSurfaceRecord =
346 (sys_mmap(NX_SURFACE_RECORD_BYTES * 3)) as *NxSurfaceRecord
347 _spc_set_surface(arr_mul, 0, 1, NX_SURFACE_FLOOR, 600, 700)
348 _spc_set_surface(arr_mul, 1, 2, NX_SURFACE_BED_TOP, 610, 700) // same height
349 _spc_set_surface(arr_mul, 2, 3, NX_SURFACE_TABLE_TOP, 800, 900) // inverted
350 let r_mul: *NxSpcResult = nx_surface_plane_check(arr_mul, 3, 40)
351 if r_mul.n_total_violations < 2 { return 30 }
352 if r_mul.verdict != NX_SPC_VERDICT_MULTIPLE_FAILURES { return 31 }
353
354 // ---- COHERENT when only one horizontal surface ----
355 let arr_one: *NxSurfaceRecord =
356 (sys_mmap(NX_SURFACE_RECORD_BYTES * 2)) as *NxSurfaceRecord
357 _spc_set_surface(arr_one, 0, 1, NX_SURFACE_FLOOR, 900, NX_MAGIC_1080)
358 _spc_set_surface(arr_one, 1, 2, NX_SURFACE_WALL, 0, NX_MAGIC_1080)
359 let r_one: *NxSpcResult = nx_surface_plane_check(arr_one, 2, 40)
360 if r_one.verdict != NX_SPC_VERDICT_COHERENT { return 40 }
361 if r_one.n_horizontal != 1 { return 41 }
362
363 // ---- COHERENT when two of same kind (two floor patches OK) ----
364 let arr_sm: *NxSurfaceRecord =
365 (sys_mmap(NX_SURFACE_RECORD_BYTES * 2)) as *NxSurfaceRecord
366 _spc_set_surface(arr_sm, 0, 1, NX_SURFACE_FLOOR, 900, NX_MAGIC_1080)
367 _spc_set_surface(arr_sm, 1, 2, NX_SURFACE_FLOOR, 905, NX_MAGIC_1080)
368 let r_sm: *NxSpcResult = nx_surface_plane_check(arr_sm, 2, 40)
369 if r_sm.verdict != NX_SPC_VERDICT_COHERENT { return 50 }
370
371 // ---- NO_HORIZONTAL_SURFACES ----
372 let r_none: *NxSpcResult = nx_surface_plane_check(arr_one, 0, 40)
373 if r_none.verdict != NX_SPC_VERDICT_NO_HORIZONTAL_SURFACES { return 60 }
374
375 return 0
376}