code wiki / _hdl_build / nx_eqsat_congruence_test.nx

nx_eqsat_congruence_test.nx

buildroot/runtime/_hdl_build/nx_eqsat_congruence_test.nx

9971 B185 linesdepth 7pulls 9 transitivereach 0 importersview sourcekind gate/prooftopic eqsat
docsdependenciesstructsconstsfunctions

about

nx_eqsat_congruence_test.nx -- STRUCTURAL-WITNESS GATE for the egg-style deferred CONGRUENCE CLOSURE newly integrated into nx_eqsat.nx. THE PROOF (the new organ actually MEETS egg's congruence rebuild): Congruence axiom of equality: if a == b (same canonical e-class) then for any deterministic function f, f(...a...) == f(...b...). The pre-MEET engine had a real hashcons-by-linear-scan + union-find, but NO rebuild: after a union it never re-merged congruent PARENTS, so f(a) and f(b) stayed in distinct classes. This gate builds exactly that witness and proves the rebuild closes it. CASE 1 (POSITIVE -- congruence FIRES, cited + logged sound): Build a, b as two DISTINCT vars; build g_a = NEG(a) and g_b = NEG(b) (so the two parent e-nodes are genuinely different nodes). Pre-merge a~b via the SOUND mul_pow2 path is overkill; instead we drive the canonical congruence trigger through the real saturator: a=(mul x 8), b=(shl x 3) -> mul_pow2 merges them, then NEG(a) and NEG(b) MUST become congruent via the rebuild (same op NEG, same payload, canonically-equal child). Assert: (1a) find(NEG a) == find(NEG b) -- congruence detected (1b) the prov log contains id 8 (CONGRUENCE) -- the merge was CITED (1c) every logged id is in the proven-sound allow-list (0..8, !=NONE-as-bad) (1d) RULE_NONE (id 0) count == 0 -- no back-door (2-arg) merge CASE 2 (NEGATIVE control -- WITHOUT rebuild the gap is REAL): Same graph, but provenance/meet OFF on a plain engine run (rebuild disabled): mul_pow2 still merges (mul x 8)~(shl x 3), but the parents NEG(mul8)/NEG(shl3) are NOT merged -> find(NEG a) != find(NEG b). This proves the rebuild is the load-bearing organ (a passing CASE 1 is not vacuous). CASE 3 (NEGATIVE -- non-congruent nodes are NOT merged): NEG(a) vs NOT(a): same single child class but DIFFERENT op -> distinct fingerprints -> never congruence-merged. Asserts the fingerprint folds op (a fingerprint that ignored op would wrongly merge them and cite CONGRUENCE). KNOWN ANSWER (FAIL LOUD), one line: "<case1_member> <cong_logged> <none_count> <case2_member> <case3_member>" = "1 1 0 0 0 " exit 0 iff every assertion holds. SOVEREIGN: no SMT, no .sh; runs on the pinned NishiLang compiler. The exit code IS the verdict. license_tier: ORIGINAL

dependencies 1 imports · 0 importers

nx_eqsat.nx nx_eqsat_congruence_test.nx

imports: nx_eqsat.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main nx_eqsat_init nx_eqsat_enable_meet nx_eqsat_enable_prov nx_eqsat_add_var nx_eqsat_add nx_eqsat_op_is_valid nx_eqsat_arity_for nx_cf_intern_const nx_eqsat_add_const nx_eqsat_add ↻ nx_eqsat_mix nx_cf_make_const_node nx_eqsat_new_class nx_eqsat_find nx_eqsat_find ↻ nx_eqsat_fold_value nx_eqsat_op_to_gate_kind nx_gsim_kind_supported nx_eqsat_arity_for ↻ nx_eqsat_find ↻ nx_gsim_eval_cell nx_eqsat_op_cost nx_eqsat_new_class ↻ nx_eqsat_union_cited nx_eqsat_find ↻ nx_eqsat_log_rule nx_eqsat_push_dirty nx_eqsat_fingerprint nx_eqsat_mix ↻ nx_hmap_has nx_hmap_probe_find nx_hmap_hash nx_hmap_entry_at nx_hmap_get nx_hmap_probe_find ↻ nx_hmap_entry_at ↻ nx_eqsat_node_matches nx_eqsat_arity_for ↻ nx_eqsat_find ↻

structs

none

consts

none

functions

43func _emit_num(v: i64) -> i64
called by 1: main
51func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 }
called by 1: main
56func _scan_log(g: *NxEGraph, want: i64, none_out: *i64, anybad_out: *i64) -> i64
called by 1: main
83func main() -> i64