Skip to main content

csp_solver/domain/
lattice.rs

1//! LatticeDomain — wrapper for monotonic CSP (types, FIRST/FOLLOW sets).
2
3use super::bitset::BitsetDomain;
4use super::traits::{Domain, LatticeDomain};
5
6/// A lattice domain backed by a `BitsetDomain`.
7///
8/// The domain is always a singleton (size == 1) from the solver's perspective:
9/// it holds a single "current value" that grows monotonically via `join` (union).
10/// Because it's always assigned, no backtracking search is needed -- AC-3
11/// propagation alone reaches the fixed point.
12#[derive(Debug, Clone, PartialEq)]
13pub struct BitsetLatticeDomain {
14    /// The current lattice value (grows via union).
15    value: BitsetDomain,
16}
17
18impl BitsetLatticeDomain {
19    /// Create a lattice domain initialized with the given bitset value.
20    pub fn new(value: BitsetDomain) -> Self {
21        Self { value }
22    }
23
24    /// Access the underlying bitset.
25    pub fn inner(&self) -> &BitsetDomain {
26        &self.value
27    }
28}
29
30impl Domain for BitsetLatticeDomain {
31    type Value = BitsetDomain;
32
33    fn size(&self) -> usize {
34        // Lattice domains are always "singletons" -- one current value.
35        1
36    }
37
38    fn is_singleton(&self) -> bool {
39        true
40    }
41
42    fn singleton_value(&self) -> Option<BitsetDomain> {
43        Some(self.value.clone())
44    }
45
46    fn contains(&self, val: &BitsetDomain) -> bool {
47        self.value == *val
48    }
49
50    fn remove(&mut self, _val: &BitsetDomain) -> bool {
51        // Lattice domains don't support removal -- they only grow.
52        false
53    }
54
55    fn add(&mut self, _val: &BitsetDomain) {
56        // No-op for lattice domains.
57    }
58
59    fn values(&self) -> Vec<BitsetDomain> {
60        vec![self.value.clone()]
61    }
62
63    fn iter(&self) -> impl Iterator<Item = BitsetDomain> {
64        std::iter::once(self.value.clone())
65    }
66}
67
68impl LatticeDomain for BitsetLatticeDomain {
69    fn bottom() -> Self {
70        Self {
71            value: BitsetDomain::empty(),
72        }
73    }
74
75    fn join(&mut self, other: &Self) -> bool {
76        let old = self.value.bits();
77        self.value.union_with(&other.value);
78        self.value.bits() != old
79    }
80}