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 DeclarationKind::GivenQuantified(inner) => {
247 writeln!(f, "given {name}: {}", inner.domain())?;
248 }
249
250 DeclarationKind::RecordField(_) => {
251 writeln!(f)?;
253 }
255 }
256 }
257
258 if !self.constraints().is_empty() {
259 writeln!(f, "\nsuch that\n")?;
260 writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
261 }
262
263 if !self.clauses().is_empty() {
264 writeln!(f, "\nclauses:\n")?;
265
266 writeln!(f, "{}", pretty_clauses(self.clauses()))?;
267 }
268 Ok(())
269 }
270}
271
272impl Uniplate for SubModel {
286 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
287 let (expr_tree, expr_ctx) = <Expression as Biplate<SubModel>>::biplate(self.root());
290
291 let symtab_ptr = self.symbols();
292 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<SubModel>>::biplate(&symtab_ptr);
293
294 let tree = Tree::Many(VecDeque::from([expr_tree, symtab_tree]));
295
296 let self2 = self.clone();
297 let ctx = Box::new(move |x| {
298 let Tree::Many(xs) = x else {
299 panic!();
300 };
301
302 let root = expr_ctx(xs[0].clone());
303 let symtab = symtab_ctx(xs[1].clone());
304
305 let mut self3 = self2.clone();
306
307 let Expression::Root(_, _) = root else {
308 bug!("root expression not root");
309 };
310
311 *self3.root_mut_unchecked() = root;
312
313 *self3.symbols_mut() = symtab;
314
315 self3
316 });
317
318 (tree, ctx)
319 }
320}
321
322impl Biplate<Expression> for SubModel {
323 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
324 let symtab_ptr = self.symbols();
326 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<Expression>>::biplate(&symtab_ptr);
327
328 let tree = Tree::Many(VecDeque::from([
329 Tree::One(self.root().clone()),
330 symtab_tree,
331 ]));
332
333 let self2 = self.clone();
334 let ctx = Box::new(move |x| {
335 let Tree::Many(xs) = x else {
336 panic!();
337 };
338
339 let Tree::One(root) = xs[0].clone() else {
340 panic!();
341 };
342
343 let symtab = symtab_ctx(xs[1].clone());
344
345 let mut self3 = self2.clone();
346
347 let Expression::Root(_, _) = root else {
348 bug!("root expression not root");
349 };
350
351 *self3.root_mut_unchecked() = root;
352
353 *self3.symbols_mut() = symtab;
354
355 self3
356 });
357
358 (tree, ctx)
359 }
360}
361
362impl Biplate<SubModel> for SubModel {
363 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
364 (
365 Tree::One(self.clone()),
366 Box::new(move |x| {
367 let Tree::One(x) = x else {
368 panic!();
369 };
370 x
371 }),
372 )
373 }
374}
375
376impl Biplate<Atom> for SubModel {
377 fn biplate(&self) -> (Tree<Atom>, Box<dyn Fn(Tree<Atom>) -> Self>) {
378 let (expression_tree, rebuild_self) = <SubModel as Biplate<Expression>>::biplate(self);
387 let (expression_list, rebuild_expression_tree) = expression_tree.list();
388
389 let (atom_trees, reconstruct_exprs): (VecDeque<_>, VecDeque<_>) = expression_list
391 .iter()
392 .map(|e| <Expression as Biplate<Atom>>::biplate(e))
393 .unzip();
394
395 let tree = Tree::Many(atom_trees);
396 let ctx = Box::new(move |atom_tree: Tree<Atom>| {
397 let Tree::Many(atoms) = atom_tree else {
400 panic!();
401 };
402
403 assert_eq!(
404 atoms.len(),
405 reconstruct_exprs.len(),
406 "the number of children should not change when using Biplate"
407 );
408
409 let expression_list: VecDeque<Expression> = izip!(atoms, &reconstruct_exprs)
410 .map(|(atom, recons)| recons(atom))
411 .collect();
412
413 let expression_tree = rebuild_expression_tree(expression_list);
415
416 rebuild_self(expression_tree)
418 });
419
420 (tree, ctx)
421 }
422}
423
424impl Biplate<Comprehension> for SubModel {
425 fn biplate(
426 &self,
427 ) -> (
428 Tree<Comprehension>,
429 Box<dyn Fn(Tree<Comprehension>) -> Self>,
430 ) {
431 let (f1_tree, f1_ctx) = <_ as Biplate<Comprehension>>::biplate(&self.constraints);
432 let (f2_tree, f2_ctx) =
433 <SymbolTable as Biplate<Comprehension>>::biplate(&self.symbols.borrow());
434
435 let tree = Tree::Many(VecDeque::from([f1_tree, f2_tree]));
436 let self2 = self.clone();
437 let ctx = Box::new(move |x| {
438 let Tree::Many(xs) = x else {
439 panic!();
440 };
441
442 let root = f1_ctx(xs[0].clone());
443 let symtab = f2_ctx(xs[1].clone());
444
445 let mut self3 = self2.clone();
446
447 let Expression::Root(_, _) = &*root else {
448 bug!("root expression not root");
449 };
450
451 *self3.symbols_mut() = symtab;
452 self3.constraints = root;
453
454 self3
455 });
456
457 (tree, ctx)
458 }
459}