1
//! Normalising rules for `Sum`
2

            
3
use ApplicationError::RuleNotApplicable;
4
use conjure_cp::{
5
    ast::{Expression as Expr, SymbolTable},
6
    rule_engine::{ApplicationError, ApplicationResult, RuleEffect, register_rule},
7
};
8

            
9
/// Removes sums with a single argument.
10
///
11
/// ```text
12
/// sum([a]) ~> a
13
/// ```
14
#[register_rule("Base", 8800, [Sum])]
15
1231316
fn remove_unit_vector_sum(expr: &Expr, _: &SymbolTable) -> ApplicationResult {
16
1231316
    let Expr::Sum(_, e) = expr else {
17
4339
        return Err(RuleNotApplicable);
18
    };
19

            
20
    // The failure path is only a shape check and must stay O(1) on a wide sum.
21
1226977
    if e.list_len() != Some(1) {
22
1224950
        return Err(RuleNotApplicable);
23
2027
    }
24
2027
    let mut exprs = e.unwrap_list().ok_or(RuleNotApplicable)?;
25
2027
    Ok(RuleEffect::pure(
26
2027
        exprs.pop().expect("singleton length checked above"),
27
2027
    ))
28
1231316
}