pcp/
model.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 concept::*;
16use std::collections::HashMap;
17use std::fmt::Debug;
18
19#[derive(Clone)]
20pub struct Model {
21  pub groups: Vec<(String, usize)>,
22  pub var_names: HashMap<usize, String>
23}
24
25impl Model
26{
27  pub fn new() -> Self {
28    Model {
29      groups: vec![],
30      var_names: HashMap::new()
31    }
32  }
33
34  pub fn open_group(&mut self, name: &str) {
35    self.groups.push((String::from(name), 1));
36  }
37
38  pub fn close_group(&mut self) {
39    self.groups.pop().expect("Cannot close a non-opened group.");
40  }
41
42  pub fn alloc_var<VStore, Domain>(&mut self,
43    vstore: &mut VStore, dom: Domain) -> Var<VStore> where
44   VStore: VStoreConcept<Item=Domain>,
45   Domain: Clone + Debug + 'static
46  {
47    let name = self.make_name();
48    self.alloc_var_with_name(vstore, dom, name)
49  }
50
51  pub fn alloc_var_with_name<VStore, Domain>(&mut self,
52    vstore: &mut VStore, dom: Domain, name: String) -> Var<VStore> where
53   VStore: VStoreConcept<Item=Domain>,
54   Domain: Clone + Debug + 'static
55  {
56    let loc = vstore.alloc(dom);
57    self.register_var(loc.index(), name);
58    Box::new(loc)
59  }
60
61
62  pub fn register_var(&mut self, var: usize, name: String) {
63    self.var_names.insert(var, name);
64  }
65
66  pub fn var_name(&self, idx: usize) -> String {
67    match self.var_names.get(&idx) {
68      Some(name) => name.clone(),
69      None => format!("_{}", idx)
70    }
71  }
72
73  pub fn inc_group(&mut self) {
74    self.groups.last_mut()
75      .expect("Open a group with `open_group` before allocating a variable.").1 += 1;
76  }
77
78  fn make_name(&mut self) -> String {
79    let mut name = String::new();
80    for (g, i) in self.groups.clone() {
81      name.push_str(&format!("{}{}", g, i));
82    }
83    self.inc_group();
84    name
85  }
86
87  pub fn display_global<VStore>(&self, name: &str, args: &Vec<Var<VStore>>) {
88    print!("{}(", name);
89    let mut i = 0;
90    while i < args.len() - 1 {
91      args[i].display(self);
92      print!(", ");
93      i += 1;
94    }
95    args[i].display(self);
96    print!(") (decomposed)");
97  }
98}