csp_solver/constraint/
not_equal.rs1use crate::domain::Domain;
6use crate::variable::Variable;
7
8use super::traits::{Constraint, Revision, VarId};
9
10#[derive(Debug)]
11pub struct NotEqual {
12 pub(crate) scope: [VarId; 2],
13}
14
15impl NotEqual {
16 pub fn new(x: VarId, y: VarId) -> Self {
17 Self { scope: [x, y] }
18 }
19
20 pub(crate) fn check_impl<V: PartialEq>(&self, assignment: &[Option<V>]) -> bool {
21 let xi = self.scope[0] as usize;
22 let xj = self.scope[1] as usize;
23 match (&assignment[xi], &assignment[xj]) {
24 (Some(a), Some(b)) => a != b,
25 _ => true,
26 }
27 }
28
29 pub(crate) fn revise_impl<D: Domain>(&self, vars: &mut [Variable<D>], depth: usize) -> Revision
30 where
31 D::Value: PartialEq,
32 {
33 let xi = self.scope[0] as usize;
34 let xj = self.scope[1] as usize;
35 let mut changed = false;
36
37 if let Some(v) = vars[xi].domain.singleton_value()
38 && vars[xj].prune(&v, depth)
39 {
40 changed = true;
41 }
42 if let Some(v) = vars[xj].domain.singleton_value()
43 && vars[xi].prune(&v, depth)
44 {
45 changed = true;
46 }
47
48 if vars[xi].domain.is_empty() || vars[xj].domain.is_empty() {
49 return Revision::Unsatisfiable;
50 }
51
52 if changed {
53 Revision::Changed
54 } else {
55 Revision::Unchanged
56 }
57 }
58}
59
60impl<D: Domain> Constraint<D> for NotEqual
61where
62 D::Value: PartialEq,
63{
64 fn scope(&self) -> &[VarId] {
65 &self.scope
66 }
67 fn check(&self, assignment: &[Option<D::Value>]) -> bool {
68 self.check_impl(assignment)
69 }
70 fn revise(&self, vars: &mut [Variable<D>], depth: usize) -> Revision {
71 self.revise_impl(vars, depth)
72 }
73}