pub fn collect_like_adds(self) -> Expression {
        match self {
            Expression::Variadic(Operator::Add, exprs) => {
                let exprs = exprs
                    .into_iter()
                    .map(Expression::collect_like_adds)
                    .filter_map(|expr| match expr {
                        Expression::Variadic(Operator::Mul, exprs) => {
                            Some(exprs.into_iter().partition(|expr| {
                                matches!(expr, Expression::Lit(Term::Numeric(_)))
                            }))
                        }
                        expr @ Expression::Lit(Term::Numeric(_)) => Some((vec![expr], Vec::new())),
                        _ => None,
                    })
                    .collect::<Vec<(Vec<Expression>, Vec<Expression>)>>();

                let grouped =
                    group_similar_by(exprs, |(_, terms_a), (_, terms_b)| terms_a == terms_b)
                        .into_iter()
                        .map(|vec| {
                            let (coeffs, mut terms) = vec.into_iter().fold(
                                (Vec::new(), Vec::new()),
                                |(mut coeffs_acc, _), (mut coeffs_x, terms_x)| {
                                    coeffs_acc.append(&mut coeffs_x);
                                    (coeffs_acc, terms_x)
                                },
                            );
                            terms.push(coeffs.into_iter().fold(
                                Expression::integer_expression(0),
                                |acc, expr| match (acc, expr) {
                                    (
                                        Expression::Lit(Term::Numeric(a)),
                                        Expression::Lit(Term::Numeric(b)),
                                    ) => Expression::Lit(Term::Numeric(Literal::apply(
                                        a,
                                        b,
                                        i128::add,
                                        f64::add,
                                    ))),
                                    (acc, _) => acc,
                                },
                            ));
                            Expression::Variadic(Operator::Mul, terms)
                        })
                        .collect();

                Expression::Variadic(Operator::Add, grouped)
            }
            other => other.apply_on_others(Expression::collect_like_adds),
        }
    }
//Groups products with the same variables
Groups products with the same variables
Groups products with the same variables
pub fn collect_like_adds(self) -> Expression {
        match self {
            Expression::Variadic(Operator::Add, exprs) => {
                let exprs = exprs
                    .into_iter()
                    .map(Expression::collect_like_adds)
                    .filter_map(|expr| match expr {
                        Expression::Variadic(Operator::Mul, exprs) => {
                            Some(exprs.into_iter().partition(|expr| {
                                matches!(expr, Expression::Lit(Term::Numeric(_)))
                            }))
                        }
                        expr @ Expression::Lit(Term::Numeric(_)) => Some((vec![expr], Vec::new())),
                        _ => None,
                    })
                    .collect::<Vec<(Vec<Expression>, Vec<Expression>)>>();
                let grouped =
                    group_similar_by(exprs, |(_, terms_a), (_, terms_b)| terms_a == terms_b)
                        .into_iter()
                        .map(|vec| {
                            let (coeffs, mut terms) = vec.into_iter().fold(
                                (Vec::new(), Vec::new()),
                                |(mut coeffs_acc, _), (mut coeffs_x, terms_x)| {
                                    coeffs_acc.append(&mut coeffs_x);
                                    (coeffs_acc, terms_x)
                                },
                            );
                            terms.push(coeffs.into_iter().fold(
                                Expression::integer_expression(0),
                                |acc, expr| match (acc, expr) {
                                    (
                                        Expression::Lit(Term::Numeric(a)),
                                        Expression::Lit(Term::Numeric(b)),
                                    ) => Expression::Lit(Term::Numeric(Literal::apply(
                                        a,
                                        b,
                                        i128::add,
                                        f64::add,
                                    ))),
                                    (acc, _) => acc,
                                },
                            ));
                            Expression::Variadic(Operator::Mul, terms)
                        })
                        .collect();
                Expression::Variadic(Operator::Add, grouped)
            }
            other => other.apply_on_others(Expression::collect_like_adds),
        }
    }
pub fn collect_like_adds ( self ) -> Expression { match self { Expression :: Variadic ( Operator :: Add , exprs ) => { let exprs = exprs . into_iter ( ) . map ( Expression :: collect_like_adds ) . filter_map ( | expr | match expr { Expression :: Variadic ( Operator :: Mul , exprs ) => { Some ( exprs . into_iter ( ) . partition ( | expr | { matches ! ( expr Expression Lit ( Term Numeric ( ) ) ) } ) ) } expr @ Expression :: Lit ( Term :: Numeric ( _ ) ) => Some ( ( vec ! [ expr ] , Vec :: new ( ) ) ) , _ => None , } ) . collect :: < Vec < ( Vec < Expression > , Vec < Expression > ) > > ( ) ; let grouped = group_similar_by ( exprs , | ( _ , terms_a ) , ( _ , terms_b ) | terms_a == terms_b ) . into_iter ( ) . map ( | vec | { let ( coeffs , mut terms ) = vec . into_iter ( ) . fold ( ( Vec :: new ( ) , Vec :: new ( ) ) , | ( mut coeffs_acc , _ ) , ( mut coeffs_x , terms_x ) | { coeffs_acc . append ( & mut coeffs_x ) ; ( coeffs_acc , terms_x ) } , ) ; terms . push ( coeffs . into_iter ( ) . fold ( Expression :: integer_expression ( 0 ) , | acc , expr | match ( acc , expr ) { ( Expression :: Lit ( Term :: Numeric ( a ) ) , Expression :: Lit ( Term :: Numeric ( b ) ) , ) => Expression :: Lit ( Term :: Numeric ( Literal :: apply ( a , b , i128 :: add , f64 :: add , ) ) ) , ( acc , _ ) => acc , } , ) ) ; Expression :: Variadic ( Operator :: Mul , terms ) } ) . collect ( ) ; Expression :: Variadic ( Operator :: Add , grouped ) } other => other . apply_on_others ( Expression :: collect_like_adds ) , } }
Groups products with the same variables
Groups products with the same variables
self
self