canonicalize
Stable function · Document I/O
Tier: stable · Kind: function · Topic: Document I/O
| Julia | TypeScript | Python | Rust | Go |
|---|---|---|---|---|
canonicalize | canonicalize | not exported | canonicalize | Canonicalize |
Julia
canonicalize(e::IntExpr)
canonicalize(e::NumExpr)
canonicalize(e::VarExpr)
canonicalize(e::OpExpr)
canonicalize(expr::ASTExpr) -> ASTExpr
Canonicalize an expression tree per discretization RFC §5.4. Returns a new
tree; the input is not mutated. Throws CanonicalizeError
for
NaN/Inf or 0/0.
Field handling (cross-binding parity): like the TypeScript ({...node}),
Python (dataclasses.replace), and Rust (node.clone()) canonicalizers,
every OpExpr field is PRESERVED on the rebuilt node (via reconstruct),
and canonicalization recurses into args only — sub-expressions carried by
aggregate fields (expr_body, filter, lower/upper, values,
table_axes, …) pass through verbatim, exactly as in the other bindings.
RFC §5.4 pins rewrite rules only for the scalar arithmetic subset
(+ * - / neg); all other ops are structure-preserving pass-throughs.
Emission of such aggregate-carrying nodes is the restricted step — see
canonical_json
.
Example (canonicalize)
# The canonical form orders commutative arguments and drops identities, so two
# spellings of the same expression compare equal.
a = canonicalize(parse_expression("b + a + 0"))
b = canonicalize(parse_expression("a + b"))
@assert to_ascii(a) == to_ascii(b) == "a + b"
@assert canonical_json(a) == canonical_json(b) == """{"args":["a","b"],"op":"+"}"""
TypeScript
function canonicalize(expr: Expr): Expr
Canonicalize an expression tree per RFC §5.4. Input is not mutated.
Example (canonicalize)
const a = parseExpression('b + a*2 + 0')
const b = parseExpression('0 + 2*a + b')
// Operands are ordered and identities dropped.
assert.equal(toAscii(canonicalize(a)), 'b + 2 * a')
assert.deepEqual(canonicalize(a), canonicalize(b))
// The canonical JSON text is a stable key for hashing or comparison.
assert.equal(canonicalJson(a), canonicalJson(b))
Python
Python does not export this function.
Rust
pub fn canonicalize(expr: &Expr) -> Result<Expr, CanonicalizeError>
Canonicalize an Expr
tree per RFC §5.4. Returns a new tree; input is not mutated.
Go
func Canonicalize(expr Expression) (Expression, error)
Canonicalize applies RFC §5.4 canonical form to an expression tree.
Returns ErrCanonicalNonFinite if the tree contains NaN or ±Inf, and ErrCanonicalDivByZero for 0/0. Input is not mutated; callers receive a new tree built from the same leaf values.