use std::{cell::RefCell, rc::Rc};
use crate::{solver::Solver, Lit, Valuation, Var};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ClausePersistence {
Forgettable,
Irreduntant,
}
pub trait ExternalPropagation: Solver {
fn add_observed_var(&mut self, var: Var);
fn connect_propagator<P: PropagatorDefinition + 'static>(&mut self, propagator: Rc<RefCell<P>>);
fn disconnect_propagator(&mut self);
fn new_observed_lit(&mut self) -> Lit {
self.new_observed_var().into()
}
fn new_observed_var(&mut self) -> Var {
let var = self.new_var_range(1).next().unwrap();
self.add_observed_var(var);
var
}
fn phase(&mut self, lit: Lit);
fn remove_observed_var(&mut self, var: Var);
fn reset_observed_vars(&mut self);
fn unphase(&mut self, lit: Lit);
}
pub trait PersistentAssignmentListener {
fn notify_persistent_assignment(&mut self, lit: Lit) {
let _ = lit;
}
}
pub trait PersistentAssignmentNotifier: Solver {
fn connect_persistent_assignment_listener<L: PersistentAssignmentListener + 'static>(
&mut self,
listener: Rc<RefCell<L>>,
);
fn disconnect_persistent_assignment_listener(&mut self);
}
pub trait Propagator {
fn add_external_clause(
&mut self,
slv: &mut dyn SolvingActions,
) -> Option<(Vec<Lit>, ClausePersistence)> {
let _ = slv;
None
}
fn add_reason_clause(&mut self, propagated_lit: Lit) -> Vec<Lit> {
let _ = propagated_lit;
Vec::new()
}
fn check_solution(&mut self, slv: &mut dyn SolvingActions, value: &dyn Valuation) -> bool {
let _ = value;
let _ = slv;
true
}
fn decide(&mut self, slv: &mut dyn SolvingActions) -> SearchDecision {
let _ = slv;
SearchDecision::Free
}
fn notify_assignment(&mut self, lits: &[Lit]) {
let _ = lits;
}
fn notify_backtrack(&mut self, new_level: usize, restart: bool) {
let _ = new_level;
let _ = restart;
}
fn notify_new_decision_level(&mut self) {}
fn propagate(&mut self, slv: &mut dyn SolvingActions) -> Option<Lit> {
let _ = slv;
None
}
}
pub trait PropagatorDefinition: Propagator {
const CHECK_ONLY: bool = false;
const REASON_PERSISTENCE: ClausePersistence = ClausePersistence::Irreduntant;
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SearchDecision {
Free,
Assign(Lit),
Backtrack(usize),
}
pub trait SolvingActions {
fn is_decision(&mut self, lit: Lit) -> bool;
fn new_observed_lit(&mut self) -> Lit {
self.new_observed_var().into()
}
fn new_observed_var(&mut self) -> Var;
fn phase(&mut self, lit: Lit);
fn unphase(&mut self, lit: Lit);
}