1use super::{
2 Atom, CnfClause, DeclarationPtr, Expression, Literal, Metadata, Moo, ReturnType, SymbolTable,
3 SymbolTablePtr, 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::PtrAsInner,
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 parking_lot::{RwLockReadGuard, RwLockWriteGuard};
19use std::hash::Hash;
20use std::{collections::VecDeque, fmt::Display};
21
22#[serde_as]
29#[derive(Clone, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)]
30pub struct SubModel {
31 constraints: Moo<Expression>,
32 #[serde_as(as = "PtrAsInner")]
33 symbols: SymbolTablePtr,
34 cnf_clauses: Vec<CnfClause>, }
36
37impl SubModel {
38 #[doc(hidden)]
43 pub(super) fn new_top_level() -> SubModel {
44 SubModel {
45 constraints: Moo::new(Expression::Root(Metadata::new(), vec![])),
46 symbols: SymbolTablePtr::new(),
47 cnf_clauses: Vec::new(),
48 }
49 }
50
51 pub fn new(parent: SymbolTablePtr) -> SubModel {
55 SubModel {
56 constraints: Moo::new(Expression::Root(Metadata::new(), vec![])),
57 symbols: SymbolTablePtr::with_parent(parent),
58 cnf_clauses: Vec::new(),
59 }
60 }
61
62 pub fn symbols_ptr_unchecked(&self) -> &SymbolTablePtr {
67 &self.symbols
68 }
69
70 pub fn symbols_ptr_unchecked_mut(&mut self) -> &mut SymbolTablePtr {
75 &mut self.symbols
76 }
77
78 pub fn symbols(&self) -> RwLockReadGuard<'_, SymbolTable> {
80 self.symbols.read()
81 }
82
83 pub fn symbols_mut(&mut self) -> RwLockWriteGuard<'_, SymbolTable> {
85 self.symbols.write()
86 }
87
88 pub fn root(&self) -> &Expression {
93 &self.constraints
94 }
95
96 pub fn root_mut_unchecked(&mut self) -> &mut Expression {
101 Moo::make_mut(&mut self.constraints)
102 }
103
104 pub fn replace_root(&mut self, new_root: Expression) -> Expression {
110 let Expression::Root(_, _) = new_root else {
111 tracing::error!(new_root=?new_root,"new_root is not an Expression::root");
112 panic!("new_root is not an Expression::Root");
113 };
114
115 std::mem::replace(self.root_mut_unchecked(), new_root)
117 }
118
119 pub fn constraints(&self) -> &Vec<Expression> {
121 let Expression::Root(_, constraints) = self.constraints.as_ref() else {
122 bug!("The top level expression in a submodel should be Expr::Root");
123 };
124 constraints
125 }
126
127 pub fn clauses(&self) -> &Vec<CnfClause> {
129 &self.cnf_clauses
130 }
131
132 pub fn constraints_mut(&mut self) -> &mut Vec<Expression> {
134 let Expression::Root(_, constraints) = Moo::make_mut(&mut self.constraints) else {
135 bug!("The top level expression in a submodel should be Expr::Root");
136 };
137
138 constraints
139 }
140
141 pub fn clauses_mut(&mut self) -> &mut Vec<CnfClause> {
143 &mut self.cnf_clauses
144 }
145
146 pub fn replace_constraints(&mut self, new_constraints: Vec<Expression>) -> Vec<Expression> {
148 std::mem::replace(self.constraints_mut(), new_constraints)
149 }
150
151 pub fn replace_clauses(&mut self, new_clauses: Vec<CnfClause>) -> Vec<CnfClause> {
153 std::mem::replace(self.clauses_mut(), new_clauses)
154 }
155
156 pub fn add_constraint(&mut self, constraint: Expression) {
158 self.constraints_mut().push(constraint);
159 }
160
161 pub fn add_clause(&mut self, clause: CnfClause) {
163 self.clauses_mut().push(clause);
164 }
165
166 pub fn add_constraints(&mut self, constraints: Vec<Expression>) {
168 self.constraints_mut().extend(constraints);
169 }
170
171 pub fn add_clauses(&mut self, clauses: Vec<CnfClause>) {
173 self.clauses_mut().extend(clauses);
174 }
175
176 pub fn add_symbol(&mut self, decl: DeclarationPtr) -> Option<()> {
179 self.symbols_mut().insert(decl)
180 }
181
182 pub fn into_single_expression(self) -> Expression {
189 let constraints = self.constraints().clone();
190 match constraints.len() {
191 0 => Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(true))),
192 1 => constraints[0].clone(),
193 _ => Expression::And(Metadata::new(), Moo::new(into_matrix_expr![constraints])),
194 }
195 }
196}
197
198impl Typeable for SubModel {
199 fn return_type(&self) -> ReturnType {
200 ReturnType::Bool
201 }
202}
203
204impl Display for SubModel {
205 #[allow(clippy::unwrap_used)] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207 for (name, decl) in self.symbols().clone().into_iter_local() {
208 match &decl.kind() as &DeclarationKind {
209 DeclarationKind::Find(_) => {
210 writeln!(
211 f,
212 "{}",
213 pretty_variable_declaration(&self.symbols(), &name).unwrap()
214 )?;
215 }
216 DeclarationKind::ValueLetting(_) => {
217 writeln!(
218 f,
219 "{}",
220 pretty_value_letting_declaration(&self.symbols(), &name).unwrap()
221 )?;
222 }
223 DeclarationKind::DomainLetting(_) => {
224 writeln!(
225 f,
226 "{}",
227 pretty_domain_letting_declaration(&self.symbols(), &name).unwrap()
228 )?;
229 }
230 DeclarationKind::Given(d) => {
231 writeln!(f, "given {name}: {d}")?;
232 }
233 DeclarationKind::Quantified(inner) => {
234 writeln!(f, "given {name}: {}", inner.domain())?;
235 }
236
237 DeclarationKind::RecordField(_) => {
238 writeln!(f)?;
240 }
242 }
243 }
244
245 if !self.constraints().is_empty() {
246 writeln!(f, "\nsuch that\n")?;
247 writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
248 }
249
250 if !self.clauses().is_empty() {
251 writeln!(f, "\nclauses:\n")?;
252
253 writeln!(f, "{}", pretty_clauses(self.clauses()))?;
254 }
255 Ok(())
256 }
257}
258
259impl Uniplate for SubModel {
273 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
274 let (expr_tree, expr_ctx) = <Expression as Biplate<SubModel>>::biplate(self.root());
277
278 let symtab_ptr = self.symbols();
279 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<SubModel>>::biplate(&symtab_ptr);
280
281 let tree = Tree::Many(VecDeque::from([expr_tree, symtab_tree]));
282
283 let self2 = self.clone();
284 let ctx = Box::new(move |x| {
285 let Tree::Many(xs) = x else {
286 panic!();
287 };
288
289 let root = expr_ctx(xs[0].clone());
290 let symtab = symtab_ctx(xs[1].clone());
291
292 let mut self3 = self2.clone();
293
294 let Expression::Root(_, _) = root else {
295 bug!("root expression not root");
296 };
297
298 *self3.root_mut_unchecked() = root;
299
300 *self3.symbols_mut() = symtab;
301
302 self3
303 });
304
305 (tree, ctx)
306 }
307}
308
309impl Biplate<Expression> for SubModel {
310 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
311 let symtab_ptr = self.symbols();
313 let (symtab_tree, symtab_ctx) = <SymbolTable as Biplate<Expression>>::biplate(&symtab_ptr);
314
315 let tree = Tree::Many(VecDeque::from([
316 Tree::One(self.root().clone()),
317 symtab_tree,
318 ]));
319
320 let self2 = self.clone();
321 let ctx = Box::new(move |x| {
322 let Tree::Many(xs) = x else {
323 panic!();
324 };
325
326 let Tree::One(root) = xs[0].clone() else {
327 panic!();
328 };
329
330 let symtab = symtab_ctx(xs[1].clone());
331
332 let mut self3 = self2.clone();
333
334 let Expression::Root(_, _) = root else {
335 bug!("root expression not root");
336 };
337
338 *self3.root_mut_unchecked() = root;
339
340 *self3.symbols_mut() = symtab;
341
342 self3
343 });
344
345 (tree, ctx)
346 }
347}
348
349impl Biplate<SubModel> for SubModel {
350 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
351 (
352 Tree::One(self.clone()),
353 Box::new(move |x| {
354 let Tree::One(x) = x else {
355 panic!();
356 };
357 x
358 }),
359 )
360 }
361}
362
363impl Biplate<Atom> for SubModel {
364 fn biplate(&self) -> (Tree<Atom>, Box<dyn Fn(Tree<Atom>) -> Self>) {
365 let (expression_tree, rebuild_self) = <SubModel as Biplate<Expression>>::biplate(self);
374 let (expression_list, rebuild_expression_tree) = expression_tree.list();
375
376 let (atom_trees, reconstruct_exprs): (VecDeque<_>, VecDeque<_>) = expression_list
378 .iter()
379 .map(|e| <Expression as Biplate<Atom>>::biplate(e))
380 .unzip();
381
382 let tree = Tree::Many(atom_trees);
383 let ctx = Box::new(move |atom_tree: Tree<Atom>| {
384 let Tree::Many(atoms) = atom_tree else {
387 panic!();
388 };
389
390 assert_eq!(
391 atoms.len(),
392 reconstruct_exprs.len(),
393 "the number of children should not change when using Biplate"
394 );
395
396 let expression_list: VecDeque<Expression> = izip!(atoms, &reconstruct_exprs)
397 .map(|(atom, recons)| recons(atom))
398 .collect();
399
400 let expression_tree = rebuild_expression_tree(expression_list);
402
403 rebuild_self(expression_tree)
405 });
406
407 (tree, ctx)
408 }
409}
410
411impl Biplate<Comprehension> for SubModel {
412 fn biplate(
413 &self,
414 ) -> (
415 Tree<Comprehension>,
416 Box<dyn Fn(Tree<Comprehension>) -> Self>,
417 ) {
418 let (f1_tree, f1_ctx) = <_ as Biplate<Comprehension>>::biplate(&self.constraints);
419 let (f2_tree, f2_ctx) = <SymbolTable as Biplate<Comprehension>>::biplate(&self.symbols());
420
421 let tree = Tree::Many(VecDeque::from([f1_tree, f2_tree]));
422 let self2 = self.clone();
423 let ctx = Box::new(move |x| {
424 let Tree::Many(xs) = x else {
425 panic!();
426 };
427
428 let root = f1_ctx(xs[0].clone());
429 let symtab = f2_ctx(xs[1].clone());
430
431 let mut self3 = self2.clone();
432
433 let Expression::Root(_, _) = &*root else {
434 bug!("root expression not root");
435 };
436
437 *self3.symbols_mut() = symtab;
438 self3.constraints = root;
439
440 self3
441 });
442
443 (tree, ctx)
444 }
445}