Skip to main content

antecedent_graph/
error.rs

1//! Graph construction and validation errors.
2//!
3//! SPDX-License-Identifier: MIT OR Apache-2.0
4
5use antecedent_core::{Lag, VariableId};
6use thiserror::Error;
7
8/// Graph-layer errors.
9#[derive(Clone, Debug, Eq, PartialEq, Error)]
10#[non_exhaustive]
11pub enum GraphError {
12    /// Unknown dense node.
13    #[error("unknown dense node {id}")]
14    UnknownNode {
15        /// Dense id.
16        id: u32,
17    },
18    /// Unknown variable name at an API boundary.
19    #[error("unknown variable name '{name}'")]
20    UnknownVariableName {
21        /// Requested name.
22        name: String,
23    },
24    /// Edge would introduce a directed cycle.
25    #[error("edge {from}->{to} would create a cycle")]
26    Cycle {
27        /// Source dense id.
28        from: u32,
29        /// Target dense id.
30        to: u32,
31    },
32    /// Invalid endpoint combination for this graph class.
33    #[error("invalid endpoints: {message}")]
34    InvalidEndpoints {
35        /// Explanation.
36        message: &'static str,
37    },
38    /// Contemporaneous self-edge is invalid.
39    #[error("contemporaneous self-edge on {variable}")]
40    ContemporaneousSelfEdge {
41        /// Variable.
42        variable: VariableId,
43    },
44    /// Duplicate edge.
45    #[error("duplicate edge {from}->{to}")]
46    DuplicateEdge {
47        /// From.
48        from: u32,
49        /// To.
50        to: u32,
51    },
52    /// Lagged self-edge with lag 0.
53    #[error("invalid lag {lag}")]
54    InvalidLag {
55        /// Lag value.
56        lag: Lag,
57    },
58    /// Edge points from the future into the past (source lag nearer the present
59    /// than target lag).
60    #[error("edge {from}->{to} points from the future ({from_lag}) into the past ({to_lag})")]
61    FutureToPast {
62        /// Source dense id.
63        from: u32,
64        /// Target dense id.
65        to: u32,
66        /// Source lag.
67        from_lag: Lag,
68        /// Target lag.
69        to_lag: Lag,
70    },
71    /// Node capacity exceeded.
72    #[error("too many nodes")]
73    TooManyNodes,
74    /// Invalid selection-diagram metadata.
75    #[error("invalid selection diagram: {message}")]
76    InvalidSelectionDiagram {
77        /// Explanation.
78        message: String,
79    },
80    /// Bounded path search hit `max_paths` or `max_len` before exploring all candidates.
81    ///
82    /// Returned when m-separation would otherwise conclude "separated" after an incomplete
83    /// search (an unexplored active path may still exist). Finding an active path remains
84    /// conclusive even under truncation.
85    #[error("path search budget exhausted (max_paths={max_paths}, max_len={max_len})")]
86    SearchBudgetExhausted {
87        /// Path-count budget.
88        max_paths: usize,
89        /// Path-length budget.
90        max_len: usize,
91    },
92}