1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//! Framework: traits, state shapes, the iteration driver, and the
//! termination layer. The slot taxonomy is:
//!
//! - [`problem`] — what the *user* implements about their objective:
//! [`CostFunction`](problem::CostFunction),
//! [`Gradient`](problem::Gradient).
//! Future: residual/Jacobian, Hessian, operators (matrix-free).
//! - [`constraint`] — constraint markers carried on the problem (tenet 4
//! in `AGENTS.md`). Currently
//! [`BoxConstrained`](constraint::BoxConstrained).
//! - [`state`] — what a solver carries between iterations:
//! [`State`](state::State) for the minimum,
//! [`GradientState`](state::GradientState) /
//! [`SimplexState`](state::SimplexState) when a solver carries
//! richer info that termination criteria can read.
//! - [`solver`] — the [`Solver`](solver::Solver) trait every concrete
//! solver implements. Lifecycle is `init` once, then repeated
//! `next_iter`, with an optional `terminate` hook.
//! - [`termination`] — the framework-level
//! [`TerminationCriterion`](termination::TerminationCriterion)
//! trait plus shipped criteria. Each criterion bounds on the minimum
//! state shape it needs (tenet 3), so mismatches are compile errors
//! rather than runtime no-ops.
//! - [`executor`] — the driver: [`Executor`](executor::Executor) /
//! [`Stepper`](executor::Stepper) / [`run_loop`](executor::run_loop).
//! The canonical iteration ordering is documented on the
//! [`executor`] module.
//! - [`inner`] — the composition adapter:
//! [`InnerExecutor`](inner::InnerExecutor) wraps `run_loop` for outer
//! solvers that drive an inner solver per outer iteration. See
//! `AGENTS.md` "Solver composition" for the contracts.
//! - [`math`] — the small shared math layer
//! ([`ScaledAdd`](math::ScaledAdd), [`NormSquared`](math::NormSquared),
//! …) that backend-generic solvers depend on. Per tenet 5, this stays
//! honest: only ops every backend can implement well live here. LA-heavy
//! ops will live in a separate tier when the first solver wants them.