1
use conjure_cp::ast::Metadata;
2
use conjure_cp::rule_engine::Reduction;
3

            
4
use conjure_cp::ast::AbstractLiteral;
5
use conjure_cp::ast::Atom;
6
use conjure_cp::ast::Expression as Expr;
7
use conjure_cp::ast::Literal;
8

            
9
use conjure_cp::ast::SymbolTable;
10
use conjure_cp::rule_engine::{
11
    ApplicationError::RuleNotApplicable, ApplicationResult, register_rule,
12
};
13

            
14
// turns an in expression into a w-inset expression where x is an integer decision variable
15
// and the set is a set of integers like:
16
// x in {1,2,3} => w-inset(x, [1,2,3])
17
#[register_rule(("Minion", 1))]
18
31443
fn in_set(expr: &Expr, _: &SymbolTable) -> ApplicationResult {
19
31443
    match expr {
20
72
        Expr::In(_, a, b) => {
21
72
            let Expr::Atomic(_, Atom::Literal(Literal::AbstractLiteral(AbstractLiteral::Set(c)))) =
22
72
                b.as_ref()
23
            else {
24
                return Err(RuleNotApplicable);
25
            };
26

            
27
72
            let literals = c
28
72
                .iter()
29
72
                .map(i32::try_from)
30
72
                .collect::<Result<Vec<_>, _>>()
31
72
                .map_err(|_| RuleNotApplicable)?;
32

            
33
72
            if let Expr::Atomic(_, a) = a.as_ref() {
34
72
                Ok(Reduction::pure(Expr::MinionWInSet(
35
72
                    Metadata::new(),
36
72
                    a.clone(),
37
72
                    literals,
38
72
                )))
39
            } else {
40
                Err(RuleNotApplicable)
41
            }
42
        }
43
31371
        _ => Err(RuleNotApplicable),
44
    }
45
31443
}