use crate::{
context::GenericContext,
db::LevelIndex,
misc::log::targets::{self},
structures::{clause::Clause, literal::Literal},
types::err,
};
impl<R: rand::Rng + std::default::Default> GenericContext<R> {
pub fn backjump(&mut self, target: LevelIndex) {
unsafe {
for _ in 0..(self.literal_db.decision_count().saturating_sub(target)) {
self.atom_db
.drop_value(self.literal_db.last_decision_unchecked().atom());
for (_, literal) in self.literal_db.last_consequences_unchecked() {
self.atom_db.drop_value(literal.atom());
}
self.literal_db.forget_last_decision();
}
}
self.clear_q(target);
}
pub fn non_chronological_backjump_level(
&self,
clause: &impl Clause,
) -> Result<LevelIndex, err::Context> {
match clause.size() {
0 => panic!("!"),
1 => Ok(0),
_ => {
let mut top_two = (None, None);
for literal in clause.literals() {
let Some(dl) = (unsafe { self.atom_db.decision_index_of(literal.atom()) })
else {
log::error!(target: targets::BACKJUMP, "{literal} was not chosen");
return Err(err::Context::Backjump);
};
match top_two {
(_, None) => top_two.1 = Some(dl),
(_, Some(the_top)) if dl > the_top => {
top_two.0 = top_two.1;
top_two.1 = Some(dl);
}
(None, _) => top_two.0 = Some(dl),
(Some(second_to_top), _) if dl > second_to_top => top_two.0 = Some(dl),
_ => {}
}
}
match top_two {
(None, _) => Ok(0),
(Some(second_to_top), _) => Ok(second_to_top),
}
}
}
}
}