code wiki / _hdl_build / nx_rule_soundness.nx

nx_rule_soundness.nx

buildroot/runtime/_hdl_build/nx_rule_soundness.nx

12466 B281 linesdepth 8pulls 9 transitivereach 3 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_rule_soundness.nx -- SOVEREIGN soundness prover for the nx_eqsat rewrite rules. Each rule in nx_eqsat.nx does a union that ASSERTS an algebraic equivalence; this organ PROVES that equivalence holds for ALL inputs in W-bit (mod 2^W) arithmetic, via the winning strategy: (1) WIDTH-INDEPENDENT INDUCTION (reuses the nx_alu_divider_proof_test.nx template): prove a per-element invariant EXHAUSTIVELY at a representative width W, plus a width-independence argument (per_rule comments) that lifts the W=8 machine-check to ANY W. For the SIX width-trivial unary rules {add_zero, sub_self, add_self, and_self, or_zero, mul_one} the lift is genuine: identity-element / group-inverse / per-bit-idempotence / k=1-shift laws DO NOT depend on W. For mul_pow2 it is k-induction with the side-condition k+1<W (base k=0, step *2 == <<1 mod 2^W). (2) EXHAUSTIVE SMALL-WIDTH: enumerate every x in [0,2^W) (and, for mul_pow2, every k in [0,W)) -- a real proof over the rule's full local operand space at W, NOT sampling. (3) nx_triangulate AS INDEPENDENT CROSS-CHECK: two independent gsim legs (LHS-eval, RHS-eval) plus an independent oracle, fed to nx_tri_pass_strict (unanimity, k_min = n_legs). Defense in depth. TWO INDEPENDENT WITNESSES, ANDed (honoring the design's two-witness claim): - WITNESS A (algebraic, SEPARATELY CODED): a NishiLang-native masked-arith computation of the rule's invariant, computed WITHOUT reading the gsim legs (so it is independent of the gsim truncation behavior). Asserts the masked identity directly. - WITNESS B (triangulation over gsim legs): the two netlist evaluators must BOTH equal the masked oracle. A rule vector is CERTIFIED iff WITNESS A holds AND WITNESS B passes. TRUNCATION-GAP DEFENSE (adversarial trap #1): nx_gsim_eval_cell computes a*b, a<<b, a+b, a-b in FULL i64 with ZERO truncation. So this organ MASKS every evaluator output (and the oracle) to (1<<W)-1 BEFORE comparison -- the check then tests the real mod-2^W identity, not a coincidental i64 identity. The algebraic witness also masks. No rule is certified on raw unmasked i64. k>=W BOUNDARY DEFENSE (adversarial trap #2): mul_pow2 fires unbounded in nx_eqsat.nx (NO k<W guard -- owed). For k>=W the identity is FALSE (2^k mod 2^W == 0 so x*2^k mod 2^W == 0 for all x, but x<<k is an out-of-range

dependencies 2 imports · 3 importers

nx_alu_divider.nx nx_triangulate.nx nx_rule_soundness.nx nx_rule_soundness_test.nx nx_self_build_cycle_test.nx nx_self_repair_cycle_test.nx

imports: nx_alu_divider.nxnx_triangulate.nx

imported by: nx_rule_soundness_test.nxnx_self_build_cycle_test.nxnx_self_repair_cycle_test.nx

structs

none

consts

55const NX_RS_ADD_ZERO: i64 = 1
56const NX_RS_SUB_SELF: i64 = 2
57const NX_RS_ADD_SELF: i64 = 3
58const NX_RS_AND_SELF: i64 = 4
59const NX_RS_OR_ZERO: i64 = 5
60const NX_RS_MUL_ONE: i64 = 6
64const NX_RS_OOR: i64 = 0 - 999999

functions

67func nx_rs_mask(w: i64) -> i64 { return (1 << w) - 1 }
71func nx_rs_mk(vals: *i64, cells: *NxGsimCell, g: *NxGsim) -> i64
79func nx_rs_witness_a(rule: i64, x: i64, w: i64) -> i64
called by 1: nx_rs_certify_unary calls 1: nx_rs_mask
108func nx_rs_oracle(rule: i64, x: i64, w: i64) -> i64
called by 1: nx_rs_certify_unary calls 1: nx_rs_mask
122func nx_rs_eval_lhs(rule: i64, x: i64, w: i64, vals: *i64, cells: *NxGsimCell, g: *NxGsim) -> i64
153func nx_rs_eval_rhs(rule: i64, x: i64, w: i64, vals: *i64, cells: *NxGsimCell, g: *NxGsim) -> i64
176func nx_rs_certify_unary(rule: i64, x: i64, w: i64,
196func nx_rs_pow2(k: i64, w: i64) -> i64
206func nx_rs_mulpow2_oracle(x: i64, k: i64, w: i64) -> i64
215func nx_rs_mulpow2_witness_a(x: i64, k: i64, w: i64) -> i64
226func nx_rule_shl_wbit(x: i64, k: i64, w: i64) -> i64
235func nx_rs_certify_mulpow2(x: i64, k: i64, w: i64,
272func nx_rs_mulpow2_boundary_unsound(x: i64, k: i64, w: i64) -> i64