zoomy_core.symbolic.canonicalise module#
canonicalise(expr) — the structural-only normalisation pass.
Replaces the legacy _simplify_preserve_integrals
(ins_generator.py:4409), including its 6-iteration fixpoint loop, with
a single fixed-step pipeline of mathematically-trivial structural
rewrites that cannot alter equality.
Steps (in order):
alpha_rename()— depth-keyed canonical bound-variable names so alpha-equivalent integrals match structurally.sp.expand(Mul-over-Add only, kwargs-restricted; Integrals protected as Dummies during expand to keep their integrands intact).drop_zero_integrand()—∫0 dv = 0.kill_zero_length_integral()—∫_a^a dv = 0(structurala == bonly — nosp.simplify(lo - hi)).zero_derivative_of_free_symbol()—∂_v sym = 0for free symbols distinct fromv.drop_zero_derivative_inner()—∂_v 0 = 0.merge_integrals_over_add()— combine sibling integrals with matching(limits, deriv-wrapper); required for sibling cancellations.split_integral_over_add()— rest state: one logical equation term per Integral.
Sympy calls allowed: sp.Add (additive group axioms — combine like
terms, drop zeros), sp.Mul/Pow constructors,
sp.expand(_, mul=True, multinomial=False, …) (Mul-over-Add only),
xreplace.
Sympy calls forbidden: sp.simplify, sp.cancel, sp.together,
sp.factor, sp.collect, sp.powsimp, .doit(),
sp.diff, sp.integrate.
The pass converges in one application — no fixpoint loop is needed because every step is a contraction on a well-founded ordering (number of Integral atoms, depth of nested integrands, count of zero Add-summands).
- zoomy_core.symbolic.canonicalise.canonicalise(expr)#
Normalise
exprvia the fixed structural pipeline.Pure:
canonicalise(canonicalise(x)) == canonicalise(x). Equality-preserving:canonicalise(x - y) == 0iffxandyare structurally equal up to the canonicalisation rules (alpha-renaming of bound variables, Mul-over-Add distribution, Integral linearity, zero-collapse).