use crate::position::PositionInLanguageTerm;
use crate::rule::RewriteRule;
use crate::term::syntax::{LanguageTerm, RewritableLanguageOperatorSymbol, TermFactory};
#[allow(clippy::type_complexity)]
pub struct RootRule<LOS: RewritableLanguageOperatorSymbol> {
desc: String,
guard: Box<dyn Fn(&LOS) -> bool>,
rewrite:
Box<dyn Fn(&LOS, &[LanguageTerm<LOS>], &mut TermFactory<LOS>) -> Option<LanguageTerm<LOS>>>,
}
impl<LOS: RewritableLanguageOperatorSymbol> RootRule<LOS> {
pub fn new<G, R>(desc: impl Into<String>, guard: G, rewrite: R) -> Self
where
G: Fn(&LOS) -> bool + 'static,
R: Fn(&LOS, &[LanguageTerm<LOS>], &mut TermFactory<LOS>) -> Option<LanguageTerm<LOS>>
+ 'static,
{
Self {
desc: desc.into(),
guard: Box::new(guard),
rewrite: Box::new(rewrite),
}
}
pub fn unary<G, R>(desc: impl Into<String>, guard: G, rewrite: R) -> Self
where
G: Fn(&LOS) -> bool + 'static,
R: Fn(&LOS, &LanguageTerm<LOS>, &mut TermFactory<LOS>) -> Option<LanguageTerm<LOS>>
+ 'static,
{
Self::new(desc, guard, move |op, children, f| {
rewrite(op, &children[0], f)
})
}
pub fn binary<G, R>(desc: impl Into<String>, guard: G, rewrite: R) -> Self
where
G: Fn(&LOS) -> bool + 'static,
R: Fn(
&LOS,
&LanguageTerm<LOS>,
&LanguageTerm<LOS>,
&mut TermFactory<LOS>,
) -> Option<LanguageTerm<LOS>>
+ 'static,
{
Self::new(desc, guard, move |op, children, f| {
rewrite(op, &children[0], &children[1], f)
})
}
}
impl<LOS: RewritableLanguageOperatorSymbol> RewriteRule<LOS> for RootRule<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>> {
if (self.guard)(&term.operator) {
(self.rewrite)(&term.operator, &term.sub_terms, factory)
} else {
None
}
}
}