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