use std::ops::Deref;
use crate::conflict_resolving::ConflictAnalysisContext;
use crate::predicates::Predicate;
#[derive(Clone, Debug)]
pub(crate) struct LearnedNogood {
pub(crate) predicates: Vec<Predicate>,
pub(crate) backtrack_level: usize,
}
impl Deref for LearnedNogood {
type Target = [Predicate];
fn deref(&self) -> &Self::Target {
&self.predicates
}
}
impl LearnedNogood {
pub(crate) fn create_from_vec(
mut clean_nogood: Vec<Predicate>,
context: &ConflictAnalysisContext,
) -> Self {
let mut index = 1;
let mut highest_level_below_current = 0;
while index < clean_nogood.len() {
let predicate = clean_nogood[index];
let dl = context
.state
.get_checkpoint_for_predicate(predicate)
.unwrap();
if dl == context.state.get_checkpoint() {
clean_nogood.swap(0, index);
index -= 1;
} else if dl > highest_level_below_current {
highest_level_below_current = dl;
clean_nogood.swap(1, index);
}
index += 1;
}
let backjump_level = if clean_nogood.len() > 1 {
context
.state
.get_checkpoint_for_predicate(clean_nogood[1])
.unwrap()
} else {
0
};
Self {
predicates: clean_nogood,
backtrack_level: backjump_level,
}
}
}