fix(tensorlogic): add __rmul__/__radd__ for scalar-on-left ops (AX-038)#76
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
…LOGIC-OPS) Scalar * TensorRef previously raised TypeError because Python's int.__mul__ returned NotImplemented. Adding reflected ops on TensorRef / Scalar / Product / Sum makes 2*t == t*2 and 1+t == t+1. Tests verify commutativity for Product and Sum and that reflected ops on nested expressions produce the right Product/Sum shape.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88e01804e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| def __rmul__(self, other) -> "Product": | ||
| # TENSOR-LOGIC-OPS: when the left operand is a Python number, | ||
| # Python calls `int.__mul__(other, self)`, which returns | ||
| # NotImplemented for our Expr. Dispatch back through as_expr | ||
| # so `2 * s` and `s * 2` produce the same Product. | ||
| return Product(as_expr(other), as_expr(self)) |
There was a problem hiding this comment.
Add normal Scalar operators for parsed scalar-left rules
For .tl rules where a numeric literal is on the left, the parser creates a Scalar first (_parse_factor) and _parse_product then evaluates expr * next_factor, so TensorRef.__rmul__ is never invoked. As a result, rules like scaled(x,y) := 2 * edge(x,y) still raise TypeError for Scalar * TensorRef while edge(x,y) * 2 works. Please add Scalar.__mul__ (and the matching __add__ for 2 + edge(x,y)) or route these parser operations through as_expr explicitly.
Useful? React with 👍 / 👎.
Adds
__rmul__and__radd__on Tensor so expressions like2 * Tand2 + Troute through the right side and produce the same value asT * 2/T + 2. Without these, Python triesint.__mul__(Tensor)first and raises TypeError on a non-numeric operand type.Ref: AGY audit 2026-06-21 TENSOR-LOGIC-OPS / AX-038.