mod eliminate;
mod heap;
mod simplify;
mod subsume;
use {
crate::{
assign::AssignIF,
cdb::ClauseDBIF,
processor::heap::{LitOccurs, VarOccHeap},
state::State,
types::*,
},
std::slice::Iter,
};
pub trait EliminateIF: Instantiate {
fn is_running(&self) -> bool;
fn prepare(&mut self, asg: &mut impl AssignIF, cdb: &mut impl ClauseDBIF, force: bool);
fn enqueue_var(&mut self, asg: &mut impl AssignIF, vi: VarId, upward: bool);
fn simplify(
&mut self,
asg: &mut impl AssignIF,
cdb: &mut impl ClauseDBIF,
state: &mut State,
force_run: bool,
) -> MaybeInconsistent;
fn sorted_iterator(&self) -> Iter<'_, u32>;
fn stats(&self, vi: VarId) -> Option<(usize, usize)>;
fn eliminated_lits(&mut self) -> &mut Vec<Lit>;
}
#[derive(Copy, Clone, Eq, Debug, PartialEq)]
enum EliminatorMode {
Dormant,
Running,
}
#[derive(Clone, Debug)]
pub struct Eliminator {
enable: bool,
mode: EliminatorMode,
clause_queue: Vec<ClauseId>,
var_queue: VarOccHeap,
bwdsub_assigns: usize,
elim_lits: Vec<Lit>,
eliminate_var_occurrence_limit: usize,
eliminate_grow_limit: usize,
eliminate_occurrence_limit: usize,
subsume_literal_limit: usize,
var: Vec<LitOccurs>,
pub num_subsumed: usize,
}
#[cfg(not(feature = "no_IO"))]
#[cfg(test)]
mod tests {
use super::*;
use crate::{assign::VarManipulateIF, processor::EliminateIF, solver::Solver};
use std::path::Path;
#[test]
fn check_elimination() {
let mut config = Config::default();
if !config.enable_eliminator {
return;
}
config.quiet_mode = true;
let mut s = Solver::try_from(Path::new("cnfs/sample.cnf")).expect("failed to load");
let Solver {
ref mut asg,
ref mut cdb,
ref mut state,
..
} = s;
let mut elim = Eliminator::instantiate(&state.config, &state.cnf);
assert!(elim.enable);
elim.simplify(asg, cdb, state, false).expect("");
assert!(!asg.var_iter().skip(1).all(|v| v.is(FlagVar::ELIMINATED)));
assert!(0 < asg.num_eliminated_vars);
assert_eq!(
asg.num_eliminated_vars,
asg.var_iter().filter(|v| v.is(FlagVar::ELIMINATED)).count()
);
let elim_vars = asg
.var_iter()
.enumerate()
.skip(1)
.filter(|(_, v)| v.is(FlagVar::ELIMINATED))
.map(|(vi, _)| vi)
.collect::<Vec<_>>();
assert_eq!(
0,
cdb.iter()
.skip(1)
.filter(|c| !c.is_dead())
.filter(|c| c.iter().any(|l| elim_vars.contains(&l.vi())))
.count()
);
}
}