Use case
After differentiating a tangent, a user or codegen wants to ask for simplification: apply the opt-in rewrite passes (mixed inverse-trig, projector algebra, like-term cleanup, dead-contraction removal) once, on the finished expression, before emitting it.
What happens today (probed on main)
simplify(expr) -> no such API (any domain)
expand(expr) -> no such API
Simplification is construction-time only. The opt-in passes that exist are individual visitor classes a user must know by name and include by path: scalar_function_simplifier (#417, mixed inverse-trig), tensor_projector_simplifier (unwired, #453), and the construction-time folds cannot be re-run on an expression built earlier (e.g. after a substitution that makes new folds possible). Nothing is reachable as one call, and nothing spans domains.
Proposal
expression_holder<Any> simplify(expression_holder<Any> const&); // all opt-in passes, to a fixpoint with a step bound
expression_holder<Any> simplify(expression_holder<Any> const&, pass_set); // pick passes
Implementation: a rebuild-visitor driver per domain that (1) rebuilds through the factories, so every construction-time rule re-fires on the new tree, and (2) runs the registered opt-in passes (the rule-contract catalogs from #417/#420 are the natural registry). Termination: contraction-only passes plus a no-progress guard, as the existing add/mul passes do. Preserve sharing (#472) so a simplified tangent is not exponentially larger than its input.
Tests: simplify(substitute(e, x, 0)) re-fires folds that construction could not; idempotence simplify(simplify(e)) == simplify(e); the mixed inverse-trig pass reachable through it.
Scope
Medium. Depends on the rule-contract registry direction (#419, #95) and on #472 for sharing.
Signed-off-by: petlenz [email protected]
Use case
After differentiating a tangent, a user or codegen wants to ask for simplification: apply the opt-in rewrite passes (mixed inverse-trig, projector algebra, like-term cleanup, dead-contraction removal) once, on the finished expression, before emitting it.
What happens today (probed on main)
Simplification is construction-time only. The opt-in passes that exist are individual visitor classes a user must know by name and include by path:
scalar_function_simplifier(#417, mixed inverse-trig),tensor_projector_simplifier(unwired, #453), and the construction-time folds cannot be re-run on an expression built earlier (e.g. after a substitution that makes new folds possible). Nothing is reachable as one call, and nothing spans domains.Proposal
Implementation: a rebuild-visitor driver per domain that (1) rebuilds through the factories, so every construction-time rule re-fires on the new tree, and (2) runs the registered opt-in passes (the rule-contract catalogs from #417/#420 are the natural registry). Termination: contraction-only passes plus a no-progress guard, as the existing add/mul passes do. Preserve sharing (#472) so a simplified tangent is not exponentially larger than its input.
Tests:
simplify(substitute(e, x, 0))re-fires folds that construction could not; idempotencesimplify(simplify(e)) == simplify(e); the mixed inverse-trig pass reachable through it.Scope
Medium. Depends on the rule-contract registry direction (#419, #95) and on #472 for sharing.
Signed-off-by: petlenz [email protected]