use std::rc::Rc; use super::process::Process; use super::set::{BasicSet, Set}; use super::translator::{Translator, PrintableWithTranslator, Formatter}; #[derive(Clone, Debug)] pub struct Choices { context_moves: Vec<(Rc, Rc)>, } impl Choices { pub fn new() -> Self { Choices { context_moves: vec![], } } pub fn new_not_empty() -> Self { Choices { context_moves: vec![(Rc::new(Set::default()), Rc::new(Process::Nill))], } } pub fn append(&mut self, a: &mut Choices) { self.context_moves.append(&mut a.context_moves); } pub fn replace(&mut self, a: Rc) { self.context_moves = self .context_moves .iter_mut() .map(|(c1, _)| (Rc::clone(c1), Rc::clone(&a))) .collect::>(); } pub fn shuffle(&mut self, choices: Choices) { match ( self.context_moves.is_empty(), choices.context_moves.is_empty(), ) { (true, true) => {} (true, false) => self.context_moves = choices.context_moves, (false, true) => {} (false, false) => { let mut new_self = vec![]; for item_self in &self.context_moves { for item_choices in &choices.context_moves { new_self.push(( Rc::new(item_self.0.union(&item_choices.0)), Rc::new(item_self.1.concat(&item_choices.1)), )); } } self.context_moves = new_self; } } } pub fn iter(&self) -> std::slice::Iter<'_, (Rc, Rc)> { self.context_moves.iter() } } impl Default for Choices { fn default() -> Self { Self::new() } } impl IntoIterator for Choices { type Item = (Rc, Rc); type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.context_moves.into_iter() } } impl From<[(Rc, Rc); N]> for Choices { fn from(arr: [(Rc, Rc); N]) -> Self { Choices { context_moves: arr.to_vec(), } } } impl From<&[(Rc, Rc)]> for Choices { fn from(arr: &[(Rc, Rc)]) -> Self { Choices { context_moves: arr.to_vec(), } } } impl From, Rc)>> for Choices { fn from(arr: Vec<(Rc, Rc)>) -> Self { Choices { context_moves: arr } } } impl PrintableWithTranslator for Choices { fn print(&self, f: &mut std::fmt::Formatter, translator: &Translator) -> std::fmt::Result { write!(f, "[")?; let mut it = self.iter().peekable(); while let Some(el) = it.next() { if it.peek().is_none() { write!( f, "[set: {}, process: {}]", Formatter::from(translator, &*el.0), Formatter::from(translator, &*el.1) )?; } else { write!( f, "[set: {}, process: {}], ", Formatter::from(translator, &*el.0), Formatter::from(translator, &*el.1) )?; } } write!(f, "]") } }