use crate::domain::Domain;
use super::lambda::CheckerFn;
use super::traits::{Constraint, SoftConstraint, VarId};
pub struct SoftLambdaConstraint<D: Domain> {
pub(crate) scope: Vec<VarId>,
pub(crate) checker: CheckerFn<D>,
pub(crate) penalty: f64,
label: String,
}
impl<D: Domain> std::fmt::Debug for SoftLambdaConstraint<D> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"SoftLambdaConstraint({}, {:?}, penalty={})",
self.label, self.scope, self.penalty
)
}
}
impl<D: Domain> SoftLambdaConstraint<D> {
pub fn new(
scope: Vec<VarId>,
checker: impl Fn(&[Option<D::Value>]) -> bool + 'static,
penalty: f64,
label: impl Into<String>,
) -> Self {
Self {
scope,
checker: Box::new(checker),
penalty,
label: label.into(),
}
}
}
impl<D: Domain> Constraint<D> for SoftLambdaConstraint<D> {
fn scope(&self) -> &[VarId] {
&self.scope
}
fn check(&self, _assignment: &[Option<D::Value>]) -> bool {
true
}
}
impl<D: Domain> SoftConstraint<D> for SoftLambdaConstraint<D> {
fn penalty(&self) -> f64 {
self.penalty
}
}
impl<D: Domain> SoftLambdaConstraint<D> {
pub fn is_satisfied(&self, assignment: &[Option<D::Value>]) -> bool {
(self.checker)(assignment)
}
}