smt_lang/problem/
function.rs1use super::*;
2use crate::parser::Position;
3
4#[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#[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 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 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 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
89impl WithPosition for Function {
92 fn position(&self) -> &Option<Position> {
93 &self.position
94 }
95}
96
97impl 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
113impl 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
139impl 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
162impl 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}