use std::borrow::Borrow;
use crate::{
db::atom::AtomDB,
misc::log::targets,
structures::literal::{abLiteral, Literal},
types::err::{self},
};
use super::dbClause;
impl dbClause {
pub fn subsume(
&mut self,
literal: impl Borrow<abLiteral>,
atom_db: &mut AtomDB,
fix_watch: bool,
) -> Result<usize, err::Subsumption> {
if self.clause.len() < 3 {
log::error!(target: targets::SUBSUMPTION, "Subsumption attempted on non-long clause");
return Err(err::Subsumption::ShortClause);
}
let mut position = {
let search = self
.clause
.iter()
.position(|clause_literal| clause_literal == literal.borrow());
match search {
None => {
log::error!(target: targets::SUBSUMPTION, "Pivot not found for subsumption");
return Err(err::Subsumption::NoPivot);
}
Some(p) => p,
}
};
let mut zero_swap = false;
if position == 0 {
self.clause.swap(0, self.watch_ptr);
zero_swap = true;
position = self.watch_ptr;
}
let removed = self.clause.swap_remove(position);
match unsafe { atom_db.unwatch_unchecked(removed.atom(), removed.polarity(), &self.key) } {
Ok(()) => {}
Err(_) => return Err(err::Subsumption::WatchError),
};
if fix_watch && position == self.watch_ptr {
let clause_length = self.clause.len();
self.watch_ptr = 1;
for index in 1..clause_length {
let index_literal = unsafe { self.clause.get_unchecked(index) };
let index_value = atom_db.value_of(index_literal.atom());
match index_value {
Some(value) if value != index_literal.polarity() => {}
_ => {
self.watch_ptr = index;
break;
}
}
}
let watched_literal = unsafe { self.clause.get_unchecked(self.watch_ptr) };
self.note_watch(watched_literal.atom(), watched_literal.polarity(), atom_db);
if zero_swap && atom_db.value_of(watched_literal.atom()).is_none() {
self.clause.swap(0, self.watch_ptr);
}
}
Ok(self.clause.len())
}
}