zoomy_core.symbolic.sp_safe module#
Held-form sympy constructors for the symbolic primitive layer.
Sympy’s default constructors auto-evaluate where they can:
sp.Derivative(x**2, x) returns 2*x, not a held atom. This
auto-evaluation is the root of every “math fired at the wrong pipeline
position” bug we’ve hit — the framework can’t keep an opaque atom
opaque if sympy decides to evaluate it on construction.
The constructors here always pass evaluate=False. Every primitive
in this package must use them when it constructs a fresh Derivative,
Integral or Subs atom. A CI grep forbids bare sp.Derivative(...),
sp.Integral(...), sp.diff(...) calls inside the symbolic
subpackage.
- zoomy_core.symbolic.sp_safe.D(expr, *vars)#
Held
Derivative(expr, *vars).- Parameters:
expr (sympy.Expr) –
*vars – Each entry is either a single
Symbol(∂_v applied once) or a(symbol, n)tuple (∂_v^n). Same shape sympy’sDerivativeaccepts.
- Returns:
Always held — never auto-evaluated. The primitive layer decides when to apply chain/product/Leibniz rules.
- Return type:
sympy.Derivative
- zoomy_core.symbolic.sp_safe.Int(integrand, *limits)#
Held
Integral(integrand, *limits).Each limit is either a bare
Symbol(indefinite integral, single arg) or a(symbol, lower, upper)triple (definite integral).sp.Integralis held by default (it never auto-evaluates on construction), so this is a thin documenting wrapper. Only.doit()orsp.integrate(...)would evaluate it — both are forbidden inside the symbolic package.
- zoomy_core.symbolic.sp_safe.Sub(expr, var, value)#
Held
Subs(expr, var, value).sp.Subsis held by default, so this is a thin alias that documents intent: any “evaluateexpratvar = value” should go throughSuband produce a held atom rendered asexpr|_{var=value}by the latex printer.The primitive
UnSubsis the only thing that may unwrap this.
- zoomy_core.symbolic.sp_safe.held_function(name, *args, **kwargs)#
Construct a held
UndefinedFunctioncallf(*args).A passthrough wrapper for completeness — sympy’s default behaviour on UndefinedFunction calls is already non-evaluating, so this is just
sp.Function(name)(*args).