pub mod clause;
pub mod cnf;
pub mod ema;
pub mod flags;
pub mod idx;
pub mod lit;
pub mod luby;
pub mod rng;
pub mod sort_key;
pub mod var;
pub use self::{
clause::*, cnf::*, ema::*, flags::*, idx::*, lit::*, luby::*, rng::*, sort_key::*, var::*,
};
pub use crate::{assign::AssignReason, config::Config, solver::SolverEvent};
use std::{fmt, fs::File};
pub trait PropertyReference<I, O> {
fn refer(&self, key: I) -> &O;
}
pub trait PropertyDereference<I, O: Sized> {
fn derefer(&self, key: I) -> O;
}
pub trait ActivityIF<Ix> {
fn activity(&self, ix: Ix) -> f64;
fn set_activity(&mut self, ix: Ix, val: f64);
fn reward_to(&mut self, vi: VarId) -> f64;
fn reward_at_analysis(&mut self, _ix: Ix) {}
fn reward_at_assign(&mut self, _ix: Ix) {}
fn reward_at_propagation(&mut self, _ix: Ix) {}
fn reward_at_unassign(&mut self, _ix: Ix) {}
fn set_learning_rate(&mut self, learning_rate: f64);
fn update_activity_tick(&mut self);
fn rescale_learning_rate(&mut self, scaling: f64);
}
pub trait Instantiate {
fn instantiate(conf: &Config, cnf: &CNFDescription) -> Self;
fn handle(&mut self, _e: SolverEvent) {}
}
pub trait Delete<T> {
fn delete_unstable<F>(&mut self, filter: F)
where
F: FnMut(&T) -> bool;
}
pub type ConflictContext = (Lit, AssignReason);
pub type PropagationResult = Result<(), ConflictContext>;
#[derive(Debug, Eq, PartialEq)]
pub enum SolverError {
EmptyClause,
InvalidLiteral,
IOError,
Inconsistent,
OutOfMemory,
RootLevelConflict(ConflictContext),
TimeOut,
SolverBug,
UndescribedError,
}
impl fmt::Display for SolverError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self:?}")
}
}
pub type MaybeInconsistent = Result<(), SolverError>;
impl<T> Delete<T> for Vec<T> {
fn delete_unstable<F>(&mut self, filter: F)
where
F: FnMut(&T) -> bool,
{
if let Some(i) = self.iter().position(filter) {
self.swap_remove(i);
}
}
}
#[derive(Debug, Default)]
pub struct Logger {
dest: Option<File>,
}
impl fmt::Display for Logger {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Dump({:?})", self.dest)
}
}
impl Logger {
pub fn new<T: AsRef<str>>(fname: T) -> Self {
Logger {
dest: File::create(fname.as_ref()).ok(),
}
}
pub fn dump(&mut self, mes: String) {
use std::io::Write;
if let Some(f) = &mut self.dest {
f.write_all(&mes.into_bytes())
.unwrap_or_else(|_| panic!("fail to dump {f:?}"));
} else {
println!("{mes}");
}
}
}
pub const RED: &str = "\x1B[001m\x1B[031m";
pub const GREEN: &str = "\x1B[001m\x1B[032m";
pub const BLUE: &str = "\x1B[001m\x1B[034m";
pub const MAGENTA: &str = "\x1B[001m\x1B[035m";
pub const CYAN: &str = "\x1B[001m\x1B[036m";
pub const RESET: &str = "\x1B[000m";
pub const REVERT: &str = "\x1B[1A\x1B[1G\x1B[1K";
pub const REVERSE: &str = "\x1B[001m\x1B[07m";
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
#[test]
fn test_cnf() {
if let Ok(reader) = CNFReader::try_from(Path::new("cnfs/sample.cnf")) {
assert_eq!(reader.cnf.num_of_variables, 250);
assert_eq!(reader.cnf.num_of_clauses, 1065);
} else {
panic!("failed to load cnfs/sample.cnf");
}
}
}