1use std::collections::{HashMap, VecDeque};
2use std::fmt::{Debug, Display};
3use std::hash::Hash;
4use std::sync::{Arc, RwLock};
5
6use crate::ast::Domain;
7use crate::context::Context;
8use crate::{bug, into_matrix_expr};
9use derivative::Derivative;
10use indexmap::IndexSet;
11use itertools::izip;
12use parking_lot::{RwLockReadGuard, RwLockWriteGuard};
13use serde::{Deserialize, Serialize};
14use serde_with::serde_as;
15use uniplate::{Biplate, Tree, Uniplate};
16
17use super::serde::{HasId, ObjId, PtrAsInner};
18use super::{
19 Atom, CnfClause, DeclarationPtr, Expression, Literal, Metadata, Moo, Name, Objective,
20 ReturnType, SymbolTable, SymbolTablePtr, Typeable,
21 comprehension::Comprehension,
22 declaration::DeclarationKind,
23 pretty::{
24 pretty_clauses, pretty_domain_letting_declaration, pretty_expressions_as_top_level,
25 pretty_value_letting_declaration, pretty_variable_declaration,
26 },
27};
28
29#[serde_as]
31#[derive(Derivative, Clone, Debug, Serialize, Deserialize)]
32#[derivative(PartialEq, Eq)]
33pub struct Model {
34 constraints: Moo<Expression>,
35 #[serde(default, skip_serializing_if = "Vec::is_empty")]
36 instantiation_conditions: Vec<Expression>,
37 #[serde_as(as = "PtrAsInner")]
38 symbols: SymbolTablePtr,
39 cnf_clauses: Vec<CnfClause>,
40
41 pub search_order: Option<Vec<Name>>,
42 pub dominance: Option<Expression>,
43 pub objective: Option<Objective>,
44
45 #[serde(skip, default = "default_context")]
46 #[derivative(PartialEq = "ignore")]
47 pub context: Arc<RwLock<Context<'static>>>,
48}
49
50fn default_context() -> Arc<RwLock<Context<'static>>> {
51 Arc::new(RwLock::new(Context::default()))
52}
53
54impl Model {
55 fn new_empty(symbols: SymbolTablePtr, context: Arc<RwLock<Context<'static>>>) -> Model {
56 Model {
57 constraints: Moo::new(Expression::Root(Metadata::new(), vec![])),
58 instantiation_conditions: Vec::new(),
59 symbols,
60 cnf_clauses: Vec::new(),
61 search_order: None,
62 dominance: None,
63 objective: None,
64 context,
65 }
66 }
67
68 pub fn new(context: Arc<RwLock<Context<'static>>>) -> Model {
70 Self::new_empty(SymbolTablePtr::new(), context)
71 }
72
73 pub fn new_in_parent_scope(parent: SymbolTablePtr) -> Model {
75 Self::new_empty(SymbolTablePtr::with_parent(parent), default_context())
76 }
77
78 pub fn symbols_ptr_unchecked(&self) -> &SymbolTablePtr {
80 &self.symbols
81 }
82
83 pub fn symbols_ptr_unchecked_mut(&mut self) -> &mut SymbolTablePtr {
85 &mut self.symbols
86 }
87
88 pub fn symbols(&self) -> RwLockReadGuard<'_, SymbolTable> {
90 self.symbols.read()
91 }
92
93 pub fn symbols_mut(&mut self) -> RwLockWriteGuard<'_, SymbolTable> {
95 self.symbols.write()
96 }
97
98 pub fn root(&self) -> &Expression {
100 &self.constraints
101 }
102
103 pub fn root_mut_unchecked(&mut self) -> &mut Expression {
107 Moo::make_mut(&mut self.constraints)
108 }
109
110 pub fn replace_root(&mut self, new_root: Expression) -> Expression {
112 let Expression::Root(_, _) = new_root else {
113 tracing::error!(new_root=?new_root,"new_root is not an Expression::Root");
114 panic!("new_root is not an Expression::Root");
115 };
116
117 std::mem::replace(self.root_mut_unchecked(), new_root)
118 }
119
120 pub fn constraints(&self) -> &Vec<Expression> {
122 let Expression::Root(_, constraints) = self.constraints.as_ref() else {
123 bug!("The top level expression in a model should be Expr::Root");
124 };
125 constraints
126 }
127
128 pub fn clauses(&self) -> &Vec<CnfClause> {
130 &self.cnf_clauses
131 }
132
133 pub fn constraints_mut(&mut self) -> &mut Vec<Expression> {
135 let Expression::Root(_, constraints) = Moo::make_mut(&mut self.constraints) else {
136 bug!("The top level expression in a model should be Expr::Root");
137 };
138
139 constraints
140 }
141
142 pub fn clauses_mut(&mut self) -> &mut Vec<CnfClause> {
144 &mut self.cnf_clauses
145 }
146
147 pub fn replace_constraints(&mut self, new_constraints: Vec<Expression>) -> Vec<Expression> {
149 std::mem::replace(self.constraints_mut(), new_constraints)
150 }
151
152 pub fn replace_clauses(&mut self, new_clauses: Vec<CnfClause>) -> Vec<CnfClause> {
154 std::mem::replace(self.clauses_mut(), new_clauses)
155 }
156
157 pub fn add_constraint(&mut self, constraint: Expression) {
159 self.constraints_mut().push(constraint);
160 }
161
162 pub fn add_clause(&mut self, clause: CnfClause) {
164 self.clauses_mut().push(clause);
165 }
166
167 pub fn add_constraints(&mut self, constraints: Vec<Expression>) {
169 self.constraints_mut().extend(constraints);
170 }
171
172 pub fn instantiation_conditions(&self) -> &[Expression] {
174 &self.instantiation_conditions
175 }
176
177 pub fn add_instantiation_condition(&mut self, condition: Expression) {
179 self.instantiation_conditions.push(condition);
180 }
181
182 pub fn take_instantiation_conditions(&mut self) -> Vec<Expression> {
184 std::mem::take(&mut self.instantiation_conditions)
185 }
186
187 pub fn add_clauses(&mut self, clauses: Vec<CnfClause>) {
189 self.clauses_mut().extend(clauses);
190 }
191
192 pub fn add_symbol(&mut self, decl: DeclarationPtr) -> Option<()> {
194 self.symbols_mut().insert(decl)
195 }
196
197 pub fn into_single_expression(self) -> Expression {
200 let constraints = self.constraints().clone();
201 match constraints.len() {
202 0 => Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(true))),
203 1 => constraints[0].clone(),
204 _ => Expression::And(Metadata::new(), Moo::new(into_matrix_expr![constraints])),
205 }
206 }
207
208 pub fn collect_stable_id_mapping(&self) -> HashMap<ObjId, ObjId> {
210 fn visit_symbol_table(symbol_table: SymbolTablePtr, id_list: &mut IndexSet<ObjId>) {
211 if !id_list.insert(symbol_table.id()) {
212 return;
213 }
214
215 let table_ref = symbol_table.read();
216 table_ref.iter_local().for_each(|(_, decl)| {
217 id_list.insert(decl.id());
218 });
219 }
220
221 let mut id_list: IndexSet<ObjId> = IndexSet::new();
222
223 visit_symbol_table(self.symbols_ptr_unchecked().clone(), &mut id_list);
224
225 let mut exprs: VecDeque<Expression> = self.universe_bi();
226 if let Some(dominance) = &self.dominance {
227 exprs.push_back(dominance.clone());
228 }
229 if let Some(objective) = &self.objective {
230 exprs.push_back(objective.expression.clone());
231 }
232
233 for symbol_table in Biplate::<SymbolTablePtr>::universe_bi(&exprs) {
234 visit_symbol_table(symbol_table, &mut id_list);
235 }
236 for declaration in Biplate::<DeclarationPtr>::universe_bi(&exprs) {
237 id_list.insert(declaration.id());
238 }
239
240 let mut id_map = HashMap::new();
241 for (stable_id, original_id) in id_list.into_iter().enumerate() {
242 let type_name = original_id.type_name;
243 id_map.insert(
244 original_id,
245 ObjId {
246 object_id: stable_id as u32,
247 type_name,
248 },
249 );
250 }
251
252 id_map
253 }
254}
255
256impl Default for Model {
257 fn default() -> Self {
258 Self::new(default_context())
259 }
260}
261
262impl Typeable for Model {
263 fn return_type(&self) -> ReturnType {
264 ReturnType::Bool
265 }
266}
267
268impl Hash for Model {
269 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
270 self.constraints.hash(state);
271 self.instantiation_conditions.hash(state);
272 self.symbols.hash(state);
273 self.cnf_clauses.hash(state);
274 self.search_order.hash(state);
275 self.dominance.hash(state);
276 self.objective.hash(state);
277 }
278}
279
280impl Uniplate for Model {
283 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
284 let self2 = self.clone();
285 (Tree::Zero, Box::new(move |_| self2.clone()))
286 }
287}
288
289impl Biplate<Expression> for Model {
290 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
291 let (symtab_tree, symtab_ctx) =
292 <SymbolTable as Biplate<Expression>>::biplate(&self.symbols());
293
294 let dom_tree = match &self.dominance {
295 Some(expr) => Tree::One(expr.clone()),
296 None => Tree::Zero,
297 };
298
299 let obj_tree = match &self.objective {
300 Some(objective) => Tree::One(objective.expression.clone()),
301 None => Tree::Zero,
302 };
303
304 let instantiation_tree = Tree::Many(
305 self.instantiation_conditions
306 .iter()
307 .cloned()
308 .map(Tree::One)
309 .collect(),
310 );
311
312 let tree = Tree::Many(VecDeque::from([
313 Tree::One(self.root().clone()),
314 instantiation_tree,
315 symtab_tree,
316 dom_tree,
317 obj_tree,
318 ]));
319
320 let obj_direction = self.objective.as_ref().map(|objective| objective.direction);
321
322 let self2 = self.clone();
323 let ctx = Box::new(move |x| {
324 let Tree::Many(xs) = x else {
325 panic!("Expected a tree with five children");
326 };
327 if xs.len() != 5 {
328 panic!("Expected a tree with five children");
329 }
330
331 let Tree::One(root) = xs[0].clone() else {
332 panic!("Expected root expression tree");
333 };
334
335 let Tree::Many(instantiation_conditions) = xs[1].clone() else {
336 panic!("Expected instantiation-condition expression tree");
337 };
338 let symtab = symtab_ctx(xs[2].clone());
339 let dominance = match xs[3].clone() {
340 Tree::One(expr) => Some(expr),
341 Tree::Zero => None,
342 _ => panic!("Expected dominance tree"),
343 };
344 let objective_expr = match xs[4].clone() {
345 Tree::One(expr) => Some(expr),
346 Tree::Zero => None,
347 _ => panic!("Expected objective tree"),
348 };
349
350 let mut self3 = self2.clone();
351
352 let Expression::Root(_, _) = root else {
353 bug!("root expression not root");
354 };
355
356 *self3.root_mut_unchecked() = root;
357 self3.instantiation_conditions = instantiation_conditions
358 .into_iter()
359 .map(|tree| match tree {
360 Tree::One(expr) => expr,
361 _ => panic!("Expected instantiation condition expression"),
362 })
363 .collect();
364 *self3.symbols_mut() = symtab;
365 self3.dominance = dominance;
366 self3.objective = match (obj_direction, objective_expr) {
367 (Some(direction), Some(expression)) => Some(Objective {
368 direction,
369 expression,
370 }),
371 _ => None,
372 };
373
374 self3
375 });
376
377 (tree, ctx)
378 }
379}
380
381impl Biplate<Atom> for Model {
382 fn biplate(&self) -> (Tree<Atom>, Box<dyn Fn(Tree<Atom>) -> Self>) {
383 let (expression_tree, rebuild_self) = <Model 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
387 .iter()
388 .map(|e| <Expression as Biplate<Atom>>::biplate(e))
389 .unzip();
390
391 let tree = Tree::Many(atom_trees);
392 let ctx = Box::new(move |atom_tree: Tree<Atom>| {
393 let Tree::Many(atoms) = atom_tree else {
394 panic!();
395 };
396
397 assert_eq!(
398 atoms.len(),
399 reconstruct_exprs.len(),
400 "the number of children should not change when using Biplate"
401 );
402
403 let expression_list: VecDeque<Expression> = izip!(atoms, &reconstruct_exprs)
404 .map(|(atom, recons)| recons(atom))
405 .collect();
406
407 let expression_tree = rebuild_expression_tree(expression_list);
408 rebuild_self(expression_tree)
409 });
410
411 (tree, ctx)
412 }
413}
414
415impl Biplate<Comprehension> for Model {
416 fn biplate(
417 &self,
418 ) -> (
419 Tree<Comprehension>,
420 Box<dyn Fn(Tree<Comprehension>) -> Self>,
421 ) {
422 let (f1_tree, f1_ctx) = <_ as Biplate<Comprehension>>::biplate(&self.constraints);
423 let (f2_tree, f2_ctx) = <SymbolTable as Biplate<Comprehension>>::biplate(&self.symbols());
424
425 let tree = Tree::Many(VecDeque::from([f1_tree, f2_tree]));
426 let self2 = self.clone();
427 let ctx = Box::new(move |x| {
428 let Tree::Many(xs) = x else {
429 panic!();
430 };
431
432 let root = f1_ctx(xs[0].clone());
433 let symtab = f2_ctx(xs[1].clone());
434
435 let mut self3 = self2.clone();
436
437 let Expression::Root(_, _) = &*root else {
438 bug!("root expression not root");
439 };
440
441 *self3.symbols_mut() = symtab;
442 self3.constraints = root;
443
444 self3
445 });
446
447 (tree, ctx)
448 }
449}
450
451impl Display for Model {
452 #[allow(clippy::unwrap_used)]
453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454 let symbols = self.symbols();
455 for (name, decl) in symbols.iter_local() {
456 match &decl.kind() as &DeclarationKind {
457 DeclarationKind::Find(_) | DeclarationKind::FindAuxiliary(_) => {
458 writeln!(
459 f,
460 "{}",
461 pretty_variable_declaration(&symbols, name).unwrap()
462 )?;
463 }
464 DeclarationKind::ValueLetting(_, _) | DeclarationKind::TemporaryValueLetting(_) => {
465 writeln!(
466 f,
467 "{}",
468 pretty_value_letting_declaration(&symbols, name).unwrap()
469 )?;
470 }
471 DeclarationKind::DomainLetting(_) => {
472 writeln!(
473 f,
474 "{}",
475 pretty_domain_letting_declaration(&symbols, name).unwrap()
476 )?;
477 }
478 DeclarationKind::Given(d) => {
479 writeln!(f, "given {name}: {d}")?;
480 }
481 DeclarationKind::Quantified(inner) => {
482 writeln!(f, "quantified {name}: {}", inner.domain())?;
483 }
484 DeclarationKind::QuantifiedExpr(expr) => {
485 writeln!(f, "quantified expr {name} <- {}", expr)?;
486 }
487 }
488 }
489
490 if !self.constraints().is_empty() {
491 writeln!(f, "\nsuch that\n")?;
492 writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
493 }
494
495 if !self.instantiation_conditions.is_empty() {
496 writeln!(f, "\nwhere\n")?;
497 writeln!(
498 f,
499 "{}",
500 pretty_expressions_as_top_level(&self.instantiation_conditions)
501 )?;
502 }
503
504 if !self.clauses().is_empty() {
505 writeln!(f, "\nclauses:\n")?;
506 writeln!(f, "{}", pretty_clauses(self.clauses()))?;
507 }
508 Ok(())
509 }
510}
511
512#[serde_as]
517#[derive(Clone, Debug, Serialize, Deserialize)]
518pub struct SerdeModel {
519 constraints: Moo<Expression>,
520 #[serde(default, skip_serializing_if = "Vec::is_empty")]
521 instantiation_conditions: Vec<Expression>,
522 #[serde_as(as = "PtrAsInner")]
523 symbols: SymbolTablePtr,
524 cnf_clauses: Vec<CnfClause>,
525 search_order: Option<Vec<Name>>,
526 dominance: Option<Expression>,
527 objective: Option<Objective>,
528}
529
530impl SerdeModel {
531 pub fn initialise(mut self, context: Arc<RwLock<Context<'static>>>) -> Option<Model> {
533 let mut tables: HashMap<ObjId, SymbolTablePtr> = HashMap::new();
534
535 tables.insert(self.symbols.id(), self.symbols.clone());
537
538 let mut exprs: VecDeque<Expression> = self.constraints.universe_bi();
539 exprs.extend(self.instantiation_conditions.clone());
540 if let Some(dominance) = &self.dominance {
541 exprs.push_back(dominance.clone());
542 }
543 if let Some(objective) = &self.objective {
544 exprs.push_back(objective.expression.clone());
545 }
546
547 for table in Biplate::<SymbolTablePtr>::universe_bi(&exprs) {
549 tables.entry(table.id()).or_insert(table);
550 }
551
552 for table in tables.clone().into_values() {
553 let mut table_mut = table.write();
554 let parent_mut = table_mut.parent_mut_unchecked();
555
556 #[allow(clippy::unwrap_used)]
557 if let Some(parent) = parent_mut {
558 let parent_id = parent.id();
559 *parent = tables.get(&parent_id).unwrap().clone();
560 }
561 }
562
563 let mut all_declarations: HashMap<ObjId, DeclarationPtr> = HashMap::new();
564 for table in tables.values() {
565 for (_, decl) in table.read().iter_local() {
566 let id = decl.id();
567 all_declarations.insert(id, decl.clone());
568 }
569 }
570
571 self.constraints = self.constraints.transform_bi(&move |decl: DeclarationPtr| {
572 let id = decl.id();
573 all_declarations
574 .get(&id)
575 .unwrap_or_else(|| {
576 panic!(
577 "A declaration used in the expression tree should exist in the symbol table. The missing declaration has id {id}."
578 )
579 })
580 .clone()
581 });
582
583 Some(Model {
584 constraints: self.constraints,
585 instantiation_conditions: self.instantiation_conditions,
586 symbols: self.symbols,
587 cnf_clauses: self.cnf_clauses,
588 search_order: self.search_order,
589 dominance: self.dominance,
590 objective: self.objective,
591 context,
592 })
593 }
594}
595
596impl From<Model> for SerdeModel {
597 fn from(val: Model) -> Self {
598 SerdeModel {
599 constraints: val.constraints,
600 instantiation_conditions: val.instantiation_conditions,
601 symbols: val.symbols,
602 cnf_clauses: val.cnf_clauses,
603 search_order: val.search_order,
604 dominance: val.dominance,
605 objective: val.objective,
606 }
607 }
608}
609
610impl Display for SerdeModel {
611 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
612 let model = Model {
613 constraints: self.constraints.clone(),
614 instantiation_conditions: self.instantiation_conditions.clone(),
615 symbols: self.symbols.clone(),
616 cnf_clauses: self.cnf_clauses.clone(),
617 search_order: self.search_order.clone(),
618 dominance: self.dominance.clone(),
619 objective: self.objective.clone(),
620 context: default_context(),
621 };
622 std::fmt::Display::fmt(&model, f)
623 }
624}
625
626impl SerdeModel {
627 pub fn collect_stable_id_mapping(&self) -> HashMap<ObjId, ObjId> {
629 let model = Model {
630 constraints: self.constraints.clone(),
631 instantiation_conditions: self.instantiation_conditions.clone(),
632 symbols: self.symbols.clone(),
633 cnf_clauses: self.cnf_clauses.clone(),
634 search_order: self.search_order.clone(),
635 dominance: self.dominance.clone(),
636 objective: self.objective.clone(),
637 context: default_context(),
638 };
639 model.collect_stable_id_mapping()
640 }
641}
642
643#[serde_as]
645#[derive(Serialize)]
646pub struct ExprInfo {
647 pretty: String,
648 domain: Option<Moo<Domain>>,
649 children: Vec<ExprInfo>,
650}
651
652impl ExprInfo {
653 pub fn create(expr: &Expression) -> ExprInfo {
654 let pretty = expr.to_string();
655 let domain = expr.domain_of();
656 let children = expr.children().iter().map(Self::create).collect();
657
658 ExprInfo {
659 pretty,
660 domain,
661 children,
662 }
663 }
664}