use crate::{
config::Config,
db::LevelIndex,
structures::{consequence::Consequence, literal::CLiteral},
};
#[doc(hidden)]
mod ad_level;
#[doc(hidden)]
pub mod config;
pub use config::LiteralDBConfig;
pub use ad_level::*;
#[allow(dead_code)]
pub struct LiteralDB {
pub config: LiteralDBConfig,
pub lowest_decision_level: LevelIndex,
pub level_stack: Vec<ADLevel>,
pub assumptions: Vec<CLiteral>,
}
impl LiteralDB {
pub fn push_fresh_decision(&mut self, decision: CLiteral) {
self.level_stack.push(ADLevel::new(decision));
}
pub fn push_fresh_assumption(&mut self, assumption: CLiteral) {
self.level_stack.push(ADLevel::new(assumption));
self.lowest_decision_level += 1;
}
}
impl LiteralDB {
pub fn assumption_is_made(&self) -> bool {
self.lowest_decision_level > 0
}
pub fn store_assumption(&mut self, assumption: CLiteral) {
self.assumptions.push(assumption);
}
pub fn stored_assumptions(&self) -> &[CLiteral] {
&self.assumptions
}
pub unsafe fn stored_assumption(&self, index: usize) -> CLiteral {
*self.assumptions.get_unchecked(index)
}
pub fn clear_assumptions(&mut self) {
self.assumptions.clear();
}
}
impl LiteralDB {
pub fn new(config: &Config) -> Self {
LiteralDB {
config: config.literal_db.clone(),
lowest_decision_level: 0,
level_stack: Vec::default(),
assumptions: Vec::default(),
}
}
pub fn lowest_decision_level(&self) -> LevelIndex {
self.lowest_decision_level
}
pub unsafe fn decision_unchecked(&self, level: LevelIndex) -> CLiteral {
self.level_stack.get_unchecked(level as usize).literal()
}
pub unsafe fn top_decision_unchecked(&self) -> CLiteral {
self.level_stack
.get_unchecked(self.level_stack.len() - 1)
.literal()
}
pub fn decision_consequences_unchecked(&self, level: LevelIndex) -> &[Consequence] {
unsafe {
self.level_stack
.get_unchecked(level as usize)
.consequences()
}
}
pub unsafe fn top_consequences_unchecked(&self) -> &[Consequence] {
self.level_stack
.get_unchecked(self.current_level().saturating_sub(1) as usize)
.consequences()
}
pub fn forget_top_level(&mut self) {
self.level_stack.pop();
}
pub fn decision_count(&self) -> LevelIndex {
(self.level_stack.len() as LevelIndex) - self.lowest_decision_level
}
pub fn decision_is_made(&self) -> bool {
self.decision_count() > 0
}
pub fn current_level(&self) -> LevelIndex {
self.level_stack.len() as LevelIndex
}
pub unsafe fn top_level_unchecked_mut(&mut self) -> &mut ADLevel {
let top_decision_index = self.level_stack.len().saturating_sub(1);
self.level_stack.get_unchecked_mut(top_decision_index)
}
}
impl LiteralDB {
pub(super) unsafe fn store_top_consequence_unchecked(&mut self, consequence: Consequence) {
self.top_level_unchecked_mut()
.store_consequence(consequence);
}
}