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
21744
fn in_set(expr: &Expr, _: &SymbolTable) -> ApplicationResult {
19
21744
    match expr {
20
48
        Expr::In(_, a, b) => {
21
48
            let Expr::Atomic(_, Atom::Literal(Literal::AbstractLiteral(AbstractLiteral::Set(c)))) =
22
48
                b.as_ref()
23
            else {
24
                return Err(RuleNotApplicable);
25
            };
26

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

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