Skip to main content

Module canonical

Module canonical 

Source
Expand description

Canonicalisation of composition graphs.

Rewrites a CompositionNode into its canonical form so that semantically equivalent graphs produce the same byte representation (and therefore the same composition ID). The rules implemented here are justified in docs/architecture/semantics.md; the property tests in crates/noether-engine/tests/laws.rs check every law.

Rules (M1):

  1. Flatten nested Sequential into a single list, left-to-right.
  2. Collapse singleton Sequential[s] to s.
  3. Retry { s, 1, _ }s.
  4. Retry { Retry { s, n, d }, m, d }Retry { s, n·m, d } when both delays match.
  5. Let { {}, body }body.
  6. BTreeMap in Parallel.branches and Let.bindings already guarantees alphabetical ordering in the serialised form; no active rewrite needed.

What is not done in M1 (see semantics.md):

  • Stage-level identity detection (needs stage metadata, M2).
  • Const absorption (f >> ConstConst) — deferred to M2 so this module remains purely structural.
  • Dead-branch elimination when Branch.predicate is Const (optimizer territory, M3).

Canonicalisation is idempotent: canonicalise(canonicalise(g)) == canonicalise(g). That’s tested as a law.

Functions§

canonicalise
Rewrite a node into its canonical form. Recurses through the tree bottom-up so each parent sees already-canonical children.