1
use conjure_cp::ast::Metadata;
2
use conjure_cp::rule_engine::RuleEffect;
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, [In])]
18
688
fn in_set(expr: &Expr, _: &SymbolTable) -> ApplicationResult {
19
688
    match expr {
20
        Expr::In(_, a, b) => {
21
            let Expr::Atomic(_, Atom::Literal(Literal::AbstractLiteral(AbstractLiteral::Set(c)))) =
22
63
                b.as_ref()
23
            else {
24
                return Err(RuleNotApplicable);
25
            };
26

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

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