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 Atom, Declaration, Literal,
10};
11use serde::{Deserialize, Serialize};
12use serde_with::serde_as;
13use uniplate::{Biplate, Tree, Uniplate};
14
15use crate::{bug, into_matrix_expr, 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 pub 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 pub fn into_single_expression(self) -> Expression {
156 let constraints = self.constraints().clone();
157 match constraints.len() {
158 0 => Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(true))),
159 1 => constraints[0].clone(),
160 _ => Expression::And(Metadata::new(), Box::new(into_matrix_expr![constraints])),
161 }
162 }
163}
164
165impl Typeable for SubModel {
166 fn return_type(&self) -> Option<super::ReturnType> {
167 Some(ReturnType::Bool)
168 }
169}
170
171impl Display for SubModel {
172 #[allow(clippy::unwrap_used)] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 for (name, decl) in self.symbols().clone().into_iter_local() {
175 match decl.kind() {
176 DeclarationKind::DecisionVariable(_) => {
177 writeln!(
178 f,
179 "{}",
180 pretty_variable_declaration(&self.symbols(), &name).unwrap()
181 )?;
182 }
183 DeclarationKind::ValueLetting(_) => {
184 writeln!(
185 f,
186 "{}",
187 pretty_value_letting_declaration(&self.symbols(), &name).unwrap()
188 )?;
189 }
190 DeclarationKind::DomainLetting(_) => {
191 writeln!(
192 f,
193 "{}",
194 pretty_domain_letting_declaration(&self.symbols(), &name).unwrap()
195 )?;
196 }
197 DeclarationKind::Given(d) => {
198 writeln!(f, "given {name}: {d}")?;
199 }
200 }
201 }
202
203 writeln!(f, "\nsuch that\n")?;
204
205 writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
206
207 Ok(())
208 }
209}
210
211impl Uniplate for SubModel {
225 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
226 let (expr_tree, expr_ctx) = <Expression as Biplate<SubModel>>::biplate(self.root());
229
230 let symtab_ptr = self.symbols();
231 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<SubModel>>::biplate(&symtab_ptr);
232
233 let tree = Tree::Many(VecDeque::from([expr_tree, symtab_tree]));
234
235 let self2 = self.clone();
236 let ctx = Box::new(move |x| {
237 let Tree::Many(xs) = x else {
238 panic!();
239 };
240
241 let root = expr_ctx(xs[0].clone());
242 let symtab = symtab_ctx(xs[1].clone());
243
244 let mut self3 = self2.clone();
245
246 let Expression::Root(_, _) = root else {
247 bug!("root expression not root");
248 };
249
250 *self3.root_mut_unchecked() = root;
251
252 *self3.symbols_mut() = symtab;
253
254 self3
255 });
256
257 (tree, ctx)
258 }
259}
260
261impl Biplate<Expression> for SubModel {
262 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
263 let symtab_ptr = self.symbols();
265 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<Expression>>::biplate(&symtab_ptr);
266
267 let tree = Tree::Many(VecDeque::from([
268 Tree::One(self.root().clone()),
269 symtab_tree,
270 ]));
271
272 let self2 = self.clone();
273 let ctx = Box::new(move |x| {
274 let Tree::Many(xs) = x else {
275 panic!();
276 };
277
278 let Tree::One(root) = xs[0].clone() else {
279 panic!();
280 };
281
282 let symtab = symtab_ctx(xs[1].clone());
283
284 let mut self3 = self2.clone();
285
286 let Expression::Root(_, _) = root else {
287 bug!("root expression not root");
288 };
289
290 *self3.root_mut_unchecked() = root;
291
292 *self3.symbols_mut() = symtab;
293
294 self3
295 });
296
297 (tree, ctx)
298 }
299}
300
301impl Biplate<Atom> for SubModel {
302 fn biplate(&self) -> (Tree<Atom>, Box<dyn Fn(Tree<Atom>) -> Self>) {
303 let (tree, expr_ctx) = <Expression as Biplate<Atom>>::biplate(&self.constraints);
305
306 let self2 = self.clone();
307 let ctx = Box::new(move |x| {
308 let mut self3 = self2.clone();
309 self3.constraints = expr_ctx(x);
310 self3
311 });
312
313 (tree, ctx)
314 }
315}
316
317impl Biplate<SubModel> for SubModel {
318 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
319 (
320 Tree::One(self.clone()),
321 Box::new(move |x| {
322 let Tree::One(x) = x else {
323 panic!();
324 };
325 x
326 }),
327 )
328 }
329}
330
331impl Biplate<Comprehension> for SubModel {
332 fn biplate(
333 &self,
334 ) -> (
335 Tree<Comprehension>,
336 Box<dyn Fn(Tree<Comprehension>) -> Self>,
337 ) {
338 let (f1_tree, f1_ctx) = <_ as Biplate<Comprehension>>::biplate(&self.constraints);
339 let (f2_tree, f2_ctx) =
340 <SymbolTable as Biplate<Comprehension>>::biplate(&self.symbols.borrow());
341
342 let tree = Tree::Many(VecDeque::from([f1_tree, f2_tree]));
343 let self2 = self.clone();
344 let ctx = Box::new(move |x| {
345 let Tree::Many(xs) = x else {
346 panic!();
347 };
348
349 let root = f1_ctx(xs[0].clone());
350 let symtab = f2_ctx(xs[1].clone());
351
352 let mut self3 = self2.clone();
353
354 let Expression::Root(_, _) = root else {
355 bug!("root expression not root");
356 };
357
358 *self3.symbols_mut() = symtab;
359 *self3.root_mut_unchecked() = root;
360
361 self3
362 });
363
364 (tree, ctx)
365 }
366}