conjure_core/ast/
submodel.rs
1use super::{
2 comprehension::Comprehension,
3 declaration::DeclarationKind,
4 pretty::{
5 pretty_domain_letting_declaration, pretty_expressions_as_top_level,
6 pretty_value_letting_declaration, pretty_variable_declaration,
7 },
8 serde::RcRefCellAsInner,
9 Declaration,
10};
11use serde::{Deserialize, Serialize};
12use serde_with::serde_as;
13use uniplate::{Biplate, Tree, Uniplate};
14
15use crate::{bug, metadata::Metadata};
16use std::{
17 cell::{Ref, RefCell, RefMut},
18 collections::VecDeque,
19 fmt::Display,
20 rc::Rc,
21};
22
23use super::{types::Typeable, Expression, ReturnType, SymbolTable};
24
25#[serde_as]
32#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
33pub struct SubModel {
34 constraints: Expression,
35 #[serde_as(as = "RcRefCellAsInner")]
36 symbols: Rc<RefCell<SymbolTable>>,
37}
38
39impl SubModel {
40 #[doc(hidden)]
45 pub(super) fn new_top_level() -> SubModel {
46 SubModel {
47 constraints: Expression::Root(Metadata::new(), vec![]),
48 symbols: Rc::new(RefCell::new(SymbolTable::new())),
49 }
50 }
51
52 pub fn new(parent: Rc<RefCell<SymbolTable>>) -> SubModel {
56 SubModel {
57 constraints: Expression::Root(Metadata::new(), vec![]),
58 symbols: Rc::new(RefCell::new(SymbolTable::with_parent(parent))),
59 }
60 }
61
62 pub fn symbols_ptr_unchecked(&self) -> &Rc<RefCell<SymbolTable>> {
67 &self.symbols
68 }
69
70 pub fn symbols(&self) -> Ref<SymbolTable> {
72 (*self.symbols).borrow()
73 }
74
75 pub fn symbols_mut(&mut self) -> RefMut<SymbolTable> {
77 (*self.symbols).borrow_mut()
78 }
79
80 pub fn root(&self) -> &Expression {
85 &self.constraints
86 }
87
88 fn root_mut_unchecked(&mut self) -> &mut Expression {
93 &mut self.constraints
94 }
95
96 pub fn replace_root(&mut self, new_root: Expression) -> Expression {
102 let Expression::Root(_, _) = new_root else {
103 panic!("new_root is not an Expression::Root");
104 };
105
106 std::mem::replace(self.root_mut_unchecked(), new_root)
108 }
109
110 pub fn constraints(&self) -> &Vec<Expression> {
112 let Expression::Root(_, constraints) = &self.constraints else {
113 bug!("The top level expression in a submodel should be Expr::Root");
114 };
115
116 constraints
117 }
118
119 pub fn constraints_mut(&mut self) -> &mut Vec<Expression> {
121 let Expression::Root(_, constraints) = &mut self.constraints else {
122 bug!("The top level expression in a submodel should be Expr::Root");
123 };
124
125 constraints
126 }
127
128 pub fn replace_constraints(&mut self, new_constraints: Vec<Expression>) -> Vec<Expression> {
130 std::mem::replace(self.constraints_mut(), new_constraints)
131 }
132
133 pub fn add_constraint(&mut self, constraint: Expression) {
135 self.constraints_mut().push(constraint);
136 }
137
138 pub fn add_constraints(&mut self, constraints: Vec<Expression>) {
140 self.constraints_mut().extend(constraints);
141 }
142
143 pub fn add_symbol(&mut self, sym: Declaration) -> Option<()> {
146 self.symbols_mut().insert(Rc::new(sym))
147 }
148}
149
150impl Typeable for SubModel {
151 fn return_type(&self) -> Option<super::ReturnType> {
152 Some(ReturnType::Bool)
153 }
154}
155
156impl Display for SubModel {
157 #[allow(clippy::unwrap_used)] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159 for (name, decl) in self.symbols().clone().into_iter_local() {
160 match decl.kind() {
161 DeclarationKind::DecisionVariable(_) => {
162 writeln!(
163 f,
164 "{}",
165 pretty_variable_declaration(&self.symbols(), &name).unwrap()
166 )?;
167 }
168 DeclarationKind::ValueLetting(_) => {
169 writeln!(
170 f,
171 "{}",
172 pretty_value_letting_declaration(&self.symbols(), &name).unwrap()
173 )?;
174 }
175 DeclarationKind::DomainLetting(_) => {
176 writeln!(
177 f,
178 "{}",
179 pretty_domain_letting_declaration(&self.symbols(), &name).unwrap()
180 )?;
181 }
182 }
183 }
184
185 writeln!(f, "\nsuch that\n")?;
186
187 writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
188
189 Ok(())
190 }
191}
192
193impl Uniplate for SubModel {
207 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
208 let (expr_tree, expr_ctx) = <Expression as Biplate<SubModel>>::biplate(self.root());
211
212 let symtab_ptr = self.symbols();
213 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<SubModel>>::biplate(&symtab_ptr);
214
215 let tree = Tree::Many(VecDeque::from([expr_tree, symtab_tree]));
216
217 let self2 = self.clone();
218 let ctx = Box::new(move |x| {
219 let Tree::Many(xs) = x else {
220 panic!();
221 };
222
223 let root = expr_ctx(xs[0].clone());
224 let symtab = symtab_ctx(xs[1].clone());
225
226 let mut self3 = self2.clone();
227
228 let Expression::Root(_, _) = root else {
229 bug!("root expression not root");
230 };
231
232 *self3.root_mut_unchecked() = root;
233
234 *self3.symbols_mut() = symtab;
235
236 self3
237 });
238
239 (tree, ctx)
240 }
241}
242
243impl Biplate<Expression> for SubModel {
244 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
245 let symtab_ptr = self.symbols();
247 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<Expression>>::biplate(&symtab_ptr);
248
249 let tree = Tree::Many(VecDeque::from([
250 Tree::One(self.root().clone()),
251 symtab_tree,
252 ]));
253
254 let self2 = self.clone();
255 let ctx = Box::new(move |x| {
256 let Tree::Many(xs) = x else {
257 panic!();
258 };
259
260 let Tree::One(root) = xs[0].clone() else {
261 panic!();
262 };
263
264 let symtab = symtab_ctx(xs[1].clone());
265
266 let mut self3 = self2.clone();
267
268 let Expression::Root(_, _) = root else {
269 bug!("root expression not root");
270 };
271
272 *self3.root_mut_unchecked() = root;
273
274 *self3.symbols_mut() = symtab;
275
276 self3
277 });
278
279 (tree, ctx)
280 }
281}
282
283impl Biplate<SubModel> for SubModel {
284 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
285 (
286 Tree::One(self.clone()),
287 Box::new(move |x| {
288 let Tree::One(x) = x else {
289 panic!();
290 };
291 x
292 }),
293 )
294 }
295}
296
297impl Biplate<Comprehension> for SubModel {
298 fn biplate(
299 &self,
300 ) -> (
301 Tree<Comprehension>,
302 Box<dyn Fn(Tree<Comprehension>) -> Self>,
303 ) {
304 let (f1_tree, f1_ctx) = <_ as Biplate<Comprehension>>::biplate(&self.constraints);
305 let (f2_tree, f2_ctx) =
306 <SymbolTable as Biplate<Comprehension>>::biplate(&self.symbols.borrow());
307
308 let tree = Tree::Many(VecDeque::from([f1_tree, f2_tree]));
309 let self2 = self.clone();
310 let ctx = Box::new(move |x| {
311 let Tree::Many(xs) = x else {
312 panic!();
313 };
314
315 let root = f1_ctx(xs[0].clone());
316 let symtab = f2_ctx(xs[1].clone());
317
318 let mut self3 = self2.clone();
319
320 let Expression::Root(_, _) = root else {
321 bug!("root expression not root");
322 };
323
324 *self3.symbols_mut() = symtab;
325 *self3.root_mut_unchecked() = root;
326
327 self3
328 });
329
330 (tree, ctx)
331 }
332}