Add forgotten file

This commit is contained in:
Loïc Lecrenier 2023-03-19 15:14:40 +01:00
parent 825f742000
commit a59ca28e2c

View File

@ -0,0 +1,93 @@
use crate::search::new::{
interner::{FixedSizeInterner, Interned},
small_bitmap::SmallBitmap,
};
pub struct DeadEndsCache<T> {
conditions: Vec<Interned<T>>,
next: Vec<Self>,
pub forbidden: SmallBitmap<T>,
}
impl<T> Clone for DeadEndsCache<T> {
fn clone(&self) -> Self {
Self {
conditions: self.conditions.clone(),
next: self.next.clone(),
forbidden: self.forbidden.clone(),
}
}
}
impl<T> DeadEndsCache<T> {
pub fn new(for_interner: &FixedSizeInterner<T>) -> Self {
Self {
conditions: vec![],
next: vec![],
forbidden: SmallBitmap::for_interned_values_in(for_interner),
}
}
pub fn forbid_condition(&mut self, condition: Interned<T>) {
self.forbidden.insert(condition);
}
pub fn advance(&mut self, condition: Interned<T>) -> Option<&mut Self> {
if let Some(idx) = self.conditions.iter().position(|c| *c == condition) {
Some(&mut self.next[idx])
} else {
None
}
}
pub fn forbidden_conditions_for_all_prefixes_up_to(
&mut self,
prefix: &[Interned<T>],
) -> SmallBitmap<T> {
let mut forbidden = self.forbidden.clone();
let mut cursor = self;
for c in prefix.iter() {
if let Some(next) = cursor.advance(*c) {
cursor = next;
forbidden.union(&cursor.forbidden);
} else {
break;
}
}
forbidden
}
pub fn forbidden_conditions_after_prefix(
&mut self,
prefix: &[Interned<T>],
) -> Option<SmallBitmap<T>> {
let mut cursor = self;
for c in prefix.iter() {
if let Some(next) = cursor.advance(*c) {
cursor = next;
} else {
return None;
}
}
Some(cursor.forbidden.clone())
}
pub fn forbid_condition_after_prefix(
&mut self,
mut prefix: impl Iterator<Item = Interned<T>>,
forbidden: Interned<T>,
) {
match prefix.next() {
None => {
self.forbidden.insert(forbidden);
}
Some(first_condition) => {
if let Some(idx) = self.conditions.iter().position(|c| *c == first_condition) {
return self.next[idx].forbid_condition_after_prefix(prefix, forbidden);
}
let mut rest = DeadEndsCache {
conditions: vec![],
next: vec![],
forbidden: SmallBitmap::new(self.forbidden.universe_length()),
};
rest.forbid_condition_after_prefix(prefix, forbidden);
self.conditions.push(first_condition);
self.next.push(rest);
}
}
}
}