pcp/term/
constant.rs

1// Copyright 2015 Pierre Talbot (IRCAM)
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7//     http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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}