public static Expression Add(params Expression[] terms)
        {
            TypeInference type = new TypeInference(terms);

            return(type.CastToMaxNumeric()
                   .Where(x => !Elementary.IsConstantZero(x))
                   .Reduce(Expression.Add, Zero()));
        }
        public static Expression Negate(Expression term)
        {
            if (Elementary.IsConstantZero(term))
            {
                return(Arithmeric.Zero());
            }

            if (term.NodeType == ExpressionType.Negate)
            {
                UnaryExpression unary = (UnaryExpression)term;
                return(unary.Operand);
            }

            return(Expression.Negate(term));
        }
        public static Expression Subtract(Expression a, Expression b)
        {
            if (Elementary.IsConstantZero(a))
            {
                return(Negate(b));
            }

            if (Elementary.IsConstantZero(b))
            {
                return(a);
            }

            TypeInference     type        = new TypeInference(a, b);
            List <Expression> expressions = type.CastToMaxNumericList();

            return(Expression.Subtract(expressions[0], expressions[1]));
        }
        public static Expression Divide(Expression a, Expression b)
        {
            if (Elementary.IsConstantZero(a))
            {
                return(Arithmeric.Zero());
            }

            if (Elementary.IsConstantOne(b))
            {
                return(a);
            }

            TypeInference     type        = new TypeInference(a, b);
            List <Expression> expressions = type.CastToMaxNumericList();

            return(Expression.Divide(expressions[0], expressions[1]));
        }