conjure_cp_core/rule_engine/
rewrite_morph.rs

1use itertools::Itertools;
2use tree_morph::{
3    helpers::select_panic,
4    prelude::{morph, select_first},
5};
6
7use crate::{
8    Model,
9    ast::{Expression, SymbolTable},
10    bug,
11};
12
13use super::{RuleSet, get_rules_grouped};
14
15/// Call the "optimized", tree-morph rewriter.
16pub fn rewrite_morph<'a>(
17    mut model: Model,
18    rule_sets: &Vec<&'a RuleSet<'a>>,
19    prop_multiple_equally_applicable: bool,
20) -> Model {
21    let submodel = model.as_submodel_mut();
22    let rules_grouped = get_rules_grouped(rule_sets)
23        .unwrap_or_else(|_| bug!("get_rule_priorities() failed!"))
24        .into_iter()
25        .map(|(_, rule)| rule.into_iter().map(|f| f.rule).collect_vec())
26        .collect_vec();
27    let selector = if prop_multiple_equally_applicable {
28        select_panic
29    } else {
30        select_first
31    };
32
33    let (expr, symbol_table): (Expression, SymbolTable) = morph(
34        rules_grouped,
35        selector,
36        submodel.root().clone(),
37        submodel.symbols().clone(),
38    );
39
40    *submodel.symbols_mut() = symbol_table;
41    submodel.replace_root(expr);
42    model
43}