trellis_runner/engine/termination.rs
1//! Termination reasons for solver execution.
2//!
3//! This module defines the canonical set of reasons a solver may stop execution.
4//! These values are produced by the engine’s policy layer and propagated to the
5//! final `EngineOutput`.
6//!
7//! The enum is intentionally small and closed: it represents *semantic outcomes*
8//! rather than implementation-specific events.
9//!
10//! In general:
11//! - `Converged` is the only *successful* termination.
12//! - All other variants represent controlled early termination or failure modes.
13//!
14//! These values are stable identifiers suitable for logging, serialization,
15//! checkpoint metadata, and downstream analysis.
16//! Module for abstractions about the state of a solver, and reasons why a solver may have
17//! terminated.
18
19/// Canonical reasons why a solver terminated.
20///
21/// This type is produced by the engine policy layer and recorded in the final
22/// engine output.
23///
24/// It is deliberately coarse-grained: it describes *why execution stopped*,
25/// not how the engine reached that decision.
26#[derive(Copy, Clone, Debug, Eq, PartialEq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub enum Termination {
29 /// Execution was cancelled externally (e.g. user request or cancellation token).
30 ///
31 /// This is considered a non-analytic termination and does not imply failure
32 /// of the solver logic.
33 Cancelled,
34
35 /// The solver successfully met its convergence criteria.
36 ///
37 /// This is the only variant considered a successful termination.
38 Converged,
39
40 /// The solver exceeded the maximum allowed number of iterations.
41 ///
42 /// Typically enforced by `MaxIterationPolicy`.
43 ExceededMaxIterations,
44
45 /// The solver failed to make sufficient progress over a bounded window of iterations.
46 ///
47 /// Typically triggered by stagnation or no-progress policies.
48 Stagnated,
49
50 NoProgress,
51
52 /// The solver exceeded a wall-clock time limit.
53 ///
54 /// Typically enforced by `TimeoutPolicy`.
55 Timeout,
56}
57
58impl Termination {
59 /// Returns `true` if this termination represents a non-successful exit.
60 ///
61 /// This is used by the engine to classify outputs into:
62 /// - success (`Converged`)
63 /// - early termination or failure (all other variants)
64 ///
65 /// Note:
66 /// `Cancelled` is treated as a failure-like termination in this sense,
67 /// even though it may be externally induced.
68 pub(crate) fn failed(&self) -> bool {
69 *self != Self::Converged
70 }
71}