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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Error type for discrete graph algorithms.
use sim_lib_discrete_algebra::AlgebraError;
/// Errors raised by graph construction, algorithms, and verifiers.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum GraphError {
/// The graph is disconnected, so the requested result does not exist.
#[error("graph is disconnected")]
Disconnected,
/// A negative-weight cycle makes shortest paths undefined.
#[error("graph has a negative-weight cycle")]
NegativeCycle,
/// A negative edge weight was supplied to an algorithm that forbids it.
#[error("negative edge weight is not allowed here")]
NegativeWeight,
/// The algorithm was called on the wrong kind of graph.
#[error("wrong graph kind: {0}")]
WrongGraphKind(String),
/// An edge referenced a node index outside the node range.
#[error("invalid endpoint on edge {edge}: node {node} >= node count {len}")]
InvalidEndpoint {
/// The offending edge id.
edge: usize,
/// The out-of-range node index.
node: usize,
/// The number of nodes.
len: usize,
},
/// An edge id is not the storage index required by id-indexed consumers.
#[error(
"invalid edge id at storage index {index}: id {id} is not < edge count {len} and equal to its storage index"
)]
InvalidEdgeId {
/// The storage index where the edge was found.
index: usize,
/// The offending edge id.
id: usize,
/// The number of stored edge records.
len: usize,
},
/// A graph weight sum or path relaxation overflowed its representation.
#[error("graph weight overflow: {0}")]
WeightOverflow(String),
/// A floating-point or user-defined cost was not finite or comparable.
#[error("non-finite graph cost: {0}")]
NonFiniteCost(String),
/// An algorithm control was internally inconsistent.
#[error("invalid graph algorithm control: {0}")]
InvalidControl(String),
/// A work, memory, time, or cancellation bound stopped the algorithm.
#[error("graph algorithm stopped by control: {0}")]
ControlStopped(String),
/// A node index passed to an algorithm was outside the node range.
#[error("node {node} out of range: node count {count}")]
NodeOutOfRange {
/// The out-of-range node index.
node: usize,
/// The number of nodes.
count: usize,
},
/// A submitted certificate failed verification.
#[error("certificate invalid: {0}")]
CertificateInvalid(String),
/// An assignment matrix, policy, or submitted assignment was malformed.
#[error("invalid assignment: {0}")]
InvalidAssignment(String),
/// A staged feature is not yet implemented.
#[error("unsupported: {0}")]
Unsupported(String),
}
impl From<AlgebraError> for GraphError {
fn from(err: AlgebraError) -> Self {
match err {
// For a min-plus adjacency matrix, a divergent closure star means a
// negative-weight cycle.
AlgebraError::NoStar => GraphError::NegativeCycle,
other => GraphError::Unsupported(other.to_string()),
}
}
}