csp_solver/constraint/
dispatch.rs1use crate::domain::Domain;
4use crate::variable::Variable;
5
6use super::all_different::AllDifferent;
7use super::all_different_except::AllDifferentExcept;
8use super::lambda::LambdaConstraint;
9use super::not_equal::NotEqual;
10use super::soft::SoftLambdaConstraint;
11use super::traits::{Constraint, Revision, VarId};
12
13pub enum ConstraintEnum<D: Domain> {
15 NotEqual(NotEqual),
16 AllDifferent(AllDifferent),
17 AllDifferentExcept(AllDifferentExcept<D::Value>),
18 Lambda(LambdaConstraint<D>),
19 Soft(SoftLambdaConstraint<D>),
20 Custom(Box<dyn Constraint<D>>),
21}
22
23impl<D: Domain> std::fmt::Debug for ConstraintEnum<D> {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 match self {
26 Self::NotEqual(c) => c.fmt(f),
27 Self::AllDifferent(c) => c.fmt(f),
28 Self::AllDifferentExcept(c) => c.fmt(f),
29 Self::Lambda(c) => c.fmt(f),
30 Self::Soft(c) => c.fmt(f),
31 Self::Custom(c) => c.fmt(f),
32 }
33 }
34}
35
36impl<D: Domain> ConstraintEnum<D>
37where
38 D::Value: PartialEq,
39{
40 #[inline]
41 pub fn scope(&self) -> &[VarId] {
42 match self {
43 Self::NotEqual(c) => &c.scope,
44 Self::AllDifferent(c) => &c.scope,
45 Self::AllDifferentExcept(c) => &c.scope,
46 Self::Lambda(c) => &c.scope,
47 Self::Soft(c) => &c.scope,
48 Self::Custom(c) => c.scope(),
49 }
50 }
51
52 #[inline]
53 pub fn check(&self, assignment: &[Option<D::Value>]) -> bool {
54 match self {
55 Self::NotEqual(c) => c.check_impl(assignment),
56 Self::AllDifferent(c) => c.check_impl(assignment),
57 Self::AllDifferentExcept(c) => c.check_impl(assignment),
58 Self::Lambda(c) => (c.checker)(assignment),
59 Self::Soft(_) => true, Self::Custom(c) => c.check(assignment),
61 }
62 }
63
64 #[inline]
65 pub fn revise(&self, vars: &mut [Variable<D>], depth: usize) -> Revision {
66 match self {
67 Self::NotEqual(c) => c.revise_impl(vars, depth),
68 Self::AllDifferent(c) => c.revise_impl(vars, depth),
69 Self::AllDifferentExcept(c) => c.revise_impl(vars, depth),
70 Self::Lambda(c) => <LambdaConstraint<D> as Constraint<D>>::revise(c, vars, depth),
71 Self::Soft(_) => Revision::Unchanged, Self::Custom(c) => c.revise(vars, depth),
73 }
74 }
75
76 #[inline]
79 pub fn soft_penalty(&self, assignment: &[Option<D::Value>]) -> f64 {
80 match self {
81 Self::Soft(c) => {
82 if c.is_satisfied(assignment) {
83 0.0
84 } else {
85 c.penalty
86 }
87 }
88 _ => 0.0,
89 }
90 }
91}