1use kernel::*;
16use variable::ops::*;
17use variable::concept::*;
18use term::identity::*;
19use gcollections::kind::*;
20use gcollections::ops::*;
21use model::*;
22use vec_map::{Drain, VecMap};
23use std::slice;
24use std::marker::PhantomData;
25use std::fmt::{Display, Debug};
26use std::ops::Index;
27
28#[derive(Clone, Debug, PartialEq, Eq)]
29pub struct Store<Memory, Event>
30{
31 memory: Memory,
32 delta: VecMap<Event>,
33 has_changed: bool
34}
35
36impl<Memory, Event> Collection for Store<Memory, Event> where
37 Memory: MemoryConcept
38{
39 type Item = <Memory as Collection>::Item;
40}
41
42impl<Memory, Event> AssociativeCollection for Store<Memory, Event> where
43 Memory: MemoryConcept
44{
45 type Location = Identity<<Memory as Collection>::Item>;
46}
47
48impl<Memory, Event, Domain> ImmutableMemoryConcept for Store<Memory, Event> where
49 Memory: MemoryConcept<Item=Domain>,
50 Event: Debug
51{}
52
53impl<Memory, Domain, Bound, Event> VStoreConcept for Store<Memory, Event> where
54 Memory: MemoryConcept<Item=Domain>,
55 Domain: Subset + Cardinality + Bounded<Item=Bound> + Display,
56 Event: EventConcept<Domain>
57{
58}
59
60impl<Memory, Event> Store<Memory, Event> where
61 Memory: MemoryConcept
62{
63 fn from_memory(memory: Memory) -> Self {
64 Store {
65 memory: memory,
66 delta: VecMap::new(),
67 has_changed: false
68 }
69 }
70}
71
72impl<Memory, Event> Empty for Store<Memory, Event> where
73 Memory: MemoryConcept
74{
75 fn empty() -> Store<Memory, Event> {
76 Store::from_memory(Memory::empty())
77 }
78}
79
80impl<Memory, Domain, Event> Store<Memory, Event> where
81 Memory: MemoryConcept,
82 Memory: Collection<Item=Domain>,
83 Domain: Subset + Cardinality + Bounded,
84 Event: EventConcept<Domain>
85{
86 fn update_delta(&mut self, key: usize, old_dom: &Domain) {
88 if let Some(delta) = Event::new(&self[key], old_dom) {
89 self.has_changed = true;
90 let mut updated = false;
91 if let Some(old_delta) = self.delta.get_mut(key) {
92 *old_delta = Merge::merge(old_delta.clone(), delta.clone());
93 updated = true;
94 }
95 if !updated {
96 self.delta.insert(key, delta);
97 }
98 }
99 }
100}
101
102impl<Memory, Event> Cardinality for Store<Memory, Event> where
103 Memory: MemoryConcept
104{
105 type Size = usize;
106
107 fn size(&self) -> usize {
108 self.memory.size()
109 }
110}
111
112impl<Memory, Event> Iterable for Store<Memory, Event> where
113 Memory: MemoryConcept
114{
115 fn iter<'a>(&'a self) -> slice::Iter<'a, Self::Item> {
116 self.memory.iter()
117 }
118}
119
120impl<Memory, Domain, Event> Alloc for Store<Memory, Event> where
121 Memory: MemoryConcept,
122 Memory: Collection<Item=Domain>,
123 Domain: Cardinality + IsEmpty
124{
125 fn alloc(&mut self, dom: Self::Item) -> Self::Location {
126 assert!(!dom.is_empty());
127 let var_idx = self.memory.size();
128 self.memory.push(dom);
129 Identity::new(var_idx)
130 }
131}
132
133impl<Memory, Domain, Event> MonotonicUpdate for Store<Memory, Event> where
134 Memory: MemoryConcept,
135 Memory: Collection<Item=Domain>,
136 Domain: Subset + Cardinality + Bounded,
137 Event: EventConcept<Domain>
138{
139 fn update(&mut self, loc: &Identity<Domain>, dom: Self::Item) -> bool {
141 let idx = loc.index();
142 assert!(dom.is_subset(&self.memory[idx]),
143 "Domain update must be monotonic.");
144 if dom.is_empty() {
145 false
146 }
147 else {
148 if dom.size() < self[idx].size() {
149 let old_dom = self.memory.replace(idx, dom);
150 self.update_delta(idx, &old_dom);
151 }
152 true
153 }
154 }
155}
156
157impl<Memory, Event> Index<usize> for Store<Memory, Event> where
158 Memory: MemoryConcept
159{
160 type Output = <Memory as Collection>::Item;
161
162 fn index<'a>(&'a self, index: usize) -> &'a Self::Output {
163 assert!(index < self.memory.size(),
164 "Variable not registered in the store. Variable index must be obtained with `alloc`.");
165 &self.memory[index]
166 }
167}
168
169impl<Memory, Event, Domain> Store<Memory, Event> where
170 Memory: MemoryConcept<Item=Domain>,
171 Domain: Display + IsSingleton
172{
173 fn display_var_matrix(&self, model: &Model,
174 var_idx: Vec<usize>, header: &str)
175 {
176 let header_width = 15;
177 let var_width = 20;
178 let num_columns = 8;
179 print!("{:>width$} ", header, width=header_width);
180 for (i,idx) in var_idx.into_iter().enumerate() {
181 if (i+1) % (num_columns+1) == 0 {
182 print!("\n{:>width$} ", "", width=header_width);
183 }
184 let var_str = format!("{:<6} = {}", model.var_name(idx), self[idx]);
185 print!("{:<width$}", var_str, width=var_width);
186 }
187 println!();
188 }
189}
190
191impl<Memory, Event, Domain> DisplayStateful<Model> for Store<Memory, Event> where
192 Memory: MemoryConcept<Item=Domain>,
193 Domain: Display + IsSingleton
194{
195 fn display(&self, model: &Model) {
196 let mut idx_assigned = vec![];
197 let mut idx_others = vec![];
198 for (i,dom) in self.memory.iter().enumerate() {
199 if dom.is_singleton() {
200 idx_assigned.push(i);
201 }
202 else {
203 idx_others.push(i);
204 }
205 }
206 self.display_var_matrix(model, idx_assigned, "assigned:");
207 self.display_var_matrix(model, idx_others, "not assigned:");
208 }
209}
210
211impl<Memory, Event> DrainDelta<Event> for Store<Memory, Event>
212{
213 fn drain_delta<'a>(&'a mut self) -> Drain<'a, Event> {
214 self.delta.drain()
215 }
216
217 fn has_changed(&self) -> bool {
218 self.has_changed
219 }
220
221 fn reset_changed(&mut self) {
222 self.has_changed = false;
223 }
224}
225
226impl<Memory, Event> Freeze for Store<Memory, Event> where
227 Memory: MemoryConcept
228{
229 type FrozenState = FrozenStore<Memory, Event>;
230 fn freeze(self) -> Self::FrozenState
231 {
232 FrozenStore::new(self)
233 }
234}
235
236pub struct FrozenStore<Memory, Event> where
237 Memory: MemoryConcept
238{
239 frozen_memory: Memory::FrozenState,
240 phantom_event: PhantomData<Event>
241}
242
243impl<Memory, Event> FrozenStore<Memory, Event> where
244 Memory: MemoryConcept
245{
246 fn new(store: Store<Memory, Event>) -> Self {
247 FrozenStore {
248 frozen_memory: store.memory.freeze(),
249 phantom_event: PhantomData
250 }
251 }
252}
253
254impl<Memory, Event> Snapshot for FrozenStore<Memory, Event> where
255 Memory: MemoryConcept
256{
257 type Label = <Memory::FrozenState as Snapshot>::Label;
258 type State = Store<Memory, Event>;
259
260 fn label(&mut self) -> Self::Label {
261 self.frozen_memory.label()
262 }
263
264 fn restore(self, label: Self::Label) -> Self::State {
265 Store::from_memory(self.frozen_memory.restore(label))
266 }
267}
268
269#[cfg(test)]
270pub mod test {
271 use variable::VStoreFD;
272 use variable::ops::*;
273 use term::ops::*;
274 use term::identity::*;
275 use propagation::events::*;
276 use propagation::events::FDEvent::*;
277 use interval::interval::*;
278 use gcollections::ops::*;
279
280 pub type Domain = Interval<i32>;
281 pub type VStore = VStoreFD;
282
283 pub fn consume_delta(store: &mut VStore, delta_expected: Vec<(usize, FDEvent)>) {
284 let res: Vec<(usize, FDEvent)> = store.drain_delta().collect();
285 assert_eq!(res, delta_expected);
286 assert!(store.drain_delta().next().is_none());
287 }
288
289 #[test]
290 fn ordered_assign_10_vars() {
291 let dom0_10 = (0, 10).to_interval();
292 let mut store = VStore::empty();
293
294 for i in 0..10 {
295 assert_eq!(store.alloc(dom0_10), Identity::new(i));
296 }
297 }
298
299 #[test]
300 fn valid_read_update() {
301 let dom0_10 = (0, 10).to_interval();
302 let dom5_5 = (5, 5).to_interval();
303 let mut store = VStore::empty();
304
305 let vars: Vec<_> = (0..10).map(|_| store.alloc(dom0_10)).collect();
306 for mut var in vars {
307 assert_eq!(var.read(&store), dom0_10);
308 assert_eq!(var.update(&mut store, dom5_5), true);
309 assert_eq!(var.read(&store), dom5_5);
310 }
311 }
312
313 #[test]
314 fn empty_update() {
315 let mut store = VStore::empty();
316 let dom5_5 = (5, 5).to_interval();
317
318 let mut var = store.alloc(dom5_5);
319 assert_eq!(var.update(&mut store, Interval::empty()), false);
320 }
321
322 #[test]
323 #[should_panic]
324 fn empty_assign() {
325 let mut store = VStore::empty();
326 store.alloc(Interval::<i32>::empty());
327 }
328
329 #[test]
330 #[should_panic]
331 fn non_monotonic_update_singleton() {
332 let dom0_10 = (0,10).to_interval();
333 let dom11_11 = 11.to_interval();
334
335 let mut store = VStore::empty();
336 let mut var = store.alloc(dom0_10);
337 var.update(&mut store, dom11_11);
338 }
339
340 #[test]
341 #[should_panic]
342 fn non_monotonic_update_widen() {
343 let dom0_10 = (0,10).to_interval();
344 let domm5_15 = (-5, 15).to_interval();
345
346 let mut store = VStore::empty();
347 let mut var = store.alloc(dom0_10);
348 var.update(&mut store, domm5_15);
349 }
350
351 fn test_op<Op>(test_num: u32, source: Domain, target: Domain, delta_expected: Vec<FDEvent>, update_success: bool, op: Op) where
352 Op: FnOnce(&VStore, Identity<Domain>) -> Domain
353 {
354 println!("Test number {}", test_num);
355 let mut store = VStore::empty();
356 let mut var = store.alloc(source);
357
358 let new = op(&store, var);
359 assert_eq!(var.update(&mut store, new), update_success);
360 assert_eq!(new, target);
361
362 if update_success {
363 let delta_expected = delta_expected.into_iter().map(|d| (var.index(), d)).collect();
364 consume_delta(&mut store, delta_expected);
365 assert_eq!(var.read(&store), target);
366 }
367 }
368
369 fn test_binary_op<Op>(source1: Domain, source2: Domain, target: Domain, delta_expected: Vec<(usize, FDEvent)>, update_success: bool, op: Op) where
370 Op: FnOnce(&VStore, Identity<Domain>, Identity<Domain>) -> Domain
371 {
372 let mut store = VStore::empty();
373 let mut var1 = store.alloc(source1);
374 let mut var2 = store.alloc(source2);
375
376 let new = op(&store, var1, var2);
377 assert_eq!(var1.update(&mut store, new), update_success);
378 assert_eq!(var2.update(&mut store, new), update_success);
379 assert_eq!(new, target);
380
381 if update_success {
382 consume_delta(&mut store, delta_expected);
383 assert_eq!(var1.read(&store), target);
384 assert_eq!(var2.read(&store), target);
385 }
386 }
387
388 #[test]
389 fn var_update_test() {
390 let dom0_10 = (0,10).to_interval();
391 let dom0_9 = (0,5).to_interval();
392 let dom1_10 = (5,10).to_interval();
393 let dom1_9 = (1,9).to_interval();
394 let dom0_0 = (0,0).to_interval();
395 let empty = Interval::empty();
396
397 var_update_test_one(1, dom0_10, dom0_10, vec![], true);
398 var_update_test_one(2, dom0_10, empty, vec![], false);
399 var_update_test_one(3, dom0_10, dom0_0, vec![Assignment], true);
400 var_update_test_one(4, dom0_10, dom1_10, vec![Bound], true);
401 var_update_test_one(5, dom0_10, dom0_9, vec![Bound], true);
402 var_update_test_one(6, dom0_10, dom1_9, vec![Bound], true);
403 }
404
405 fn var_update_test_one(test_num: u32, source: Domain, target: Domain, delta_expected: Vec<FDEvent>, update_success: bool) {
406 test_op(test_num, source, target, delta_expected, update_success, |_,_| target);
407 }
408
409 #[test]
410 fn var_shrink_bound() {
411 let dom0_10 = (0,10).to_interval();
412
413 var_shrink_lb_test_one(1, dom0_10, 0, vec![], true);
414 var_shrink_lb_test_one(2, dom0_10, 10, vec![Assignment], true);
415 var_shrink_lb_test_one(3, dom0_10, 1, vec![Bound], true);
416 var_shrink_lb_test_one(4, dom0_10, 11, vec![], false);
417
418 var_shrink_ub_test_one(5, dom0_10, 10, vec![], true);
419 var_shrink_ub_test_one(6, dom0_10, 0, vec![Assignment], true);
420 var_shrink_ub_test_one(7, dom0_10, 1, vec![Bound], true);
421 var_shrink_ub_test_one(8, dom0_10, -1, vec![], false);
422 }
423
424 fn var_shrink_lb_test_one(test_num: u32, source: Domain, target_lb: i32, delta_expected: Vec<FDEvent>, update_success: bool) {
425 let expected_dom = (target_lb, source.upper()).to_interval();
426
427 test_op(test_num, source, expected_dom, delta_expected, update_success,
428 |store, var| var.read(store).shrink_left(target_lb));
429 }
430
431 fn var_shrink_ub_test_one(test_num: u32, source: Domain, target_ub: i32, delta_expected: Vec<FDEvent>, update_success: bool) {
432 let expected_dom = (source.lower(), target_ub).to_interval();
433
434 test_op(test_num, source, expected_dom, delta_expected, update_success,
435 |store, var| var.read(store).shrink_right(target_ub));
436 }
437
438 #[test]
439 fn var_intersection_test() {
440 let dom0_10 = (0,10).to_interval();
441 let dom10_20 = (10,20).to_interval();
442 let dom10_10 = (10,10).to_interval();
443 let dom11_20 = (11,20).to_interval();
444 let dom1_9 = (1,9).to_interval();
445
446 var_intersection_test_one(dom0_10, dom10_20, dom10_10, vec![(0, Assignment), (1, Assignment)], true);
447 var_intersection_test_one(dom0_10, dom1_9, dom1_9, vec![(0, Bound)], true);
448 var_intersection_test_one(dom1_9, dom0_10, dom1_9, vec![(1, Bound)], true);
449 var_intersection_test_one(dom0_10, dom11_20, Interval::empty(), vec![], false);
450 }
451
452 fn var_intersection_test_one(source1: Domain, source2: Domain, target: Domain, delta_expected: Vec<(usize, FDEvent)>, update_success: bool) {
453 test_binary_op(source1, source2, target, delta_expected, update_success,
454 |store, v1, v2| v1.read(store).intersection(&v2.read(store)));
455 }
456}