use crate::position::PositionInLanguageTerm;
use crate::rule::RewriteRule;
use crate::rules::util::assoc::{
fold_associative_sub_terms_recursively, get_associative_sub_terms_recursively,
};
use crate::term::syntax::{LanguageTerm, RewritableLanguageOperatorSymbol, TermFactory};
pub trait ModuloAssociativeGenericFlattenedChecker<LOS: RewritableLanguageOperatorSymbol> {
fn is_an_associative_binary_operator_we_may_consider(&self, op: &LOS) -> bool;
fn transform_flattened_sub_terms(
&self,
considered_ac_op: &LOS,
flattened_subterms: Vec<&LanguageTerm<LOS>>,
factory: &mut TermFactory<LOS>,
) -> Option<Vec<LanguageTerm<LOS>>>;
}
fn transformation_modulo_associative_generic_flattened_transfo<
LOS: RewritableLanguageOperatorSymbol,
>(
checker: &dyn ModuloAssociativeGenericFlattenedChecker<LOS>,
term: &LanguageTerm<LOS>,
factory: &mut TermFactory<LOS>,
) -> Option<LanguageTerm<LOS>> {
if checker.is_an_associative_binary_operator_we_may_consider(&term.operator) {
let op = &term.operator;
let flat = get_associative_sub_terms_recursively(term, op);
if let Some(mut transformed) = checker.transform_flattened_sub_terms(op, flat, factory) {
return fold_associative_sub_terms_recursively(op, &mut transformed, &None, factory);
}
}
None
}
pub struct FlattenedACTransfoRule<LOS: RewritableLanguageOperatorSymbol> {
desc: String,
checker: Box<dyn ModuloAssociativeGenericFlattenedChecker<LOS>>,
}
impl<LOS: RewritableLanguageOperatorSymbol> FlattenedACTransfoRule<LOS> {
pub fn new(
desc: impl Into<String>,
checker: impl ModuloAssociativeGenericFlattenedChecker<LOS> + 'static,
) -> Self {
Self {
desc: desc.into(),
checker: Box::new(checker),
}
}
}
impl<LOS: RewritableLanguageOperatorSymbol> RewriteRule<LOS> for FlattenedACTransfoRule<LOS> {
fn get_desc(&self) -> String {
self.desc.clone()
}
fn try_apply(
&self,
term: &LanguageTerm<LOS>,
_ctx: &LanguageTerm<LOS>,
_pos: &PositionInLanguageTerm,
factory: &mut TermFactory<LOS>,
) -> Option<LanguageTerm<LOS>> {
transformation_modulo_associative_generic_flattened_transfo(
self.checker.as_ref(),
term,
factory,
)
}
}