code wiki / (root) / nx_eqprobe.nx

nx_eqprobe.nx source

↩ module page · 66 lines · 4119 B

1// nx_eqprobe.nx -- MINIMAL REPRO for the suspected `if v == CONST` compiling as `if v > CONST` 2// (debt 1785530065, found in nx_mcu_ready.nx rdy_reason). 3// 4// Deliberately tiny and self-contained: its own puts, its own 4-branch dispatch, no shared helpers, so 5// nothing but the compiler can explain a wrong answer. THE DISCRIMINATOR IS pick(999): 999 matches NO 6// branch, so a correct compiler MUST return "D". If equality is emitted as greater-than, 999 > 100 is 7// true and it returns "A". 8// 9// EXPECTED (correct): 100->A 101->B 102->C 999->D 10// EXPECTED (== behaves as >): 100->D 101->A 102->A 999->A 11// 12// VARIANT KNOB: this file currently imports ONLY nx_syscalls. The broken rdy_reason lives in a file that 13// imports TWO further modules, while the WORKING mf_reason imports only nx_syscalls -- so import count is 14// the leading candidate trigger. Re-run this probe after adding those imports to A/B the hypothesis. 15// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 16import "nx_syscalls.nx" 17// STEP 2 OF THE A/B: the A-side (nx_syscalls only) came back GREEN -- equality dispatched correctly, 18// including the pick(999) discriminator. Now add the two imports that the BROKEN nx_mcu_ready.nx carries, 19// changing NOTHING else. If the dispatch stays correct, import count is REFUTED as the trigger and the 20// nx_mcu_ready defect needs a different explanation. If it breaks, import count is CONFIRMED. 21import "nx_mcu_fit.nx" 22import "nx_mcu_brick.nx" 23 24const EQ_A: i64 = 100 25const EQ_B: i64 = 101 26const EQ_C: i64 = 102 27 28func eq_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 29func eq_p(s: *u8) -> i64 { sys_write(1, s, eq_len(s)); return 0 } 30 31// STEP 3: imports were REFUTED (still correct with 2 extra modules) and == was REFUTED (pick(999)=D). 32// Remaining difference vs the broken rdy_reason: THESE LITERALS WERE 1 CHARACTER LONG. rdy_reason returns 33// LONG literals (52-104 chars) containing spaces, '=', '(', '--' and '+'. If the defect is in the string 34// LITERAL POOL rather than the branch logic, lengthening the literals should reproduce it while the 35// control characters below still identify which branch was actually taken. 36// Each string still STARTS with its identifying letter, so the A/B/C/D checks are unchanged. 37func eq_pick(v: i64) -> *u8 { 38 if v == EQ_A { return "A -- fits the target and the write is reversible" as *u8 } 39 if v == EQ_B { return "B blocker=FIT (safe to write, but the model does not fit)" as *u8 } 40 if v == EQ_C { return "C blocker=SAFETY (fits, but the write is NOT reversible -- Rule 26)" as *u8 } 41 return "D blocker=SAFETY+FIT (unsafe AND does not fit; safety is the one that must never be worked around)" as *u8 42} 43 44func main() -> i64 { 45 eq_p("nx_eqprobe -- does `if v == CONST` dispatch correctly? (imports: nx_syscalls only)\n" as *u8) 46 eq_p(" pick(100) = " as *u8); eq_p(eq_pick(100)); eq_p(" (want A)\n" as *u8) 47 eq_p(" pick(101) = " as *u8); eq_p(eq_pick(101)); eq_p(" (want B)\n" as *u8) 48 eq_p(" pick(102) = " as *u8); eq_p(eq_pick(102)); eq_p(" (want C)\n" as *u8) 49 eq_p(" pick(999) = " as *u8); eq_p(eq_pick(999)); eq_p(" (want D -- THE DISCRIMINATOR)\n" as *u8) 50 // ⚠FIRST RUN PRINTED ALL FOUR CORRECTLY (100=A 101=B 102=C 999=D) YET REPORTED RED. 51 // The printing path passes the call result straight to eq_p; the CHECKING path indexed it as 52 // eq_pick(100)[0] -- INDEXING A CALL RESULT, the documented "NO fn().field" gotcha family. 53 // So the earlier RED was MY CHECK miscompiling, not the dispatch. Hoist to a temp and re-measure. 54 let s0: *u8 = eq_pick(100) 55 let s1: *u8 = eq_pick(101) 56 let s2: *u8 = eq_pick(102) 57 let s9: *u8 = eq_pick(999) 58 var ok: i64 = 1 59 if s0[0] != (65 as u8) { ok = 0 } 60 if s1[0] != (66 as u8) { ok = 0 } 61 if s2[0] != (67 as u8) { ok = 0 } 62 if s9[0] != (68 as u8) { ok = 0 } 63 if ok == 1 { eq_p("NX-EQPROBE verdict=GREEN -- equality dispatches correctly here\n" as *u8); return 0 } 64 eq_p("NX-EQPROBE verdict=RED -- equality dispatch is WRONG (see pick(999))\n" as *u8) 65 return 1 66}