optimize

fun <T> Draft<T>.optimize(): Draft<T>

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:

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