pcp/term/
sum.rs

1// Copyright 2016 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 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}