use crate::graph::NodeId;
#[derive(Debug, thiserror::Error)]
pub enum CausasvError {
#[error("cycle detected in graph")]
CycleDetected,
#[error("invalid node id: {0:?}")]
InvalidNodeId(NodeId),
#[error("self-loop on node {0:?}")]
SelfLoop(NodeId),
#[error("duplicate edge {0:?} -> {1:?}")]
DuplicateEdge(NodeId, NodeId),
#[error("graph is empty")]
EmptyGraph,
#[error("graph is not a rooted directed tree")]
NotRootedTree,
#[error("value function error: {0}")]
ValueFunctionError(String),
#[error("invalid configuration: {0}")]
InvalidConfig(String),
#[error("linear extension count overflowed u64: {0}")]
Overflow(String),
#[error(
"exact_tree: tree shape exceeds the feasibility budget (largest single side-sibling \
product {max_cartesian_terms} vs budget {cartesian_term_budget}; estimated total work \
{estimated_total_terms} vs budget {total_term_budget}); use exact_dag_sparse or approx"
)]
ExactTreeBudgetExceeded {
max_cartesian_terms: u64,
cartesian_term_budget: u64,
estimated_total_terms: u64,
total_term_budget: u64,
},
#[error(
"conflicting edge between {0:?} and {1:?}: an edge with a different orientation already exists"
)]
ConflictingEdge(NodeId, NodeId),
#[error(
"PDAG has no consistent DAG extension (undirected edges can't be oriented without creating a cycle or a new v-structure)"
)]
NotExtendable,
#[error(
"d-convex hull computation did not reach a fixed point within the expected iteration bound; this indicates an implementation bug"
)]
HullFixedPointNotReached,
}
pub(crate) fn validate_batch_result_len(
expected: usize,
actual: usize,
) -> Result<(), CausasvError> {
if expected != actual {
return Err(CausasvError::ValueFunctionError(format!(
"value_fn_batch returned {actual} values for {expected} coalitions"
)));
}
Ok(())
}