use std::fmt::Debug;
pub trait Scope<'a, T: 'a = usize> {
fn size(&self) -> usize;
fn value(&'a self, index: usize) -> T;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn iter_values(&'a self) -> ScopeIter<'a, T>
where
Self: Sized,
{
ScopeIter { index: 0, scope: self }
}
}
pub struct ScopeIter<'a, T> {
index: usize,
scope: &'a dyn Scope<'a, T>,
}
impl<'a, T> Iterator for ScopeIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.scope.len() {
None
} else {
self.index += 1;
Some(self.scope.value(self.index - 1))
}
}
}
pub trait Check<T = usize> {
fn extends_sat(&self, solution: &[T], x: &T) -> bool;
}
pub trait CheckInc<T = usize> {
type Accumulator: Debug;
fn fold_acc(
&self,
accu: Option<Self::Accumulator>,
x: &T,
position: usize,
) -> Self::Accumulator;
fn accu_sat(&self, accu: &Self::Accumulator, x: &T, position: usize) -> bool;
}
impl<C: Check<T>, T> CheckInc<T> for C
where
T: Debug + Clone,
{
type Accumulator = Vec<T>;
fn fold_acc(
&self,
accu: Option<Self::Accumulator>,
x: &T,
_position: usize,
) -> Self::Accumulator {
let mut accu = accu.unwrap_or_default();
accu.push(x.clone());
accu
}
fn accu_sat(&self, accu: &Self::Accumulator, x: &T, _position: usize) -> bool {
self.extends_sat(&accu[..accu.len() - 1], x)
}
}