pub enum TermKind<Var> {
Var(Var),
NonVar,
}
pub trait ClassifyTerm<Var> {
fn classify_term(&self) -> TermKind<&Var>;
fn superficially_unifiable(&self, other: &Self) -> bool;
fn is_var(&self) -> bool {
matches!(self.classify_term(), TermKind::Var(_))
}
fn is_non_var(&self) -> bool {
matches!(self.classify_term(), TermKind::NonVar)
}
}
pub trait DirectChildren<Var>: ClassifyTerm<Var> {
fn direct_children<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self> + 'a>;
fn map_direct_children<'a>(&'a self, f: impl FnMut(&'a Self) -> Self + 'a) -> Self;
fn variables<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Var> + 'a> {
if let TermKind::Var(v) = self.classify_term() {
return Box::new(std::iter::once(v));
}
Box::new(self.direct_children().flat_map(|child| child.variables()))
}
}