#[doc(hidden)]
pub mod activity;
#[doc(hidden)]
pub mod valuation;
pub mod watch_db;
use std::rc::Rc;
use crate::{
config::{dbs::AtomDBConfig, Activity, Config},
db::{atom::watch_db::WatchDB, LevelIndex},
dispatch::{
library::delta::{self},
Dispatch,
},
generic::index_heap::IndexHeap,
misc::log::targets::{self},
structures::{
atom::Atom,
valuation::{vValuation, Valuation},
},
};
pub struct AtomDB {
watch_dbs: Vec<WatchDB>,
valuation: vValuation,
previous_valuation: Vec<bool>,
activity_heap: IndexHeap<Activity>,
decision_indicies: Vec<Option<LevelIndex>>,
internal_map: std::collections::HashMap<String, Atom>,
external_map: Vec<String>,
dispatcher: Option<Rc<dyn Fn(Dispatch)>>,
config: AtomDBConfig,
}
pub enum AtomValue {
NotSet,
Same,
Different,
}
impl AtomDB {
pub fn new(config: &Config, dispatcher: Option<Rc<dyn Fn(Dispatch)>>) -> Self {
AtomDB {
external_map: Vec::<String>::default(),
internal_map: std::collections::HashMap::default(),
watch_dbs: Vec::default(),
activity_heap: IndexHeap::default(),
valuation: Vec::default(),
previous_valuation: Vec::default(),
decision_indicies: Vec::default(),
dispatcher,
config: config.atom_db.clone(),
}
}
pub fn count(&self) -> usize {
self.valuation.len()
}
pub fn valuation(&self) -> &impl Valuation {
&self.valuation
}
pub fn internal_representation(&self, name: &str) -> Option<Atom> {
self.internal_map.get(name).copied()
}
pub fn external_representation(&self, index: Atom) -> &String {
&self.external_map[index as usize]
}
pub fn fresh_atom(&mut self, string: &str, previous_value: bool) -> Atom {
let the_atoms = self.watch_dbs.len() as Atom;
self.internal_map.insert(string.to_string(), the_atoms);
self.external_map.push(string.to_string());
self.activity_heap.add(the_atoms as usize, 1.0);
self.watch_dbs.push(WatchDB::default());
self.valuation.push(None);
self.previous_valuation.push(previous_value);
self.decision_indicies.push(None);
if let Some(dispatcher) = &self.dispatcher {
let delta_rep = delta::AtomDB::ExternalRepresentation(string.to_string());
dispatcher(Dispatch::Delta(delta::Delta::AtomDB(delta_rep)));
let delta = delta::AtomDB::Internalised(the_atoms);
dispatcher(Dispatch::Delta(delta::Delta::AtomDB(delta)));
}
the_atoms
}
pub unsafe fn decision_index_of(&self, v_idx: Atom) -> Option<LevelIndex> {
*self.decision_indicies.get_unchecked(v_idx as usize)
}
pub unsafe fn set_value(
&mut self,
atom: Atom,
value: bool,
level: Option<LevelIndex>,
) -> Result<AtomValue, AtomValue> {
match self.value_of(atom) {
None => {
*self.valuation.get_unchecked_mut(atom as usize) = Some(value);
*self.decision_indicies.get_unchecked_mut(atom as usize) = level;
Ok(AtomValue::NotSet)
}
Some(v) if v == value => Ok(AtomValue::Same),
Some(_) => Err(AtomValue::Different),
}
}
pub unsafe fn drop_value(&mut self, atom: Atom) {
log::trace!(target: targets::VALUATION, "Cleared: {atom}");
self.clear_value(atom);
self.activity_heap.activate(atom as usize);
}
}