mod heap;
mod learning_rate;
mod propagate;
mod select;
mod stack;
mod trail_saving;
pub use self::{
learning_rate::VarActivityScheme,
propagate::PropagateIF,
property::*,
select::{RephaseTarget, VarSelectIF},
stack::{AssignStack, VarManipulateIF},
};
use {
crate::{cdb::ClauseDBIF, types::*},
std::{fmt, ops::Range, slice::Iter},
};
#[cfg(feature = "trail_saving")]
pub use self::trail_saving::TrailSavingIF;
pub trait AssignIF:
ActivityIF<VarId>
+ Instantiate
+ PropagateIF
+ VarManipulateIF
+ PropertyDereference<property::Tusize, usize>
+ PropertyReference<property::TEma, EmaView>
{
fn root_level(&self) -> DecisionLevel;
fn current_conflict_index(&self) -> usize;
fn stack(&self, i: usize) -> Lit;
fn stack_range(&self, r: Range<usize>) -> &[Lit];
fn stack_len(&self) -> usize;
fn len_upto(&self, n: DecisionLevel) -> usize;
fn stack_is_empty(&self) -> bool;
fn stack_iter(&self) -> Iter<'_, Lit>;
fn decision_level(&self) -> DecisionLevel;
fn decision_vi(&self, lv: DecisionLevel) -> VarId;
fn remains(&self) -> bool;
fn assign_ref(&self) -> Vec<Option<bool>>;
fn extend_model(&mut self, c: &mut impl ClauseDBIF) -> Vec<Option<bool>>;
fn satisfies(&self, c: &[Lit]) -> bool;
fn literal_block_distance(&mut self, lits: &[Lit]) -> DecisionLevel;
fn literal_block_distance_current(&mut self, lits: &[Lit]) -> DecisionLevel;
fn literal_block_distance_(&self, lits: &[Lit]) -> usize;
fn activity_sum(&mut self, lits: &[Lit]) -> f64;
fn activity_scheme(&self) -> &VarActivityScheme;
fn phase_mode(&self) -> RephaseTarget;
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum AssignReason {
BinaryLink(Lit),
Decision(DecisionLevel),
Implication(ClauseId),
None,
}
impl fmt::Display for AssignReason {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AssignReason::BinaryLink(_) => write!(f, "Implied by a binary clause"),
AssignReason::Decision(0) => write!(f, "Asserted"),
AssignReason::Decision(lvl) => write!(f, "Decided at level {lvl}"),
AssignReason::Implication(cid) => write!(f, "Implied by {cid}"),
AssignReason::None => write!(f, "Not assigned"),
}
}
}
pub mod property {
use super::stack::AssignStack;
use crate::types::*;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Tusize {
NumConflict,
NumDecision,
NumPropagation,
NumRestart,
NumVar,
NumAssertedVar,
NumEliminatedVar,
NumReconflict,
NumRepropagation,
NumUnassertedVar,
NumUnassignedVar,
RootLevel,
}
pub const USIZES: [Tusize; 12] = [
Tusize::NumConflict,
Tusize::NumDecision,
Tusize::NumPropagation,
Tusize::NumRestart,
Tusize::NumVar,
Tusize::NumAssertedVar,
Tusize::NumEliminatedVar,
Tusize::NumReconflict,
Tusize::NumRepropagation,
Tusize::NumUnassertedVar,
Tusize::NumUnassignedVar,
Tusize::RootLevel,
];
impl PropertyDereference<Tusize, usize> for AssignStack {
#[inline]
fn derefer(&self, k: Tusize) -> usize {
match k {
Tusize::NumConflict => self.num_conflict,
Tusize::NumDecision => self.num_decision,
Tusize::NumPropagation => self.num_propagation,
Tusize::NumRestart => self.num_restart,
Tusize::NumVar => self.num_vars,
Tusize::NumAssertedVar => self.num_asserted_vars,
Tusize::NumEliminatedVar => self.num_eliminated_vars,
Tusize::NumReconflict => self.num_reconflict,
Tusize::NumRepropagation => self.num_repropagation,
Tusize::NumUnassertedVar => {
self.num_vars - self.num_asserted_vars - self.num_eliminated_vars
}
Tusize::NumUnassignedVar => {
self.num_vars
- self.num_asserted_vars
- self.num_eliminated_vars
- self.trail.len()
}
Tusize::RootLevel => self.root_level as usize,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Tf64 {
AverageVarActivity,
CurrentWorkingSetSize,
VarLearningRate,
}
pub const F64S: [Tf64; 3] = [
Tf64::AverageVarActivity,
Tf64::CurrentWorkingSetSize,
Tf64::VarLearningRate,
];
impl PropertyDereference<Tf64, f64> for AssignStack {
#[inline]
fn derefer(&self, k: Tf64) -> f64 {
match k {
Tf64::AverageVarActivity => 0.0, Tf64::CurrentWorkingSetSize => 0.0, Tf64::VarLearningRate => 1.0 - self.activity_stay_rate,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TEma {
DecisionPerConflict,
PropagationPerConflict,
ConflictPerRestart,
ConflictPerBaseRestart,
ConlictDistanceAverage,
}
pub const EMAS: [TEma; 5] = [
TEma::DecisionPerConflict,
TEma::PropagationPerConflict,
TEma::ConflictPerRestart,
TEma::ConflictPerBaseRestart,
TEma::ConlictDistanceAverage,
];
impl PropertyReference<TEma, EmaView> for AssignStack {
#[inline]
fn refer(&self, k: TEma) -> &EmaView {
match k {
TEma::DecisionPerConflict => self.dpc_ema.as_view(),
TEma::PropagationPerConflict => self.ppc_ema.as_view(),
TEma::ConflictPerRestart => self.cpr_ema.as_view(),
TEma::ConflictPerBaseRestart => self.cpr_ema.as_view(),
TEma::ConlictDistanceAverage => self.conflict_interval_average.0.as_view(),
}
}
}
}