1use super::{
2 Atom, CnfClause, DeclarationPtr, Expression, Literal, Metadata, Moo, ReturnType, SymbolTable,
3 Typeable,
4 comprehension::Comprehension,
5 declaration::DeclarationKind,
6 pretty::{
7 pretty_clauses, pretty_domain_letting_declaration, pretty_expressions_as_top_level,
8 pretty_value_letting_declaration, pretty_variable_declaration,
9 },
10 serde::RcRefCellAsInner,
11};
12use itertools::izip;
13use serde::{Deserialize, Serialize};
14use serde_with::serde_as;
15use uniplate::{Biplate, Tree, Uniplate};
16
17use crate::{bug, into_matrix_expr};
18use std::hash::{Hash, Hasher};
19use std::{
20 cell::{Ref, RefCell, RefMut},
21 collections::VecDeque,
22 fmt::Display,
23 rc::Rc,
24};
25
26#[serde_as]
33#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
34pub struct SubModel {
35 constraints: Moo<Expression>,
36 #[serde_as(as = "RcRefCellAsInner")]
37 symbols: Rc<RefCell<SymbolTable>>,
38 cnf_clauses: Vec<CnfClause>, }
40
41impl SubModel {
42 #[doc(hidden)]
47 pub(super) fn new_top_level() -> SubModel {
48 SubModel {
49 constraints: Moo::new(Expression::Root(Metadata::new(), vec![])),
50 symbols: Rc::new(RefCell::new(SymbolTable::new())),
51 cnf_clauses: Vec::new(),
52 }
53 }
54
55 pub fn new(parent: Rc<RefCell<SymbolTable>>) -> SubModel {
59 SubModel {
60 constraints: Moo::new(Expression::Root(Metadata::new(), vec![])),
61 symbols: Rc::new(RefCell::new(SymbolTable::with_parent(parent))),
62 cnf_clauses: Vec::new(),
63 }
64 }
65
66 pub fn symbols_ptr_unchecked(&self) -> &Rc<RefCell<SymbolTable>> {
71 &self.symbols
72 }
73
74 pub fn symbols_ptr_unchecked_mut(&mut self) -> &mut Rc<RefCell<SymbolTable>> {
79 &mut self.symbols
80 }
81
82 pub fn symbols(&self) -> Ref<'_, SymbolTable> {
84 (*self.symbols).borrow()
85 }
86
87 pub fn symbols_mut(&mut self) -> RefMut<'_, SymbolTable> {
89 (*self.symbols).borrow_mut()
90 }
91
92 pub fn root(&self) -> &Expression {
97 &self.constraints
98 }
99
100 pub fn root_mut_unchecked(&mut self) -> &mut Expression {
105 Moo::make_mut(&mut self.constraints)
106 }
107
108 pub fn replace_root(&mut self, new_root: Expression) -> Expression {
114 let Expression::Root(_, _) = new_root else {
115 tracing::error!(new_root=?new_root,"new_root is not an Expression::root");
116 panic!("new_root is not an Expression::Root");
117 };
118
119 std::mem::replace(self.root_mut_unchecked(), new_root)
121 }
122
123 pub fn constraints(&self) -> &Vec<Expression> {
125 let Expression::Root(_, constraints) = self.constraints.as_ref() else {
126 bug!("The top level expression in a submodel should be Expr::Root");
127 };
128
129 constraints
130 }
131
132 pub fn clauses(&self) -> &Vec<CnfClause> {
134 &self.cnf_clauses
135 }
136
137 pub fn constraints_mut(&mut self) -> &mut Vec<Expression> {
139 let Expression::Root(_, constraints) = Moo::make_mut(&mut self.constraints) else {
140 bug!("The top level expression in a submodel should be Expr::Root");
141 };
142
143 constraints
144 }
145
146 pub fn clauses_mut(&mut self) -> &mut Vec<CnfClause> {
148 &mut self.cnf_clauses
149 }
150
151 pub fn replace_constraints(&mut self, new_constraints: Vec<Expression>) -> Vec<Expression> {
153 std::mem::replace(self.constraints_mut(), new_constraints)
154 }
155
156 pub fn replace_clauses(&mut self, new_clauses: Vec<CnfClause>) -> Vec<CnfClause> {
158 std::mem::replace(self.clauses_mut(), new_clauses)
159 }
160
161 pub fn add_constraint(&mut self, constraint: Expression) {
163 self.constraints_mut().push(constraint);
164 }
165
166 pub fn add_clause(&mut self, clause: CnfClause) {
168 self.clauses_mut().push(clause);
169 }
170
171 pub fn add_constraints(&mut self, constraints: Vec<Expression>) {
173 self.constraints_mut().extend(constraints);
174 }
175
176 pub fn add_clauses(&mut self, clauses: Vec<CnfClause>) {
178 self.clauses_mut().extend(clauses);
179 }
180
181 pub fn add_symbol(&mut self, decl: DeclarationPtr) -> Option<()> {
184 self.symbols_mut().insert(decl)
185 }
186
187 pub fn into_single_expression(self) -> Expression {
194 let constraints = self.constraints().clone();
195 match constraints.len() {
196 0 => Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(true))),
197 1 => constraints[0].clone(),
198 _ => Expression::And(Metadata::new(), Moo::new(into_matrix_expr![constraints])),
199 }
200 }
201}
202
203impl Typeable for SubModel {
204 fn return_type(&self) -> ReturnType {
205 ReturnType::Bool
206 }
207}
208
209impl Hash for SubModel {
210 fn hash<H: Hasher>(&self, state: &mut H) {
211 self.symbols.borrow().hash(state);
212 self.constraints.hash(state);
213 self.cnf_clauses.hash(state);
214 }
215}
216
217impl Display for SubModel {
218 #[allow(clippy::unwrap_used)] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 for (name, decl) in self.symbols().clone().into_iter_local() {
221 match &decl.kind() as &DeclarationKind {
222 DeclarationKind::DecisionVariable(_) => {
223 writeln!(
224 f,
225 "{}",
226 pretty_variable_declaration(&self.symbols(), &name).unwrap()
227 )?;
228 }
229 DeclarationKind::ValueLetting(_) => {
230 writeln!(
231 f,
232 "{}",
233 pretty_value_letting_declaration(&self.symbols(), &name).unwrap()
234 )?;
235 }
236 DeclarationKind::DomainLetting(_) => {
237 writeln!(
238 f,
239 "{}",
240 pretty_domain_letting_declaration(&self.symbols(), &name).unwrap()
241 )?;
242 }
243 DeclarationKind::Given(d) => {
244 writeln!(f, "given {name}: {d}")?;
245 }
246
247 DeclarationKind::RecordField(_) => {
248 writeln!(f)?;
250 }
252 }
253 }
254
255 if !self.constraints().is_empty() {
256 writeln!(f, "\nsuch that\n")?;
257 writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
258 }
259
260 if !self.clauses().is_empty() {
261 writeln!(f, "\nclauses:\n")?;
262
263 writeln!(f, "{}", pretty_clauses(self.clauses()))?;
264 }
265 Ok(())
266 }
267}
268
269impl Uniplate for SubModel {
283 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
284 let (expr_tree, expr_ctx) = <Expression as Biplate<SubModel>>::biplate(self.root());
287
288 let symtab_ptr = self.symbols();
289 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<SubModel>>::biplate(&symtab_ptr);
290
291 let tree = Tree::Many(VecDeque::from([expr_tree, symtab_tree]));
292
293 let self2 = self.clone();
294 let ctx = Box::new(move |x| {
295 let Tree::Many(xs) = x else {
296 panic!();
297 };
298
299 let root = expr_ctx(xs[0].clone());
300 let symtab = symtab_ctx(xs[1].clone());
301
302 let mut self3 = self2.clone();
303
304 let Expression::Root(_, _) = root else {
305 bug!("root expression not root");
306 };
307
308 *self3.root_mut_unchecked() = root;
309
310 *self3.symbols_mut() = symtab;
311
312 self3
313 });
314
315 (tree, ctx)
316 }
317}
318
319impl Biplate<Expression> for SubModel {
320 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
321 let symtab_ptr = self.symbols();
323 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<Expression>>::biplate(&symtab_ptr);
324
325 let tree = Tree::Many(VecDeque::from([
326 Tree::One(self.root().clone()),
327 symtab_tree,
328 ]));
329
330 let self2 = self.clone();
331 let ctx = Box::new(move |x| {
332 let Tree::Many(xs) = x else {
333 panic!();
334 };
335
336 let Tree::One(root) = xs[0].clone() else {
337 panic!();
338 };
339
340 let symtab = symtab_ctx(xs[1].clone());
341
342 let mut self3 = self2.clone();
343
344 let Expression::Root(_, _) = root else {
345 bug!("root expression not root");
346 };
347
348 *self3.root_mut_unchecked() = root;
349
350 *self3.symbols_mut() = symtab;
351
352 self3
353 });
354
355 (tree, ctx)
356 }
357}
358
359impl Biplate<SubModel> for SubModel {
360 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
361 (
362 Tree::One(self.clone()),
363 Box::new(move |x| {
364 let Tree::One(x) = x else {
365 panic!();
366 };
367 x
368 }),
369 )
370 }
371}
372
373impl Biplate<Atom> for SubModel {
374 fn biplate(&self) -> (Tree<Atom>, Box<dyn Fn(Tree<Atom>) -> Self>) {
375 let (expression_tree, rebuild_self) = <SubModel as Biplate<Expression>>::biplate(self);
384 let (expression_list, rebuild_expression_tree) = expression_tree.list();
385
386 let (atom_trees, reconstruct_exprs): (VecDeque<_>, VecDeque<_>) = expression_list
388 .iter()
389 .map(|e| <Expression as Biplate<Atom>>::biplate(e))
390 .unzip();
391
392 let tree = Tree::Many(atom_trees);
393 let ctx = Box::new(move |atom_tree: Tree<Atom>| {
394 let Tree::Many(atoms) = atom_tree else {
397 panic!();
398 };
399
400 assert_eq!(
401 atoms.len(),
402 reconstruct_exprs.len(),
403 "the number of children should not change when using Biplate"
404 );
405
406 let expression_list: VecDeque<Expression> = izip!(atoms, &reconstruct_exprs)
407 .map(|(atom, recons)| recons(atom))
408 .collect();
409
410 let expression_tree = rebuild_expression_tree(expression_list);
412
413 rebuild_self(expression_tree)
415 });
416
417 (tree, ctx)
418 }
419}
420
421impl Biplate<Comprehension> for SubModel {
422 fn biplate(
423 &self,
424 ) -> (
425 Tree<Comprehension>,
426 Box<dyn Fn(Tree<Comprehension>) -> Self>,
427 ) {
428 let (f1_tree, f1_ctx) = <_ as Biplate<Comprehension>>::biplate(&self.constraints);
429 let (f2_tree, f2_ctx) =
430 <SymbolTable as Biplate<Comprehension>>::biplate(&self.symbols.borrow());
431
432 let tree = Tree::Many(VecDeque::from([f1_tree, f2_tree]));
433 let self2 = self.clone();
434 let ctx = Box::new(move |x| {
435 let Tree::Many(xs) = x else {
436 panic!();
437 };
438
439 let root = f1_ctx(xs[0].clone());
440 let symtab = f2_ctx(xs[1].clone());
441
442 let mut self3 = self2.clone();
443
444 let Expression::Root(_, _) = &*root else {
445 bug!("root expression not root");
446 };
447
448 *self3.symbols_mut() = symtab;
449 self3.constraints = root;
450
451 self3
452 });
453
454 (tree, ctx)
455 }
456}