use crate::Solver;
use crate::propagation::PropagatorConstructor;
use crate::propagators::reified_propagator::ReifiedPropagatorArgs;
use crate::variables::Literal;
mod constraint_poster;
pub use constraint_poster::ConstraintPoster;
pub trait Constraint {
fn post(self, solver: &mut Solver);
fn implied_by(self, solver: &mut Solver, reification_literal: Literal);
}
impl<ConcretePropagator> Constraint for ConcretePropagator
where
ConcretePropagator: PropagatorConstructor + 'static,
{
fn post(self, solver: &mut Solver) {
let _ = solver.add_propagator(self);
}
fn implied_by(self, solver: &mut Solver, reification_literal: Literal) {
let _ = solver.add_propagator(ReifiedPropagatorArgs {
propagator: self,
reification_literal,
});
}
}
impl<C: Constraint> Constraint for Vec<C> {
fn post(self, solver: &mut Solver) {
self.into_iter().for_each(|c| c.post(solver))
}
fn implied_by(self, solver: &mut Solver, reification_literal: Literal) {
self.into_iter()
.for_each(|c| c.implied_by(solver, reification_literal))
}
}
pub trait NegatableConstraint: Constraint {
type NegatedConstraint: NegatableConstraint + 'static;
fn negation(&self) -> Self::NegatedConstraint;
fn reify(self, solver: &mut Solver, reification_literal: Literal)
where
Self: Sized,
{
let negation = self.negation();
self.implied_by(solver, reification_literal);
negation.implied_by(solver, !reification_literal)
}
}