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}