1use 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}