1
//! Normalising rules for Lt and Gt.
2
//!
3
//! For Minion, these normalise into Leq and Geq respectively.
4

            
5
use conjure_cp::essence_expr;
6
use conjure_cp::rule_engine::register_rule;
7
use conjure_cp::{
8
    ast::{Expression as Expr, SymbolTable},
9
    rule_engine::{ApplicationError::RuleNotApplicable, ApplicationResult, Reduction},
10
};
11

            
12
/// Converts Lt to Leq
13
///
14
/// Minion only for now, but this could be useful for other solvers too.
15
///
16
/// # Rationale
17
///
18
/// Minion supports Leq directly in some constraints, such as SumLeq, WeightedSumLeq, ...
19
/// This transformation makes Lt work with these constraints too without needing special
20
/// cases in the Minion conversion rules.
21
#[register_rule(("Minion", 8400))]
22
fn lt_to_leq(expr: &Expr, _: &SymbolTable) -> ApplicationResult {
23
    let Expr::Lt(_, lhs, rhs) = expr.clone() else {
24
        return Err(RuleNotApplicable);
25
    };
26

            
27
    // add to rhs so that this is in the correct form for ineq ( x <= y + k)
28
    // todo (gs248) - tests expect a Sum([rhs, -1]) so we generate that; maybe just use a subtraction instead?
29
    Ok(Reduction::pure(essence_expr!(&lhs <= (&rhs + (-1)))))
30
}
31

            
32
/// Converts Gt to Geq
33
///
34
/// Minion only for now, but this could be useful for other solvers too.
35
///
36
/// # Rationale
37
///
38
/// Minion supports Geq directly in some constraints, such as SumGeq, WeightedSumGeq, ...
39
/// This transformation makes Gt work with these constraints too without needing special
40
/// cases in the Minion conversion rules.
41
#[register_rule(("Minion", 8400))]
42
fn gt_to_geq(expr: &Expr, _: &SymbolTable) -> ApplicationResult {
43
    let Expr::Gt(_, lhs, rhs) = expr.clone() else {
44
        return Err(RuleNotApplicable);
45
    };
46

            
47
    Ok(Reduction::pure(essence_expr!((&lhs + (-1)) >= &rhs)))
48
}