1use term::ops::*;
16use model::*;
17use kernel::*;
18use propagation::events::*;
19use gcollections::ops::*;
20use gcollections::*;
21use std::fmt::Debug;
22
23#[derive(Clone, Debug)]
24pub struct Constant<V>
25{
26 value: V
27}
28
29impl<V> Constant<V>
30{
31 pub fn new(value: V) -> Constant<V> {
32 Constant {
33 value: value
34 }
35 }
36}
37
38impl<V> DisplayStateful<Model> for Constant<V> where
39 V: Debug
40{
41 fn display(&self, _model: &Model) {
42 print!("{:?}", self.value);
43 }
44}
45
46impl<V, Domain, VStore> StoreMonotonicUpdate<VStore> for Constant<V> where
47 VStore: Collection<Item=Domain>,
48 Domain: Collection<Item=V> + Cardinality + Contains
49{
50 fn update(&mut self, _store: &mut VStore, value: VStore::Item) -> bool {
51 !value.is_empty() && value.contains(&self.value)
52 }
53}
54
55impl<V, Domain, VStore> StoreRead<VStore> for Constant<V> where
56 VStore: Collection<Item=Domain>,
57 Domain: Collection<Item=V> + Singleton,
58 V: Clone
59{
60 fn read(&self, _store: &VStore) -> Domain {
61 Domain::singleton(self.value.clone())
62 }
63}
64
65impl<V> ViewDependencies<FDEvent> for Constant<V>
66{
67 fn dependencies(&self, _event: FDEvent) -> Vec<(usize, FDEvent)> {
68 vec![]
69 }
70}
71
72#[cfg(test)]
73mod test {
74 use super::*;
75 use trilean::SKleene;
76 use trilean::SKleene::*;
77 use propagation::*;
78 use propagation::events::FDEvent;
79 use propagation::events::FDEvent::*;
80 use concept::*;
81 use variable::VStoreFD;
82 use propagators::test::*;
83 use propagators::cmp::*;
84 use interval::interval::*;
85
86 type VStore = VStoreFD;
87
88 #[test]
89 fn x_less_constant() {
90 let dom0_10 = (0,10).to_interval();
91 let dom0_4 = (0,4).to_interval();
92 let mut store = VStore::empty();
93 let x = Box::new(store.alloc(dom0_10)) as Var<VStore>;
94 let c = Box::new(Constant::new(5 as i32)) as Var<VStore>;
95
96 let x_less_c = XLessY::new(x.bclone(), c);
97 test_propagation(1, x_less_c, &mut store, Unknown, True, vec![(0, Bound)], true);
98 assert_eq!(x.read(&store), dom0_4);
99 }
100
101 #[test]
102 fn unary_propagator_test() {
103 let dom0_10 = (0,10).to_interval();
104 let dom0_0 = (0,0).to_interval();
105
106 unary_propagator_test_one(1, dom0_10, 0, XLessY::new, False, False, vec![], false);
107 unary_propagator_test_one(2, dom0_10, 11, XLessY::new, True, True, vec![], true);
108 unary_propagator_test_one(3, dom0_10, 10, XLessY::new, Unknown, True, vec![(0, Bound)], true);
109
110 unary_propagator_test_one(4, dom0_10, -1, x_leq_y, False, False, vec![], false);
111 unary_propagator_test_one(5, dom0_10, 10, x_leq_y, True, True, vec![], true);
112 unary_propagator_test_one(6, dom0_10, 9, x_leq_y, Unknown, True, vec![(0, Bound)], true);
113
114 unary_propagator_test_one(7, dom0_10, 10, x_greater_y, False, False, vec![], false);
115 unary_propagator_test_one(8, dom0_10, -1, x_greater_y, True, True, vec![], true);
116 unary_propagator_test_one(9, dom0_10, 0, x_greater_y, Unknown, True, vec![(0, Bound)], true);
117
118 unary_propagator_test_one(10, dom0_10, 11, x_geq_y, False, False, vec![], false);
119 unary_propagator_test_one(11, dom0_10, 0, x_geq_y, True, True, vec![], true);
120 unary_propagator_test_one(12, dom0_10, 1, x_geq_y, Unknown, True, vec![(0, Bound)], true);
121
122 unary_propagator_test_one(13, dom0_0, 0, XNeqY::new, False, False, vec![], false);
123 unary_propagator_test_one(14, dom0_10, 5, XNeqY::new, Unknown, Unknown, vec![], true);
124 unary_propagator_test_one(15, dom0_10, 0, XNeqY::new, Unknown, True, vec![(0, Bound)], true);
125 unary_propagator_test_one(16, dom0_10, 10, XNeqY::new, Unknown, True, vec![(0, Bound)], true);
126 }
127
128 fn unary_propagator_test_one<P, R>(id: u32, x: Interval<i32>, c: i32, make_prop: P,
129 before: SKleene, after: SKleene, expected: Vec<(usize, FDEvent)>, propagate_success: bool) where
130 P: FnOnce(FDVar, FDVar) -> R,
131 R: PropagatorConcept<VStoreFD, FDEvent>
132 {
133 let mut store = VStore::empty();
134 let x = Box::new(store.alloc(x)) as Var<VStore>;
135 let propagator = make_prop(x, Box::new(Constant::new(c)) as Var<VStore>);
136 test_propagation(id, propagator, &mut store, before, after, expected, propagate_success);
137 }
138}