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

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

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