You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update migration plan for new ixsimpl API (lambdify, has, eval, check)
ixsimpl now covers every sympy feature used in Wave: lambdify() and
Expr.eval() replace sympy.lambdify, Expr.has() is native, abs_() is
provided, and ctx.check() replaces the sympy.solve entailment check.
No hard API gaps remain; end state is full sympy removal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ivan Butygin <ivan.butygin@gmail.com>
|**Symbol creation**|`sympy.Symbol(name, integer=True, nonneg=True)`|`ctx.sym(name)` + `extract_assumptions`|**Soft.** ixsimpl symbols carry no assumptions intrinsically; assumptions are passed separately to `simplify()`. Wave would need to track assumptions in a side table or always extract from sympy symbols during conversion. |
82
-
|**Expression construction**|`Add`, `Mul`, `Pow`, `Integer`, `Rational`, `Mod(evaluate=False)`, `floor`, `ceiling`, `Min`, `Max`, `Abs`, `Piecewise`| Arithmetic ops, `ctx.int_()`, `ctx.rat()`, `floor`, `ceil`, `mod`, `max_`, `min_`, `pw`|**Soft.**Missing: `Abs`(emulate via `pw`),`evaluate=False` (ixsimpl does not eagerly evaluate, so not needed). `Pow` must be expanded to repeated multiplication (already done in `from_sympy`). |
85
+
|**Expression construction**|`Add`, `Mul`, `Pow`, `Integer`, `Rational`, `Mod(evaluate=False)`, `floor`, `ceiling`, `Min`, `Max`, `Abs`, `Piecewise`| Arithmetic ops, `ctx.int_()`, `ctx.rat()`, `floor`, `ceil`, `mod`, `max_`, `min_`, `abs_`, `pw`|**None.**`Abs` via `abs_()` (piecewise under the hood).`evaluate=False`not needed (ixsimpl does not eagerly evaluate). `Pow` expanded to repeated multiplication (already done in `from_sympy`). |
83
86
|**Piecewise / conditionals**|`sympy.Piecewise((val, cond), ...)`|`pw(*branches)`, `.pw_ncases`, `.pw_value(i)`, `.pw_cond(i)`|**None.** Full piecewise support. The `piecewise_aware_subs()` workaround in indexing.py exists only because sympy's `.subs()` triggers expensive boolean simplification on Piecewise -- ixsimpl's `.subs()` does not have this problem. |
84
-
|**Structural inspection**|`isinstance(expr, sympy.X)`, `.is_number`, `.is_Atom`, `.args`, `.func`|`.tag` (tag-based dispatch), `.nchildren`, `.children`, `.child(i)`, specialized accessors |**Soft.**`isinstance` dispatch maps to `expr.tag == ixsimpl.ADD` etc. Specialized accessors (`.add_nterms`, `.mul_nfactors`) give richer decomposition than sympy's flat `.args`. Missing: `.is_number` (check `tag == INT or tag == RAT`), `.has()` (walk tree or check `free_symbols`). |
87
+
|**Structural inspection**|`isinstance(expr, sympy.X)`, `.is_number`, `.is_Atom`, `.args`, `.func`|`.tag` (tag-based dispatch), `.nchildren`, `.children`, `.child(i)`, `.has()`, specialized accessors |**None.**`isinstance` dispatch maps to `expr.tag == ixsimpl.ADD` etc. `.has()` is native. `.is_number` maps to `tag in (INT, RAT)`. Specialized accessors (`.add_nterms`, `.mul_nfactors`) give richer decomposition than sympy's flat `.args`. |
85
88
|**Substitution**|`.subs()`, `.xreplace()`, `.replace(pred, fn)`|`.subs(target, repl)`, `.subs(mapping)`|**Soft.** Direct substitution is supported. Missing: `.replace(pred, fn)` (predicate-based bottom-up rewrite). Used in `_custom_simplify_once` for 4 transform passes. Would need a Python-level tree walker. |
86
-
|**Free symbol inspection**|`.free_symbols`, `.has(sym)`|`.free_symbols` (Python `Expr` class) |**None.**Already implemented as a cached property on the Python `Expr`subclass. `.has()` can be trivially derived. |
89
+
|**Free symbol inspection**|`.free_symbols`, `.has(sym)`|`.free_symbols` (cached property), `.has(sym)`|**None.**Both are native on the `Expr`class. |
87
90
|**Expression decomposition**|`.as_ordered_terms()`, `.as_numer_denom()`|`.add_nterms`/`.add_term(i)`/`.add_term_coeff(i)`, `.rat_num`/`.rat_den`|**Soft.** Add decomposition is richer in ixsimpl (coefficient + terms). Numer/denom split is only used for Rational nodes (`.rat_num`/`.rat_den`). |
88
-
|**Numeric probing**|`sympy.lambdify()` with custom modules |None |**Hard gap.**`lambdify`compiles sympy expressions to fast Python callables. Would need either an ixsimpl evaluator or a custom tree walker. `.to_c()`could potentially be used with ctypes but that is overkill. |
91
+
|**Numeric probing**|`sympy.lambdify()` with custom modules |`ixsimpl.lambdify()`, `Expr.eval(env)`|**None.**`lambdify`is a near drop-in replacement (uses `.subs()` + constant folding). `Expr.eval(env)`handles single-point evaluation. No custom `modules` parameter needed -- ixsimpl handles floor/Mod/etc natively. |
89
92
|**Affine conversion**| Sympy -> MLIR AffineExpr pipeline | None (but `.tag`-based walk is possible) |**Soft.** The converter does a structural walk over the expression tree. This maps directly to ixsimpl's `.tag` + `.child(i)` API. The walk structure would be nearly identical. |
90
-
|**Constraint solving**|`sympy.solve()`, `sympy.Eq()`|`ctx.eq()` for construction, no solver |**Hard gap.**`sympy.solve()`used in 2 places (`assumptions.py`, `general_utils.py`). No ixsimpl equivalent. These are niche uses. |
91
-
|**Codegen / printing**|`lambdastr()` for grid dim lambdas |`.to_c()`|**Soft.**`.to_c()`generates C code from expressions. `lambdastr()`generates Python code. Different targets, but the need is similar. Grid lambdas could use `.to_c()`+ compile, or a Python eval walker. |
93
+
|**Constraint solving**|`sympy.solve()`, `sympy.Eq()`|`ctx.eq()`, `ctx.check(expr, assumptions=)`|**None.**The sole `sympy.solve()`call is `evaluate_with_assumptions()` in `general_utils.py`, which checks whether an inequality is entailed/contradicted by a set of constraints -- returning `True`/`False`/`None`. This maps directly to `ctx.check(expr, assumptions=)`. |
94
+
|**Codegen / printing**|`lambdastr()` for grid dim lambdas |`ixsimpl.lambdify()`, `.to_c()`|**None.**`ixsimpl.lambdify()`replaces the `lambdastr()`+ `eval()` pattern directly. `.to_c()`available for C codegen if needed. |
0 commit comments