1use kernel::*;
16use term::ops::*;
17use propagation::events::*;
18use model::*;
19use concept::*;
20use gcollections::kind::*;
21
22#[derive(Debug)]
23pub struct Sum<VStore>
24{
25 vars: Vec<Var<VStore>>
26}
27
28impl<VStore> Sum<VStore> {
29 pub fn new(vars: Vec<Var<VStore>>) -> Self {
30 Sum {
31 vars: vars
32 }
33 }
34}
35
36impl<VStore> Clone for Sum<VStore> where
37 VStore: Collection
38{
39 fn clone(&self) -> Self {
40 Sum::new(self.vars.iter().map(|v| v.bclone()).collect())
41 }
42}
43
44
45impl<VStore> DisplayStateful<Model> for Sum<VStore>
46{
47 fn display(&self, model: &Model) {
48 print!("sum(");
49 self.vars[0].display(model);
50 let mut i = 1;
51 while i < self.vars.len() {
52 print!(" + ");
53 self.vars[i].display(model);
54 i += 1;
55 }
56 print!(")");
57 }
58}
59
60impl<VStore, Domain, Bound> StoreMonotonicUpdate<VStore> for Sum<VStore> where
61 VStore: VStoreConcept<Item=Domain>,
62 Domain: IntDomain<Item=Bound>,
63 Bound: IntBound
64{
65 fn update(&mut self, store: &mut VStore, value: Domain) -> bool {
66 if self.vars.len() == 1 {
67 self.vars[0].update(store, value)
68 }
69 else {
70 let sum = self.read(store);
71 sum.overlap(&value)
72 }
73 }
74}
75
76impl<VStore, Domain, Bound> StoreRead<VStore> for Sum<VStore> where
77 VStore: VStoreConcept<Item=Domain>,
78 Domain: IntDomain<Item=Bound>,
79 Bound: IntBound
80{
81 fn read(&self, store: &VStore) -> Domain {
82 let mut iter = self.vars.iter();
83 let sum = iter.next().expect("At least one variable in sum.");
84 iter.fold(sum.read(store), |a: Domain, v| a + v.read(store))
85 }
86}
87
88impl<VStore> ViewDependencies<FDEvent> for Sum<VStore>
89{
90 fn dependencies(&self, event: FDEvent) -> Vec<(usize, FDEvent)> {
91 self.vars.iter()
92 .flat_map(|v| v.dependencies(event.clone()))
93 .collect()
94 }
95}