use varisat_formula::{lit::LitIdx, Var};
const NO_VAR_IDX: LitIdx = Var::max_count() as LitIdx;
#[derive(Default)]
pub struct VarMap {
mapping: Vec<LitIdx>,
}
impl VarMap {
pub fn get(&self, from: Var) -> Option<Var> {
match self.mapping.get(from.index()).cloned() {
Some(index) if index == NO_VAR_IDX => None,
Some(index) => Some(Var::from_index(index as usize)),
None => None,
}
}
pub fn insert(&mut self, into: Var, from: Var) {
if self.mapping.len() <= from.index() {
self.mapping.resize(from.index() + 1, NO_VAR_IDX);
}
debug_assert_eq!(self.mapping[from.index()], NO_VAR_IDX);
self.mapping[from.index()] = into.index() as LitIdx;
}
pub fn remove(&mut self, from: Var) {
if self.mapping.len() > from.index() {
self.mapping[from.index()] = NO_VAR_IDX;
}
}
pub fn watermark(&self) -> usize {
self.mapping.len()
}
}
#[derive(Default)]
pub struct VarBiMap {
fwd: VarMap,
bwd: VarMap,
}
impl VarBiMap {
pub fn fwd(&self) -> &VarMap {
&self.fwd
}
pub fn bwd(&self) -> &VarMap {
&self.bwd
}
pub fn fwd_mut(&mut self) -> VarBiMapMut {
VarBiMapMut {
fwd: &mut self.fwd,
bwd: &mut self.bwd,
}
}
pub fn bwd_mut(&mut self) -> VarBiMapMut {
VarBiMapMut {
fwd: &mut self.bwd,
bwd: &mut self.fwd,
}
}
}
pub struct VarBiMapMut<'a> {
fwd: &'a mut VarMap,
bwd: &'a mut VarMap,
}
impl<'a> VarBiMapMut<'a> {
pub fn insert(&mut self, into: Var, from: Var) {
self.fwd.insert(into, from);
self.bwd.insert(from, into);
}
pub fn remove(&mut self, from: Var) -> Option<Var> {
if let Some(into) = self.fwd.get(from) {
self.fwd.remove(from);
self.bwd.remove(into);
Some(into)
} else {
None
}
}
}