Skip to content

Fix #346: fold duplicate mul factors instead of throwing - #400

Merged
petlenz merged 2 commits into
mainfrom
fix-346-mul-duplicate-factor
Jul 30, 2026
Merged

Fix #346: fold duplicate mul factors instead of throwing#400
petlenz merged 2 commits into
mainfrom
fix-346-mul-duplicate-factor

Conversation

@petlenz

@petlenz petlenz commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #346. Stacked on #399.

sin(x) * (sin(x) * y) threw internal_error: n_ary_tree::insert_hash: duplicate child insertion instead of producing sin(x)²·y — the generic mul_dispatch::dispatch(mul_type) fallback pushed the LHS factor unconditionally, and function-type factors (not intercepted by the symbol/mul/pow domain dispatchers) hit the duplicate guard.

Design

n_ary_tree::merge_or_insert_mul — the *-combining sibling of merge_or_insert (exact keys only; mul factor maps have no coefficient-bearing like terms) — replaces the bare push_back. A duplicate factor combines via the exponent-addition rule (sin(x)·sin(x) → pow(sin(x),2)), and chained collisions (the pow result meeting an existing pow factor) converge through the same loop.

Tests

Evaluation-verified lock-in for sin/log factors plus the chained-collision case. Full suite: 2431/2431 pass. gcc-14 -Werror check clean.

@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from 150c225 to 3e626cc Compare July 25, 2026 12:09
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from 5c5b314 to ce0ac03 Compare July 25, 2026 12:11
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from 3e626cc to 9af5448 Compare July 25, 2026 13:25
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from ce0ac03 to d8d0c05 Compare July 25, 2026 13:26
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from 42da614 to 9121a68 Compare July 25, 2026 22:30
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from d8d0c05 to 4cd6afb Compare July 25, 2026 22:33
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from 9121a68 to a4eff94 Compare July 26, 2026 12:14
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from 4cd6afb to 4e982ab Compare July 26, 2026 12:14
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from a4eff94 to b731e94 Compare July 26, 2026 12:43
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch 2 times, most recently from acdea06 to b96ddbc Compare July 26, 2026 17:18
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from b731e94 to 8e05846 Compare July 26, 2026 17:18
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from b96ddbc to 8d208df Compare July 26, 2026 17:42
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from 8e05846 to 352c37e Compare July 26, 2026 17:42
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from 8d208df to 8003b27 Compare July 26, 2026 18:16
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch 2 times, most recently from b20178b to 517baa9 Compare July 26, 2026 18:40
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from 8003b27 to 2d4cbd1 Compare July 26, 2026 18:40
petlenz added 2 commits July 26, 2026 20:58
mul_dispatch::dispatch(mul_type) pushed the LHS factor into a copy of
the RHS product unconditionally; n_ary_tree::insert_hash throws on
duplicate keys, so sin(x) * (sin(x)*y) crashed with
'internal_error: duplicate child insertion' instead of producing
sin(x)^2*y. Symbol/mul/pow LHS types are intercepted by domain
dispatchers; function-type factors reached this fallback.

n_ary_tree gains merge_or_insert_mul (the *-combining sibling of
merge_or_insert, exact keys only) and the dispatch uses it; a
duplicate factor now combines via the exponent-addition rule, and a
chained collision (pow result meeting an existing pow factor)
converges the same way.

Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
The merge_or_insert_mul fix covered only x * (x*y); the mirrored
order (sin(x)*y) * sin(x) and the mul*mul factor chain
(sin(x)*y) * (sin(x)*z) still threw 'duplicate child insertion'
through the generic mul-LHS dispatch's bare push_back - multiplication
was commutative in value but not in outcome. That dispatch now routes
through merge_or_insert_mul too (the mul*mul chain re-enters it per
factor, so one fix covers both probes).

Also corrects the misleading 'chained collision' test comment:
sin(x) and pow(sin(x),2) are distinct exact keys and deliberately
coexist (pow-base folding is epic #379's scope).

Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
@petlenz
petlenz force-pushed the fix-342-343-index-sequence-identity branch from 517baa9 to df50715 Compare July 26, 2026 19:03
@petlenz
petlenz force-pushed the fix-346-mul-duplicate-factor branch from 2d4cbd1 to 64eb402 Compare July 26, 2026 19:03
@petlenz
petlenz changed the base branch from fix-342-343-index-sequence-identity to main July 30, 2026 06:53
@petlenz
petlenz merged commit 12be5dc into main Jul 30, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mul simplifier fallback throws internal_error on sin(x)*(sin(x)*y) — "duplicate child insertion" instead of sin(x)^2*y

1 participant