Version: dev

canonicalize

Stable function · Document I/O

Tier: stable · Kind: function · Topic: Document I/O

JuliaTypeScriptPythonRustGo
canonicalizecanonicalizenot exportedcanonicalizeCanonicalize

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 .

Source

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":"+"}"""

From docs/api/examples/julia/expressions.jl

TypeScript

function canonicalize(expr: Expr): Expr

Canonicalize an expression tree per RFC §5.4. Input is not mutated.

Source

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))

From docs/api/examples/typescript/canonicalize.ts

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.

Source · Rust docs

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.

Source · Go docs