The ports — where backends meet the substrate
eqsat never imports a backend, and a backend never sees the search. They meet through mlopt_core.ports: a set of Protocol shapes each side implements or consumes. This is the seam the repo split cut along — graphopt's mlopt_torch/mlopt_onnx adapters are implementations of these ports, not parts of the engine.
The contract surfaces
Source— lifts a domain object (atorch.nn.Module, an ONNX graph) intomlopt_coreterms. The substrate sees only terms.Sink— the way back down:loweremits a runnable artifact,verifychecks it against the source,executorslists what can run it — all on top ofCapabilities'ssupported_ops/ops, the hard feasibility declaration.Engine— theengine=contract onsearch: an alternate saturation engine (the PyO3mlopt_native.NativeEngine). Engines are never auto-detected — anEngine-port value is passed explicitly andstats["engine"]records which ran ("python"reference default,"native"opt-in). The port covers search only — certificates and the non-local passes are Python-engine capabilities.Runner/Executor/ExecutorSpec/Composer— delivery: how a lowered artifact is executed, timed, and chained.Policy— orders the saturation schedule (which rules to try first). Every rule still fires, so the fixed point and the certificate are unchanged — a policy can never decide equivalence.Criterion/CostFn/Strategy/TaskMetric— what "cheapest" means, and theMonolithic/Compositional/Autotunedstrategy shapes.- The rest of the port vocabulary —
Meter,Verifier,VerifyResult,PerformanceModel,Profiler,OpRegistry,RuleSetLike,RuleLike,RuleSetProvider,Binding,TimingResult,signature_conforms.
The boundary honesty
The port binds shapes, never contents: DOMAINS, ALL_RULES, MACHINE_SHIPPED rows, and the lawdata tables are data — the registries' names are frozen, the rows are each domain repo's business. Compat re-exports (egraph._term_match, cost._memo_dispatch, …) stay internal even where reachable — "reachable" is not "public".
The frozen names are the substrate slice of the manifest; the domain-side implementations are documented under graphopt.