1
use itertools::Itertools;
2
use std::collections::{HashMap, VecDeque};
3
use std::fmt::{Debug, Display};
4
use std::hash::Hash;
5
use std::sync::{Arc, RwLock};
6

            
7
use crate::ast::Domain;
8
use crate::context::Context;
9
use crate::{bug, into_matrix_expr};
10
use derivative::Derivative;
11
use indexmap::IndexSet;
12
use itertools::izip;
13
use parking_lot::{RwLockReadGuard, RwLockWriteGuard};
14
use serde::{Deserialize, Serialize};
15
use serde_with::serde_as;
16
use uniplate::{Biplate, Tree, Uniplate};
17

            
18
use super::serde::{HasId, ObjId, PtrAsInner};
19
use 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
/// An Essence model.
31
#[serde_as]
32
#[derive(Derivative, Clone, Debug, Serialize, Deserialize)]
33
#[derivative(PartialEq, Eq)]
34
pub 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

            
52
15940
fn default_context() -> Arc<RwLock<Context<'static>>> {
53
15940
    Arc::new(RwLock::new(Context::default()))
54
15940
}
55

            
56
impl Model {
57
1404255
    fn new_empty(symbols: SymbolTablePtr, context: Arc<RwLock<Context<'static>>>) -> Model {
58
1404255
        Model {
59
1404255
            constraints: Moo::new(Expression::Root(Metadata::new(), vec![])),
60
1404255
            instantiation_conditions: Vec::new(),
61
1404255
            symbols,
62
1404255
            sat_decisions: Vec::new(),
63
1404255
            search_order: None,
64
1404255
            dominance: None,
65
1404255
            objective: None,
66
1404255
            context,
67
1404255
        }
68
1404255
    }
69

            
70
    /// Creates a new top-level model from the given context.
71
1391703
    pub fn new(context: Arc<RwLock<Context<'static>>>) -> Model {
72
1391703
        Self::new_empty(SymbolTablePtr::new(), context)
73
1391703
    }
74

            
75
    /// Creates a new model whose symbol table has `parent` as parent scope.
76
12552
    pub fn new_in_parent_scope(parent: SymbolTablePtr) -> Model {
77
12552
        Self::new_empty(SymbolTablePtr::with_parent(parent), default_context())
78
12552
    }
79

            
80
    /// The symbol table for this model as a pointer.
81
5672377
    pub fn symbols_ptr_unchecked(&self) -> &SymbolTablePtr {
82
5672377
        &self.symbols
83
5672377
    }
84

            
85
    /// The symbol table for this model as a mutable pointer.
86
25104
    pub fn symbols_ptr_unchecked_mut(&mut self) -> &mut SymbolTablePtr {
87
25104
        &mut self.symbols
88
25104
    }
89

            
90
    /// The symbol table for this model as a reference.
91
3581485112
    pub fn symbols(&self) -> RwLockReadGuard<'_, SymbolTable> {
92
3581485112
        self.symbols.read()
93
3581485112
    }
94

            
95
    /// The symbol table for this model as a mutable reference.
96
68966171
    pub fn symbols_mut(&mut self) -> RwLockWriteGuard<'_, SymbolTable> {
97
68966171
        self.symbols.write()
98
68966171
    }
99

            
100
    /// The root node of this model.
101
12387241
    pub fn root(&self) -> &Expression {
102
12387241
        &self.constraints
103
12387241
    }
104

            
105
    /// The root node of this model, as a mutable reference.
106
    ///
107
    /// The caller is responsible for ensuring that the root node remains an [`Expression::Root`].
108
4346840
    pub fn root_mut_unchecked(&mut self) -> &mut Expression {
109
4346840
        Moo::make_mut(&mut self.constraints)
110
4346840
    }
111

            
112
    /// Replaces the root node with `new_root`, returning the old root node.
113
4346840
    pub fn replace_root(&mut self, new_root: Expression) -> Expression {
114
4346840
        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
4346840
        std::mem::replace(self.root_mut_unchecked(), new_root)
120
4346840
    }
121

            
122
    /// The top-level constraints in this model.
123
4164648
    pub fn constraints(&self) -> &Vec<Expression> {
124
4164648
        let Expression::Root(_, constraints) = self.constraints.as_ref() else {
125
            bug!("The top level expression in a model should be Expr::Root");
126
        };
127
4164648
        constraints
128
4164648
    }
129

            
130
    /// The SAT encoding decisions in this model.
131
10871746
    pub fn sat_decisions(&self) -> &Vec<SatEncodingDecision> {
132
10871746
        &self.sat_decisions
133
10871746
    }
134

            
135
    /// The top-level constraints in this model as a mutable vector.
136
2699001
    pub fn constraints_mut(&mut self) -> &mut Vec<Expression> {
137
2699001
        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
2699001
        constraints
142
2699001
    }
143

            
144
    /// The SAT encoding decisions in this model as a mutable vector.
145
66189560
    pub fn sat_decisions_mut(&mut self) -> &mut Vec<SatEncodingDecision> {
146
66189560
        &mut self.sat_decisions
147
66189560
    }
148

            
149
    /// Replaces the top-level constraints with `new_constraints`, returning the old ones.
150
133198
    pub fn replace_constraints(&mut self, new_constraints: Vec<Expression>) -> Vec<Expression> {
151
133198
        std::mem::replace(self.constraints_mut(), new_constraints)
152
133198
    }
153

            
154
    /// Replaces the SAT encoding decisions with `new_sat_decisions`, returning the old ones.
155
133198
    pub fn replace_sat_decisions(
156
133198
        &mut self,
157
133198
        new_sat_decisions: Vec<SatEncodingDecision>,
158
133198
    ) -> Vec<SatEncodingDecision> {
159
133198
        std::mem::replace(self.sat_decisions_mut(), new_sat_decisions)
160
133198
    }
161

            
162
    /// Adds a top-level constraint.
163
2557074
    pub fn add_constraint(&mut self, constraint: Expression) {
164
2557074
        self.constraints_mut().push(constraint);
165
2557074
    }
166

            
167
    /// Adds a SAT encoding decision.
168
    pub fn add_sat_decision(&mut self, decision: SatEncodingDecision) {
169
        self.sat_decisions_mut().push(decision);
170
    }
171

            
172
    /// Adds top-level constraints.
173
8671
    pub fn add_constraints(&mut self, constraints: Vec<Expression>) {
174
8671
        self.constraints_mut().extend(constraints);
175
8671
    }
176

            
177
    /// Conditions introduced by top-level `where` statements.
178
    pub fn instantiation_conditions(&self) -> &[Expression] {
179
        &self.instantiation_conditions
180
    }
181

            
182
    /// Adds a condition that must hold after parameter instantiation.
183
232
    pub fn add_instantiation_condition(&mut self, condition: Expression) {
184
232
        self.instantiation_conditions.push(condition);
185
232
    }
186

            
187
    /// Removes and returns all pending instantiation conditions.
188
1215464
    pub fn take_instantiation_conditions(&mut self) -> Vec<Expression> {
189
1215464
        std::mem::take(&mut self.instantiation_conditions)
190
1215464
    }
191

            
192
    /// Adds SAT encoding decisions.
193
64704823
    pub fn add_sat_decisions(&mut self, decisions: Vec<SatEncodingDecision>) {
194
64704823
        self.sat_decisions_mut().extend(decisions);
195
64704823
    }
196

            
197
    /// Adds a new symbol to the symbol table.
198
7
    pub fn add_symbol(&mut self, decl: DeclarationPtr) -> Option<()> {
199
7
        self.symbols_mut().insert(decl)
200
7
    }
201

            
202
    /// Converts the constraints in this model to a single expression suitable for use inside
203
    /// another expression tree.
204
42617
    pub fn into_single_expression(self) -> Expression {
205
42617
        let constraints = self.constraints().clone();
206
42617
        match constraints.len() {
207
            0 => Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(true))),
208
42617
            1 => constraints[0].clone(),
209
            _ => Expression::And(Metadata::new(), Moo::new(into_matrix_expr![constraints])),
210
        }
211
42617
    }
212

            
213
    /// Collects all ObjId values from the model using uniplate traversal.
214
3384
    pub fn collect_stable_id_mapping(&self) -> HashMap<ObjId, ObjId> {
215
3606
        fn visit_symbol_table(symbol_table: SymbolTablePtr, id_list: &mut IndexSet<ObjId>) {
216
3606
            if !id_list.insert(symbol_table.id()) {
217
152
                return;
218
3454
            }
219

            
220
3454
            let table_ref = symbol_table.read();
221
5148
            table_ref.iter_local().for_each(|(_, decl)| {
222
5148
                id_list.insert(decl.id());
223
5148
            });
224
3606
        }
225

            
226
3384
        let mut id_list: IndexSet<ObjId> = IndexSet::new();
227

            
228
3384
        visit_symbol_table(self.symbols_ptr_unchecked().clone(), &mut id_list);
229

            
230
3384
        let mut exprs: VecDeque<Expression> = self.universe_bi();
231
3384
        exprs.extend(self.sat_decisions.universe_bi());
232
3384
        if let Some(dominance) = &self.dominance {
233
            exprs.push_back(dominance.clone());
234
3384
        }
235
3384
        if let Some(objective) = &self.objective {
236
            exprs.push_back(objective.expression.clone());
237
3384
        }
238

            
239
3384
        for symbol_table in Biplate::<SymbolTablePtr>::universe_bi(&exprs) {
240
222
            visit_symbol_table(symbol_table, &mut id_list);
241
        }
242
3384
        for declaration in Biplate::<DeclarationPtr>::universe_bi(&exprs) {
243
9908
            id_list.insert(declaration.id());
244
        }
245

            
246
3384
        let mut id_map = HashMap::new();
247
3384
        for (stable_id, original_id) in id_list.into_iter().enumerate() {
248
8602
            let type_name = original_id.type_name;
249
8602
            id_map.insert(
250
8602
                original_id,
251
8602
                ObjId {
252
8602
                    object_id: stable_id as u32,
253
8602
                    type_name,
254
8602
                },
255
8602
            );
256
        }
257

            
258
3384
        id_map
259
3384
    }
260
}
261

            
262
impl Default for Model {
263
4
    fn default() -> Self {
264
4
        Self::new(default_context())
265
4
    }
266
}
267

            
268
impl Typeable for Model {
269
    fn return_type(&self) -> ReturnType {
270
        ReturnType::Bool
271
    }
272
}
273

            
274
impl 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

            
286
// At time of writing (03/02/2025), the Uniplate derive macro doesn't like the lifetimes inside
287
// context, and we do not yet have a way of ignoring this field.
288
impl 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

            
295
impl Biplate<Expression> for Model {
296
2735067
    fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
297
        let (symtab_tree, symtab_ctx) =
298
2735067
            <SymbolTable as Biplate<Expression>>::biplate(&self.symbols());
299

            
300
2735067
        let dom_tree = match &self.dominance {
301
35931
            Some(expr) => Tree::One(expr.clone()),
302
2699136
            None => Tree::Zero,
303
        };
304

            
305
2735067
        let obj_tree = match &self.objective {
306
42610
            Some(objective) => Tree::One(objective.expression.clone()),
307
2692457
            None => Tree::Zero,
308
        };
309

            
310
2735067
        let instantiation_tree = Tree::Many(
311
2735067
            self.instantiation_conditions
312
2735067
                .iter()
313
2735067
                .cloned()
314
2735067
                .map(Tree::One)
315
2735067
                .collect(),
316
2735067
        );
317

            
318
2735067
        let tree = Tree::Many(VecDeque::from([
319
2735067
            Tree::One(self.root().clone()),
320
2735067
            instantiation_tree,
321
2735067
            symtab_tree,
322
2735067
            dom_tree,
323
2735067
            obj_tree,
324
2735067
        ]));
325

            
326
2735067
        let obj_direction = self.objective.as_ref().map(|objective| objective.direction);
327

            
328
2735067
        let self2 = self.clone();
329
2735067
        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
2735067
        (tree, ctx)
384
2735067
    }
385
}
386

            
387
impl 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

            
421
impl 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

            
457
impl Display for Model {
458
    #[allow(clippy::unwrap_used)]
459
98759
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
460
98759
        let symbols = self.symbols();
461
        // Enum members are introduced by their type declaration, before any value uses them.
462
98759
        for (name, decl) in symbols.iter_local() {
463
506046
            if let DeclarationKind::EnumeratedType(ty) = &*decl.kind() {
464
4
                writeln!(
465
4
                    f,
466
4
                    "letting {name} be new type enum {{{}}}",
467
4
                    ty.variants.iter().join(", ")
468
                )?;
469
506042
            } else if let DeclarationKind::UnnamedType(size) = &decl.kind() as &DeclarationKind {
470
8
                writeln!(f, "letting {name} be new type of size {size}")?;
471
506034
            }
472
        }
473
98759
        for (name, decl) in symbols.iter_local() {
474
506046
            match &decl.kind() as &DeclarationKind {
475
                DeclarationKind::ValueLetting(
476
                    Expression::Atomic(_, Atom::Literal(Literal::EnumVariant(value))),
477
                    _,
478
4
                ) if value.name() == name => {}
479
                DeclarationKind::Find(_) | DeclarationKind::FindAuxiliary(_) => {
480
448634
                    writeln!(
481
448634
                        f,
482
                        "{}",
483
448634
                        pretty_variable_declaration(&symbols, name).unwrap()
484
                    )?;
485
                }
486
                DeclarationKind::ValueLetting(_, _) | DeclarationKind::TemporaryValueLetting(_) => {
487
50890
                    writeln!(
488
50890
                        f,
489
                        "{}",
490
50890
                        pretty_value_letting_declaration(&symbols, name).unwrap()
491
                    )?;
492
                }
493
                DeclarationKind::DomainLetting(_) => {
494
6425
                    writeln!(
495
6425
                        f,
496
                        "{}",
497
6425
                        pretty_domain_letting_declaration(&symbols, name).unwrap()
498
                    )?;
499
                }
500
                DeclarationKind::Given(d) => {
501
81
                    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
12
                DeclarationKind::EnumeratedType(_) | DeclarationKind::UnnamedType(_) => {}
510
            }
511
        }
512

            
513
98759
        if !self.constraints().is_empty() {
514
90122
            writeln!(f, "\nsuch that\n")?;
515
90122
            writeln!(f, "{}", pretty_expressions_as_top_level(self.constraints()))?;
516
8637
        }
517

            
518
98759
        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
98759
        }
526

            
527
98759
        if !self.sat_decisions().is_empty() {
528
3103
            writeln!(f, "\nsat encoding decisions:\n")?;
529
3103
            writeln!(f, "{}", pretty_sat_decisions(self.sat_decisions()))?;
530
95656
        }
531
98759
        Ok(())
532
98759
    }
533
}
534

            
535
/// A model that is de/serializable using `serde`.
536
///
537
/// To turn this into a rewritable model, it needs to be initialised using
538
/// [`initialise`](SerdeModel::initialise).
539
#[serde_as]
540
#[derive(Clone, Debug, Serialize, Deserialize)]
541
pub 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

            
554
impl SerdeModel {
555
    /// Initialises the model for rewriting.
556
    pub fn initialise(mut self, context: Arc<RwLock<Context<'static>>>) -> Option<Model> {
557
        let mut tables: HashMap<ObjId, SymbolTablePtr> = HashMap::new();
558

            
559
        // Root model symbol table is always definitive.
560
        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
        // Some expressions (e.g. abstract comprehensions) contain additional symbol tables.
573
        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

            
623
impl From<Model> for SerdeModel {
624
3384
    fn from(val: Model) -> Self {
625
3384
        SerdeModel {
626
3384
            constraints: val.constraints,
627
3384
            instantiation_conditions: val.instantiation_conditions,
628
3384
            symbols: val.symbols,
629
3384
            sat_decisions: val.sat_decisions,
630
3384
            search_order: val.search_order,
631
3384
            dominance: val.dominance,
632
3384
            objective: val.objective,
633
3384
        }
634
3384
    }
635
}
636

            
637
impl 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

            
653
impl SerdeModel {
654
    /// Collects all ObjId values from the model and maps them to stable sequential IDs.
655
3384
    pub fn collect_stable_id_mapping(&self) -> HashMap<ObjId, ObjId> {
656
3384
        let model = Model {
657
3384
            constraints: self.constraints.clone(),
658
3384
            instantiation_conditions: self.instantiation_conditions.clone(),
659
3384
            symbols: self.symbols.clone(),
660
3384
            sat_decisions: self.sat_decisions.clone(),
661
3384
            search_order: self.search_order.clone(),
662
3384
            dominance: self.dominance.clone(),
663
3384
            objective: self.objective.clone(),
664
3384
            context: default_context(),
665
3384
        };
666
3384
        model.collect_stable_id_mapping()
667
3384
    }
668
}
669

            
670
/// A struct for the information about expressions
671
#[serde_as]
672
#[derive(Serialize)]
673
pub struct ExprInfo {
674
    pretty: String,
675
    domain: Option<Moo<Domain>>,
676
    children: Vec<ExprInfo>,
677
}
678

            
679
impl 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
}