smt_lang/problem/
class.rs

1use super::*;
2use crate::parser::Position;
3
4pub enum ClassElement {
5    Attribute(Attribute<ClassId>),
6    Method(Method<ClassId>),
7}
8
9//------------------------- Id -------------------------
10
11#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
12pub struct ClassId(pub usize);
13
14impl Id for ClassId {
15    fn empty() -> Self {
16        Self(0)
17    }
18}
19
20//------------------------- Class -------------------------
21
22#[derive(Clone)]
23pub struct Class {
24    id: ClassId,
25    name: String,
26    typ: Type,
27    extends: Option<Type>,
28    attributes: Vec<Attribute<ClassId>>,
29    methods: Vec<Method<ClassId>>,
30    position: Option<Position>,
31}
32
33impl Class {
34    pub fn new<S: Into<String>>(
35        name: S,
36        extends: Option<Type>,
37        position: Option<Position>,
38    ) -> Self {
39        let id = ClassId::empty();
40        let name = name.into();
41        Self {
42            id,
43            name,
44            typ: Type::Class(id),
45            extends,
46            attributes: vec![],
47            methods: vec![],
48            position,
49        }
50    }
51
52    //---------- Extends ----------
53
54    pub fn extends(&self) -> &Option<Type> {
55        &self.extends
56    }
57
58    pub fn super_class(&self) -> Option<ClassId> {
59        if let Some(t) = &self.extends {
60            match t {
61                Type::Class(c) => Some(*c),
62                _ => None,
63            }
64        } else {
65            None
66        }
67    }
68
69    pub fn direct_sub_classes(&self, problem: &Problem) -> Vec<ClassId> {
70        problem
71            .classes()
72            .iter()
73            .filter(|c| c.super_class() == Some(self.id()))
74            .map(|c| c.id())
75            .collect()
76    }
77
78    pub fn super_classes(&self, problem: &Problem) -> Vec<ClassId> {
79        if let Some(c) = self.super_class() {
80            let mut v = Vec::new();
81            let mut todo = vec![c];
82
83            while !todo.is_empty() {
84                let c = todo.pop().unwrap();
85                if !v.contains(&c) {
86                    v.push(c);
87                    if let Some(s) = problem.get(c).unwrap().super_class() {
88                        todo.push(s);
89                    }
90                }
91            }
92            v
93        } else {
94            vec![]
95        }
96    }
97
98    pub fn sub_classes(&self, problem: &Problem) -> Vec<ClassId> {
99        problem
100            .classes()
101            .iter()
102            .filter(|c| c.super_classes(problem).contains(&self.id()))
103            .map(|c| c.id())
104            .collect()
105    }
106
107    pub fn common_class(&self, problem: &Problem, other: ClassId) -> Option<ClassId> {
108        let mut l1 = self.super_classes(problem);
109        l1.push(self.id());
110        let mut l2 = problem.get(other).unwrap().super_classes(problem);
111        l2.push(other);
112        //
113        let mut res = None;
114        for c in l1.iter() {
115            if !l2.contains(c) {
116                return res;
117            }
118            res = Some(*c);
119        }
120        res
121    }
122
123    //---------- Attribute ----------
124
125    pub fn add_attribute(&mut self, mut attribute: Attribute<ClassId>) -> AttributeId<ClassId> {
126        let id = AttributeId(self.id(), self.attributes.len());
127        attribute.set_id(id);
128        self.attributes.push(attribute);
129        id
130    }
131
132    pub fn get_attribute(&self, id: AttributeId<ClassId>) -> Option<&Attribute<ClassId>> {
133        let AttributeId(structure_id, n) = id;
134        if self.id != structure_id {
135            None
136        } else {
137            self.attributes.get(n)
138        }
139    }
140
141    pub fn attributes(&self) -> &Vec<Attribute<ClassId>> {
142        &self.attributes
143    }
144
145    pub fn all_attributes(&self, problem: &Problem) -> Vec<AttributeId<ClassId>> {
146        let mut classes = self.super_classes(problem).clone();
147        classes.push(self.id());
148        let mut v = Vec::new();
149        for id in classes.iter() {
150            let c = problem.get(*id).unwrap();
151            v.extend(c.attributes().iter().map(|a| a.id()));
152        }
153        v
154    }
155
156    pub fn find_attribute(&self, name: &str) -> Option<&Attribute<ClassId>> {
157        self.attributes.iter().find(|x| x.name() == name)
158    }
159
160    pub fn find_all_attribute(&self, problem: &Problem, name: &str) -> Option<Attribute<ClassId>> {
161        for x in self.attributes.iter() {
162            if x.name() == name {
163                return Some(x.clone());
164            }
165        }
166        for c in self.super_classes(problem).iter() {
167            let c = problem.get(*c).unwrap();
168            for x in c.attributes.iter() {
169                if x.name() == name {
170                    return Some(x.clone());
171                }
172            }
173        }
174        None
175    }
176
177    //---------- Method ----------
178
179    pub fn add_method(&mut self, mut method: Method<ClassId>) -> MethodId<ClassId> {
180        let id = MethodId(self.id(), self.methods.len());
181        method.set_id(id);
182        self.methods.push(method);
183        id
184    }
185
186    pub fn get_method(&self, id: MethodId<ClassId>) -> Option<&Method<ClassId>> {
187        let MethodId(class_id, n) = id;
188        if self.id != class_id {
189            None
190        } else {
191            self.methods.get(n)
192        }
193    }
194
195    pub fn methods(&self) -> &Vec<Method<ClassId>> {
196        &self.methods
197    }
198
199    pub fn all_methods(&self, problem: &Problem) -> Vec<MethodId<ClassId>> {
200        let mut classes = self.super_classes(problem).clone();
201        classes.push(self.id());
202        let mut v = Vec::new();
203        for id in classes.iter() {
204            let c = problem.get(*id).unwrap();
205            v.extend(c.methods().iter().map(|a| a.id()));
206        }
207        v
208    }
209
210    pub fn find_method(&self, name: &str) -> Option<&Method<ClassId>> {
211        self.methods.iter().find(|x| x.name() == name)
212    }
213
214    pub fn find_all_method(&self, problem: &Problem, name: &str) -> Option<Method<ClassId>> {
215        for x in self.methods.iter() {
216            if x.name() == name {
217                return Some(x.clone());
218            }
219        }
220        for c in self.super_classes(problem).iter() {
221            let c = problem.get(*c).unwrap();
222            for x in c.methods.iter() {
223                if x.name() == name {
224                    return Some(x.clone());
225                }
226            }
227        }
228        None
229    }
230
231    //---------- Instance ----------
232
233    pub fn instances(&self, problem: &Problem) -> Vec<InstanceId> {
234        let mut v = Vec::new();
235        for inst in problem.instances().iter() {
236            match inst.typ() {
237                Type::Class(id) => {
238                    if *id == self.id() {
239                        v.push(inst.id());
240                    }
241                }
242                _ => {}
243            }
244        }
245        v
246    }
247
248    pub fn is_empty(&self, problem: &Problem) -> bool {
249        self.all_instances(problem).is_empty()
250    }
251
252    pub fn all_instances(&self, problem: &Problem) -> Vec<InstanceId> {
253        let mut v = self.instances(problem).clone();
254        for c in self.sub_classes(problem).iter() {
255            v.extend(problem.get(*c).unwrap().instances(problem));
256        }
257        v
258    }
259
260    //---------- Duplicate ----------
261
262    pub fn local_naming(&self, problem: &Problem) -> Vec<Naming> {
263        let mut v = vec![];
264        v.extend(
265            self.all_attributes(problem)
266                .iter()
267                .map(|x| problem.get(*x).unwrap().naming()),
268        );
269        v.extend(
270            self.all_methods(problem)
271                .iter()
272                .map(|x| problem.get(*x).unwrap().naming()),
273        );
274        v
275    }
276
277    pub fn duplicate(&self, problem: &Problem) -> Result<(), Error> {
278        let namings = self.local_naming(problem);
279        check_duplicate(namings)?;
280        for x in self.methods.iter() {
281            x.duplicate()?;
282        }
283        Ok(())
284    }
285
286    //---------- Resolve ----------
287
288    pub fn resolve_type_expr(&mut self, entries: &TypeEntries) -> Result<(), Error> {
289        // Attribute
290        for x in self.attributes.iter_mut() {
291            x.resolve_type(entries)?;
292            x.resolve_type_expr(entries)?;
293        }
294        // Method
295        for x in self.methods.iter_mut() {
296            x.resolve_type(entries)?;
297            x.resolve_type_expr(entries)?;
298        }
299        //
300        Ok(())
301    }
302
303    pub fn resolve_expr(&self, problem: &Problem, entries: &Entries) -> Result<Class, Error> {
304        // Attribute
305        let mut attributes = Vec::new();
306        for x in self.attributes.iter() {
307            let a = x.resolve_expr(problem, &entries)?;
308            attributes.push(a);
309        }
310        // Methods
311        let mut methods = Vec::new();
312        for x in self.methods.iter() {
313            let m = x.resolve_expr(problem, &entries)?;
314            methods.push(m);
315        }
316        //
317        Ok(Class {
318            id: self.id,
319            name: self.name.clone(),
320            typ: self.typ.clone(),
321            extends: self.extends.clone(),
322            attributes,
323            methods,
324            position: self.position.clone(),
325        })
326    }
327
328    //---------- Parameter Size ----------
329
330    pub fn check_parameter_size(&self, problem: &Problem) -> Result<(), Error> {
331        for x in self.attributes.iter() {
332            x.check_parameter_size(problem)?;
333        }
334        for x in self.methods.iter() {
335            x.check_parameter_size(problem)?;
336        }
337        Ok(())
338    }
339
340    //---------- Bounded ----------
341
342    pub fn check_bounded(&self, problem: &Problem) -> Result<(), Error> {
343        for x in self.methods.iter() {
344            x.check_bounded(problem)?;
345        }
346        Ok(())
347    }
348
349    //---------- Typing ----------
350
351    pub fn check_type(&self, problem: &Problem) -> Result<(), Error> {
352        for x in self.attributes.iter() {
353            x.check_type(problem)?;
354        }
355        for x in self.methods.iter() {
356            x.check_type(problem)?;
357        }
358        Ok(())
359    }
360
361    pub fn check_cycle(&self, problem: &Problem) -> Result<(), Error> {
362        let classes = self.super_classes(problem);
363        if classes.contains(&self.id()) {
364            Err(Error::Cyclic { id: self.id() })
365        } else {
366            Ok(())
367        }
368    }
369}
370
371//------------------------- Postion -------------------------
372
373impl WithPosition for Class {
374    fn position(&self) -> &Option<Position> {
375        &self.position
376    }
377}
378
379//------------------------- Named -------------------------
380
381impl Named<ClassId> for Class {
382    fn id(&self) -> ClassId {
383        self.id
384    }
385
386    fn set_id(&mut self, id: ClassId) {
387        self.id = id;
388        self.typ = Type::Class(id);
389        for (n, x) in self.attributes.iter_mut().enumerate() {
390            let id = AttributeId(id, n);
391            x.set_id(id);
392        }
393        for (n, x) in self.methods.iter_mut().enumerate() {
394            let id = MethodId(id, n);
395            x.set_id(id);
396        }
397    }
398
399    fn name(&self) -> &str {
400        &self.name
401    }
402}
403
404//------------------------- With Type -------------------------
405
406impl WithType for Class {
407    fn typ(&self) -> &Type {
408        &self.typ
409    }
410
411    fn set_type(&mut self, _: Type) {}
412
413    fn resolve_type_children(&mut self, entries: &TypeEntries) -> Result<(), Error> {
414        if let Some(c) = &self.extends {
415            let c = c.resolve_type(entries)?;
416            self.extends = Some(c);
417        }
418        for x in self.attributes.iter_mut() {
419            x.resolve_type(&entries)?;
420        }
421        for x in self.methods.iter_mut() {
422            x.resolve_type(&entries)?;
423        }
424        Ok(())
425    }
426
427    fn check_interval_children(&self, problem: &Problem) -> Result<(), Error> {
428        for x in self.attributes.iter() {
429            x.check_interval(problem)?;
430        }
431        for x in self.methods.iter() {
432            x.check_interval(problem)?;
433        }
434        Ok(())
435    }
436}
437
438//------------------------- ToLang -------------------------
439
440impl ToLang for Class {
441    fn to_lang(&self, problem: &Problem) -> String {
442        let mut s = format!("class {}", self.name());
443        // Exptends
444        if let Some(c) = &self.extends {
445            s.push_str(&format!(" extends {}", c.to_lang(problem)));
446        }
447        s.push_str(" {\n");
448        // Attribute
449        for x in self.attributes.iter() {
450            s.push_str(&format!("{}\n", &x.to_lang(problem)));
451        }
452        // Method
453        for x in self.methods.iter() {
454            s.push_str(&format!("{}", &x.to_lang(problem)));
455            s.push_str(&format!("// {:?}\n", x.id()));
456        }
457        //
458        s.push_str("}\n");
459        s
460    }
461}
462
463//------------------------- Get From Id -------------------------
464
465impl GetFromId<AttributeId<ClassId>, Attribute<ClassId>> for Class {
466    fn get(&self, id: AttributeId<ClassId>) -> Option<&Attribute<ClassId>> {
467        self.get_attribute(id)
468    }
469}
470
471impl GetFromId<MethodId<ClassId>, Method<ClassId>> for Class {
472    fn get(&self, id: MethodId<ClassId>) -> Option<&Method<ClassId>> {
473        self.get_method(id)
474    }
475}