use crate::term::syntax::{
LanguageTerm, LanguageTermNode, RewritableLanguageOperatorSymbol, TermFactory,
};
pub fn get_associative_sub_terms_recursively<'a, LOS: RewritableLanguageOperatorSymbol>(
term: &'a LanguageTerm<LOS>,
considered_associative_operator: &LOS,
) -> Vec<&'a LanguageTerm<LOS>> {
let mut sub_terms: Vec<&'a LanguageTerm<LOS>> = Vec::new();
if &term.operator == considered_associative_operator {
for sub_term in &term.sub_terms {
sub_terms.extend(get_associative_sub_terms_recursively(
sub_term,
considered_associative_operator,
));
}
} else {
sub_terms.push(term);
}
sub_terms
}
pub fn fold_associative_sub_terms_recursively<LOS: RewritableLanguageOperatorSymbol>(
considered_associative_operator: &LOS,
sub_terms: &mut Vec<LanguageTerm<LOS>>,
default_empty_term: &Option<LOS>,
factory: &mut TermFactory<LOS>,
) -> Option<LanguageTerm<LOS>> {
let n = sub_terms.len();
match n {
2 => {
let t2 = sub_terms.pop().unwrap();
let t1 = sub_terms.pop().unwrap();
Some(LanguageTermNode::build(
considered_associative_operator.clone(),
vec![t1, t2],
factory,
))
}
1 => Some(sub_terms.pop().unwrap()),
0 => default_empty_term
.as_ref()
.map(|empty_op| LanguageTermNode::build(empty_op.clone(), vec![], factory)),
_ => {
let t1 = sub_terms.remove(0);
let t2 = fold_associative_sub_terms_recursively(
considered_associative_operator,
sub_terms,
default_empty_term,
factory,
)?;
Some(LanguageTermNode::build(
considered_associative_operator.clone(),
vec![t1, t2],
factory,
))
}
}
}