use crate::position::{PositionInLanguageTerm, PositionInRewriteProcess};
use crate::process::strategy::{run_traced_step, RewriteProcess};
use crate::term::syntax::{LanguageTerm, RewritableLanguageOperatorSymbol, TermFactory};
pub struct AtomicRuleApplication {
pub left_id: usize,
pub rule_chain: Vec<(PositionInRewriteProcess, PositionInLanguageTerm)>,
pub right_id: usize,
}
pub struct RewriteProcessTracedExecutor<LOS: RewritableLanguageOperatorSymbol> {
strategy: RewriteProcess<LOS>,
factory: TermFactory<LOS>,
current_terms: Vec<LanguageTerm<LOS>>,
completed_terms: Vec<LanguageTerm<LOS>>,
}
impl<LOS: RewritableLanguageOperatorSymbol> RewriteProcessTracedExecutor<LOS> {
pub fn new(
strategy: RewriteProcess<LOS>,
initial: LanguageTerm<LOS>,
factory: TermFactory<LOS>,
) -> Self {
Self {
strategy,
factory,
current_terms: vec![initial],
completed_terms: vec![],
}
}
pub fn into_factory(self) -> TermFactory<LOS> {
self.factory
}
pub fn get_current_terms(&self) -> &[LanguageTerm<LOS>] {
&self.current_terms
}
pub fn get_completed_terms(&self) -> &[LanguageTerm<LOS>] {
&self.completed_terms
}
pub fn progress(&mut self) -> Vec<AtomicRuleApplication> {
let root_sp = PositionInRewriteProcess::get_root_position();
let root_tp = PositionInLanguageTerm::get_root_position();
let mut next_terms: Vec<LanguageTerm<LOS>> = Vec::new();
let mut applications: Vec<AtomicRuleApplication> = Vec::new();
for (left_id, term) in self.current_terms.iter().enumerate() {
let results = run_traced_step(
&self.strategy,
term,
term,
&root_tp,
&root_sp,
&mut self.factory,
);
if results.is_empty() {
self.completed_terms.push(term.clone());
} else {
for (rule_chain, result) in results {
let right_id = next_terms.len();
next_terms.push(result);
applications.push(AtomicRuleApplication {
left_id,
rule_chain,
right_id,
});
}
}
}
self.current_terms = next_terms;
applications
}
}