smt_lang/problem/
function.rs

1use super::*;
2use crate::parser::Position;
3
4//------------------------- Id -------------------------
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
7pub struct FunctionId(pub usize);
8
9impl Id for FunctionId {
10    fn empty() -> Self {
11        Self(0)
12    }
13}
14
15//------------------------- Function -------------------------
16
17#[derive(Clone)]
18pub struct Function {
19    id: FunctionId,
20    name: String,
21    parameters: Vec<Parameter>,
22    typ: Type,
23    expr: Option<Expr>,
24    position: Option<Position>,
25}
26
27impl Function {
28    pub fn new<S: Into<String>>(
29        name: S,
30        typ: Type,
31        expr: Option<Expr>,
32        position: Option<Position>,
33    ) -> Self {
34        let id = FunctionId::empty();
35        let name = name.into();
36        Self {
37            id,
38            name,
39            parameters: vec![],
40            typ,
41            expr,
42            position,
43        }
44    }
45
46    //---------- Parameter ----------
47
48    pub fn add_parameter(&mut self, parameter: Parameter) {
49        self.parameters.push(parameter);
50    }
51
52    pub fn parameters(&self) -> &Vec<Parameter> {
53        &self.parameters
54    }
55
56    pub fn parameters_type(&self) -> Vec<Type> {
57        self.parameters.iter().map(|p| p.typ().clone()).collect()
58    }
59
60    //---------- Duplicate ----------
61
62    pub fn duplicate(&self) -> Result<(), Error> {
63        for i in 0..self.parameters.len() - 1 {
64            let x = &self.parameters[i];
65            for j in i + 1..self.parameters.len() {
66                let y = &self.parameters[j];
67                if x.name() == y.name() {
68                    return Err(Error::Duplicate {
69                        name: x.name().to_string(),
70                        first: x.position().clone(),
71                        second: y.position().clone(),
72                    });
73                }
74            }
75        }
76        Ok(())
77    }
78
79    //---------- Bounded ----------
80
81    pub fn check_bounded(&self, problem: &Problem) -> Result<(), Error> {
82        for p in self.parameters.iter() {
83            p.check_bounded(problem)?;
84        }
85        Ok(())
86    }
87}
88
89//------------------------- Postion -------------------------
90
91impl WithPosition for Function {
92    fn position(&self) -> &Option<Position> {
93        &self.position
94    }
95}
96
97//------------------------- Named -------------------------
98
99impl Named<FunctionId> for Function {
100    fn id(&self) -> FunctionId {
101        self.id
102    }
103
104    fn set_id(&mut self, id: FunctionId) {
105        self.id = id;
106    }
107
108    fn name(&self) -> &str {
109        &self.name
110    }
111}
112
113//------------------------- With Type -------------------------
114
115impl WithType for Function {
116    fn typ(&self) -> &Type {
117        &self.typ
118    }
119
120    fn set_type(&mut self, typ: Type) {
121        self.typ = typ;
122    }
123
124    fn resolve_type_children(&mut self, entries: &TypeEntries) -> Result<(), Error> {
125        for p in self.parameters.iter_mut() {
126            p.resolve_type(entries)?;
127        }
128        Ok(())
129    }
130
131    fn check_interval_children(&self, problem: &Problem) -> Result<(), Error> {
132        for p in self.parameters.iter() {
133            p.check_interval(problem)?;
134        }
135        Ok(())
136    }
137}
138
139//------------------------- With Expr -------------------------
140
141impl WithExpr for Function {
142    fn expr(&self) -> &Option<Expr> {
143        &self.expr
144    }
145
146    fn set_expr(&mut self, expr: Option<Expr>) {
147        self.expr = expr;
148    }
149
150    fn entries(&self) -> Entries {
151        let mut v = Vec::new();
152        for p in self.parameters.iter() {
153            v.push(Entry::new(
154                p.name().to_string(),
155                EntryType::Parameter(p.clone()),
156            ));
157        }
158        Entries::new(v)
159    }
160}
161
162//------------------------- ToLang -------------------------
163
164impl ToLang for Function {
165    fn to_lang(&self, problem: &Problem) -> String {
166        let mut s = format!("let {}(", self.name());
167        if !self.parameters.is_empty() {
168            s.push_str(&format!(
169                "{}",
170                self.parameters.first().unwrap().to_lang(problem)
171            ));
172            for p in self.parameters[1..].iter() {
173                s.push_str(&format!(", {}", p.to_lang(problem)));
174            }
175        }
176        s.push_str(&format!("): {}", self.typ.to_lang(problem)));
177        if let Some(e) = &self.expr {
178            s.push_str(&format!(" = {}", e.to_lang(problem)));
179        }
180        s
181    }
182}