Skip to main content

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}