optimize
Applies all rewrite rules in sequence, then consolidates independent embroideries.
The E-2 fixpoint — deferEmbroidery, pushdownFilters, fuseAdjacent — runs first until no rule changes the pipeline. consolidateEmbroideries is then applied once as a final step: it operates on the fully-deferred, filtered, and fused graph, fusing independent DraftStage.Embroider nodes at the same dependency level into a single DraftStage.BatchedEmbroider.
Applying consolidation after the fixpoint (not inside it) is deliberate:
deferEmbroidery and pushdownFilters do not move DraftStage.BatchedEmbroider nodes, so no new fixpoint iterations arise after consolidation.
fuseAdjacent never fuses coordinated stages, so the structure is stable.
Consolidation is idempotent, so calling optimize twice is safe.
Branch-aware: each constituent rule applies per branch (see deferEmbroidery, pushdownFilters, fuseAdjacent). A combined draft from Draft.combine converges to the per-branch optimal form without ever collapsing independent branches.
The returned Draft is structurally equivalent to the receiver under isEquivalentTo.
Samples
// A draft with embroider in the middle and filters after maps.
val unoptimized: Draft<ByteArray> = Warp.shuttle(OpId("source.docs"))
.map(OpId("map.enrich"))
.embroider(OpId("embroider.rank"))
.filter(OpId("filter.threshold"))
.map(OpId("map.format"))
val optimized = unoptimized.optimize()
// Embroider deferred last; filters pushed before maps; adjacent same-kind fused.
check(optimized.stages.last() is DraftStage.Embroider) { "embroider should be last" }
// Structural equivalence: same source, embroider, and free-op multiset.
check(unoptimized.isEquivalentTo(optimized)) { "optimize must preserve equivalence" }