use crate::domain::Domain;
#[derive(Debug, Clone)]
pub struct Variable<D: Domain> {
pub domain: D,
original_domain: D,
pruned: Vec<(usize, D::Value)>,
}
impl<D: Domain> Variable<D> {
pub fn new(domain: D) -> Self {
Self {
original_domain: domain.clone(),
domain,
pruned: Vec::new(),
}
}
pub fn prune(&mut self, val: &D::Value, depth: usize) -> bool {
if self.domain.remove(val) {
self.pruned.push((depth, val.clone()));
true
} else {
false
}
}
pub fn restore(&mut self, depth: usize) {
while let Some(&(d, _)) = self.pruned.last() {
if d == depth {
let (_, val) = self.pruned.pop().unwrap();
self.domain.add(&val);
} else {
break;
}
}
}
pub fn reset(&mut self) {
self.domain = self.original_domain.clone();
self.pruned.clear();
}
pub fn set_domain(&mut self, domain: D) {
self.domain = domain;
}
pub fn restrict_to(&mut self, val: &D::Value, depth: usize) {
let vals: Vec<_> = self.domain.iter().collect();
for v in &vals {
if v != val {
self.domain.remove(v);
self.pruned.push((depth, v.clone()));
}
}
}
}