pub fn fold_constants(self) -> Expression {
        match self {
            Expression::Variadic(operator, exprs) => {
                let (consts, mut vars): (Vec<Expression>, Vec<Expression>) = exprs
                    .into_iter()
                    .map(Expression::fold_constants)
                    .partition(|expr| matches!(expr, Expression::Lit(Term::Numeric(_))));
                let initial = match operator {
                    Operator::Add => Expression::integer_expression(0),
                    _ => Expression::integer_expression(1),
                };
                let op_i128 = match operator {
                    Operator::Add => i128::add,
                    _ => i128::mul,
                };
                let op_f64 = match operator {
                    Operator::Add => f64::add,
                    _ => f64::mul,
                };
                let result = consts
                    .into_iter()
                    .fold(initial.clone(), |acc, x| match (acc, x) {
                        (Expression::Lit(Term::Numeric(a)), Expression::Lit(Term::Numeric(b))) => {
                            Expression::Lit(Term::Numeric(Literal::apply(a, b, op_i128, op_f64)))
                        }
                        (acc, _) => acc,
                    });
                if vars.is_empty() {
                    result
                } else if result == initial {
                    if vars.len() == 1 {
                        vars.remove(0)
                    } else {
                        Expression::Variadic(operator, vars)
                    }
                } else if operator == Operator::Mul && result.is_zero() {
                    result
                } else {
                    vars.push(result);
                    Expression::Variadic(operator, vars)
                }
            }
            other => other.apply_on_others(Expression::fold_constants),
        }
    }
//Evaluate constants literals in addition and multiplication nodes.
Evaluate constants literals in addition and multiplication nodes.
Evaluate constants literals in addition and multiplication nodes .
pub fn fold_constants(self) -> Expression {
        match self {
            Expression::Variadic(operator, exprs) => {
                let (consts, mut vars): (Vec<Expression>, Vec<Expression>) = exprs
                    .into_iter()
                    .map(Expression::fold_constants)
                    .partition(|expr| matches!(expr, Expression::Lit(Term::Numeric(_))));
                let initial = match operator {
                    Operator::Add => Expression::integer_expression(0),
                    _ => Expression::integer_expression(1),
                };
                let op_i128 = match operator {
                    Operator::Add => i128::add,
                    _ => i128::mul,
                };
                let op_f64 = match operator {
                    Operator::Add => f64::add,
                    _ => f64::mul,
                };
                let result = consts
                    .into_iter()
                    .fold(initial.clone(), |acc, x| match (acc, x) {
                        (Expression::Lit(Term::Numeric(a)), Expression::Lit(Term::Numeric(b))) => {
                            Expression::Lit(Term::Numeric(Literal::apply(a, b, op_i128, op_f64)))
                        }
                        (acc, _) => acc,
                    });
                if vars.is_empty() {
                    result
                } else if result == initial {
                    if vars.len() == 1 {
                        vars.remove(0)
                    } else {
                        Expression::Variadic(operator, vars)
                    }
                } else if operator == Operator::Mul && result.is_zero() {
                    result
                } else {
                    vars.push(result);
                    Expression::Variadic(operator, vars)
                }
            }
            other => other.apply_on_others(Expression::fold_constants),
        }
    }
pub fn fold_constants ( self ) -> Expression { match self { Expression :: Variadic ( operator , exprs ) => { let ( consts , mut vars ) : ( Vec < Expression > , Vec < Expression > ) = exprs . into_iter ( ) . map ( Expression :: fold_constants ) . partition ( | expr | matches ! ( expr Expression Lit ( Term Numeric ( ) ) ) ) ; let initial = match operator { Operator :: Add => Expression :: integer_expression ( 0 ) , _ => Expression :: integer_expression ( 1 ) , } ; let op_i128 = match operator { Operator :: Add => i128 :: add , _ => i128 :: mul , } ; let op_f64 = match operator { Operator :: Add => f64 :: add , _ => f64 :: mul , } ; let result = consts . into_iter ( ) . fold ( initial . clone ( ) , | acc , x | match ( acc , x ) { ( Expression :: Lit ( Term :: Numeric ( a ) ) , Expression :: Lit ( Term :: Numeric ( b ) ) ) => { Expression :: Lit ( Term :: Numeric ( Literal :: apply ( a , b , op_i128 , op_f64 ) ) ) } ( acc , _ ) => acc , } ) ; if vars . is_empty ( ) { result } else if result == initial { if vars . len ( ) == 1 { vars . remove ( 0 ) } else { Expression :: Variadic ( operator , vars ) } } else if operator == Operator :: Mul && result . is_zero ( ) { result } else { vars . push ( result ) ; Expression :: Variadic ( operator , vars ) } } other => other . apply_on_others ( Expression :: fold_constants ) , } }
Evaluate constants literals in addition and multiplication nodes.
Evaluate constants literals in addition and multiplication nodes .
self
self