The physical layout of the crate — modules, the public API surface, and the feature-gated boundary — and how they map onto the design.
adaptive-msm/
├── src/
│ ├── lib.rs # crate root: prelude, re-exports, feature gate
│ ├── learner.rs # AdaptiveMsm + config/builder/statistics (always compiled)
│ └── wfst/ # MSM-as-WFST embedding (feature "wfst", default)
│ ├── mod.rs # module facade + integration tests
│ ├── weight.rs # MsmWeight (data-dependent tropical semiring)
│ ├── state.rs # encode/decode, MsmCompositeState, MsmStateRegistry, MsmTransition
│ ├── state_source.rs # MsmStateSource (stateless lazy source) + builder
│ └── wrapper.rs # MsmWfst (cached engine) + builder
├── tests/msm_wfst.rs # extraction-provenance integration tests
├── examples/ # reproducible experiments (E1, E2)
├── benches/ # criterion timing microbenchmarks
├── scripts/ # experiment orchestration + plotting
└── docs/ # this documentation corpus
The crate has a feature-gated boundary. Everything the learner needs is in the always-compiled surface; the WFST embedding is additive and optional.
| Surface | Modules | Extra deps | Enabled by |
|---|---|---|---|
| learner-only | learner |
rand |
default-features = false |
| full (default) | learner + wfst |
+ lling-llang, rustc-hash, smallvec |
default (wfst) |
lib.rs gates the WFST module and its re-exports with #[cfg(feature = "wfst")],
so the learner compiles and tests green with no lling-llang edge at all
(verified in CI as cargo build --no-default-features). This is the mechanism
that keeps the dependency graph acyclic
(ADR 0001).
Re-exported at the crate root and in adaptive_msm::prelude:
| Item | From | Feature |
|---|---|---|
AdaptiveMsm, AdaptiveMsmConfig, AdaptiveMsmBuilder, AdaptiveMsmStatistics |
learner |
always |
MsmConfig (re-export of liblevenshtein::time_series::MsmConfig) |
upstream | always |
MsmWfst, MsmWfstBuilder |
wfst::wrapper |
wfst |
MsmWeight |
wfst::weight |
wfst |
MsmStateSource, MsmStateSourceBuilder |
wfst::state_source |
wfst |
MsmCompositeState, MsmStateRegistry, MsmTransition, encode_msm_state, decode_msm_state, estimate_msm_states |
wfst::state |
wfst |
learner— the online optimizer for$c$. Depends only onMsmConfigandrand. Design:../design/adaptive-learner.md.wfst::weight—MsmWeight, the data-dependent tropical weight and its homomorphism toTropicalWeight. Design:../design/msm-weight-semiring.md.wfst::state— the positional state encoding, the composite state, the dedup registry, and the transition enum.wfst::state_source— the stateless lazy engine (MsmStateSource); purecompute_stateover positional ids.wfst::wrapper— the cached engine (MsmWfst); mutable expansion withCachePolicy. Both engines:../design/msm-wfst-embedding.md.
lib.rs → {learner, wfst}; within wfst, wrapper and state_source both
depend on weight and state; nothing in wfst depends on learner and vice
versa (the subsystems are independent). Externally, learner → MsmConfig;
weight → lling_llang semiring; state_source/wrapper → lling_llang WFST
traits. See the dependency layering for the external view
and data-flow.md for the runtime flows.