use crate::{ProofExpr, ProofTerm};
use std::fmt;
#[derive(Debug, Clone)]
pub enum ProofError {
NoProofFound,
DepthExceeded,
OccursCheck {
variable: String,
term: ProofTerm,
},
UnificationFailed {
left: ProofTerm,
right: ProofTerm,
},
ExprUnificationFailed {
left: ProofExpr,
right: ProofExpr,
},
SymbolMismatch {
left: String,
right: String,
},
ArityMismatch {
expected: usize,
found: usize,
},
PatternNotDistinct(String),
NotAPattern(ProofExpr),
ScopeViolation {
var: String,
allowed: Vec<String>,
},
}
impl fmt::Display for ProofError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ProofError::NoProofFound => {
write!(f, "No proof found: the goal could not be derived from the knowledge base")
}
ProofError::DepthExceeded => {
write!(f, "Proof search exceeded maximum depth limit")
}
ProofError::OccursCheck { variable, term } => {
write!(
f,
"Occurs check failed: variable '{}' appears in term '{}' (would create infinite type)",
variable, term
)
}
ProofError::UnificationFailed { left, right } => {
write!(f, "Unification failed: cannot unify '{}' with '{}'", left, right)
}
ProofError::ExprUnificationFailed { left, right } => {
write!(f, "Expression unification failed: cannot unify '{}' with '{}'", left, right)
}
ProofError::SymbolMismatch { left, right } => {
write!(f, "Symbol mismatch: '{}' vs '{}'", left, right)
}
ProofError::ArityMismatch { expected, found } => {
write!(f, "Arity mismatch: expected {} arguments, found {}", expected, found)
}
ProofError::PatternNotDistinct(var) => {
write!(f, "Pattern has duplicate variable '{}': Miller patterns require distinct bound variables", var)
}
ProofError::NotAPattern(expr) => {
write!(f, "Not a valid Miller pattern: '{}' (arguments must be bound variable references)", expr)
}
ProofError::ScopeViolation { var, allowed } => {
write!(f, "Scope violation: variable '{}' not in pattern scope {:?}", var, allowed)
}
}
}
}
impl std::error::Error for ProofError {}
pub type ProofResult<T> = Result<T, ProofError>;