示例#1
0
        //a/c + b/c = (a+b)/c
        public static ExpressionBase AddFractionWithCommonDenominatorRule(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is a sum.
            VariadicOperatorExpression variadicExpression = expression as VariadicOperatorExpression;
            if (variadicExpression != null && variadicExpression.Type == OperatorType.Add)
            {
                BinaryOperatorExpression binaryOperand;
                List<ExpressionBase> terms = new List<ExpressionBase>();
                ExpressionBase commonDenominator = null;

                //Foreach operand in sum.
                foreach (ExpressionBase operand in variadicExpression)
                {
                    //If operand is a fraction.
                    binaryOperand = operand as BinaryOperatorExpression;
                    if (binaryOperand != null && binaryOperand.Type == OperatorType.Divide)
                    {
                        //If operand is the first fraction in sum
                        if (terms.Count == 0)
                        {
                            //Add numerator to list of numerators.
                            terms.Add(binaryOperand.Left.Clone());

                            //Set commonDenominator to operand's denominator.
                            commonDenominator = binaryOperand.Right.Clone();
                        }
                        else if (commonDenominator == binaryOperand.Right)
                        {
                            //Add fraction's numerator to list if its denominator equals commenDenominator.
                            terms.Add(binaryOperand.Left.Clone());
                        }
                        else
                        {
                            //Return null if an fraction's denominator does not equals commenDenominator.
                            return null;
                        }
                    }
                    else
                    {
                        //Return if operand is not a fraction.
                        return null;
                    }
                }
                if (terms.Count > 1)
                {
                    //Initialize sum of all fractions' numerators.
                    VariadicOperatorExpression SuggestionNumerator = new VariadicOperatorExpression(OperatorType.Add, terms[0], terms[1]);
                    SuggestionNumerator.Add(terms.Skip(2).ToList());

                    //Return fraction with sum of all fractions' numerators and with their common denominator.
                    return new BinaryOperatorExpression(SuggestionNumerator, commonDenominator, OperatorType.Divide);
                }
            }
            return null;
        }
        public List<Identity> GetIdentities(List<ExpressionBase> selection)
        {
            var identities = new List<Identity>();

            if (selection.Count == 0)
            {
                return identities;
            }

            ExpressionBase commonParent = GetCommonParent(selection);
            if (commonParent is VariadicOperatorExpression)
            {
                VariadicOperatorExpression variadicParent = commonParent as VariadicOperatorExpression;

                List<ExpressionBase> operandsLeftOfSelection = new List<ExpressionBase>();
                List<ExpressionBase> operandsRightOfSelection = new List<ExpressionBase>();
                List<ExpressionBase> selectedOperands = new List<ExpressionBase>();

                foreach (ExpressionBase operand in variadicParent)
                {
                    if (operand.Selected == false && operand.GetNodesRecursive().Any((n) => n.Selected == true) == false)
                    {
                        if (selectedOperands.Count == 0)
                        {
                            operandsLeftOfSelection.Add(operand);
                        }
                        else
                        {
                            operandsRightOfSelection.Add(operand);
                        }
                    }
                    else
                    {
                        selectedOperands.Add(operand);
                    }
                }

                VariadicOperatorExpression toBeReplaced = new VariadicOperatorExpression(variadicParent.Type, selectedOperands[0].Clone(), selectedOperands[1].Clone());
                List<ExpressionBase> toBeReplacedSelection = new List<ExpressionBase>();
                foreach (ExpressionBase operand in selectedOperands.Skip(2))
                {
                    toBeReplaced.Add(operand.Clone());
                }

                toBeReplacedSelection = toBeReplaced.GetNodesRecursive().Where((n) => n.Selected == true).ToList();
                foreach (ExpressionRule rule in rules)
                {
                    ExpressionBase suggestion = rule(toBeReplaced, toBeReplacedSelection);
                    if (identities.Select((i) => i.Suggestion).Contains(suggestion) == false && suggestion != commonParent)
                    {
                        if (suggestion != null)
                        {
                            ExpressionBase result;
                            if (variadicParent.Count == selectedOperands.Count)
                            {
                                result = suggestion;
                            }
                            else
                            {
                                VariadicOperatorExpression variadicResult = new VariadicOperatorExpression(variadicParent.Type, new NumericExpression(-1), new NumericExpression(-1));
                                variadicResult.Add(operandsLeftOfSelection.Select((o) => o.Clone()).ToList());
                                variadicResult.Add(WrapInDelimiterIfNeccessary(suggestion.Clone(), variadicResult));
                                variadicResult.Add(operandsRightOfSelection.Select((o) => o.Clone()).ToList());
                                variadicResult.RemoveAt(0);
                                variadicResult.RemoveAt(0);
                                result = variadicResult;
                            }
                            identities.Add(new Identity(suggestion, WrapInDelimiterIfNeccessary(result, commonParent.Parent)));
                        }
                    }
                }
            }
            else
            {
                foreach (ExpressionRule rule in rules)
                {
                    ExpressionBase suggestion = WrapInDelimiterIfNeccessary(rule(commonParent, selection), commonParent.Parent);
                    if (identities.Select((i) => i.Suggestion).Contains(suggestion) == false && suggestion != commonParent)
                    {
                        if (suggestion != null)
                        {
                            identities.Add(new Identity(suggestion, suggestion));
                        }
                    }
                }
            }

            return identities;
        }
        public ExpressionBase Parse(List<Token> postFix)
        {
            var stack = new ExpressionStack();
            ExpressionBase root = null;
            ExpressionBase left = null;
            ExpressionBase right = null;
            foreach (var token in postFix)
            {
                switch (token.Type)
                {
                    case TokenType.Function:
                        root = new FunctionExpression(stack.Pop(), (string)token.Data);
                        stack.Push(root);
                        break;

                    case TokenType.Delimiter:
                        switch (token.Data.ToString())
                        {
                            case "()":
                                root = new DelimiterExpression(stack.Pop());
                                stack.Push(root);
                                break;
                            case "{}":
                                root = stack.Pop();
                                stack.Push(root);
                                break;
                        }

                        break;

                    case TokenType.Number:
					root = new NumericExpression(int.Parse(token.Data.ToString()));
                        stack.Push(root);
                        break;

                    case TokenType.Constant:
                        root = new ConstantExpression((ConstantType)token.Data);
                        stack.Push(root);
                        break;

                    case TokenType.Variable:
                        root = new VariableExpression((string)token.Data);
                        stack.Push(root);
                        break;

                    case TokenType.Operator:
                        switch (token.Data.ToString())
                        {
                            case "~":
                                root = new UnaryMinusExpression(stack.Pop());
                                stack.Push(root);
                                break;

                            case "+":
                                right = stack.Pop();
                                left = stack.Pop();
                                if (left is VariadicOperatorExpression && (left as VariadicOperatorExpression).Type == OperatorType.Add)
                                {
                                    (left as VariadicOperatorExpression).Add(right);
                                    root = left;
                                    stack.Push(root);
                                }
                                else
                                {
                                    root = new VariadicOperatorExpression(OperatorType.Add, left, right);
                                    stack.Push(root);
                                }
                                break;

                            case "-":
                                if (this.TreatMinusAsUnaryMinusInVariadicPlus)
                                {
                                    right = new UnaryMinusExpression(stack.Pop());
                                    left = stack.Pop();
                                    if (left is VariadicOperatorExpression && (left as VariadicOperatorExpression).Type == OperatorType.Add)
                                    {
                                        (left as VariadicOperatorExpression).Add(right);
                                        root = left;
                                        stack.Push(root);
                                    }
                                    else
                                    {
                                        root = new VariadicOperatorExpression(OperatorType.Add, left, right);
                                        stack.Push(root);
                                    }
                                }
                                else // treat it at binary operator
                                {
                                    right = stack.Pop();
                                    left = stack.Pop();
                                    root = new BinaryOperatorExpression(left, right, OperatorType.Subtract);
                                    stack.Push(root);
                                }
                                break;

                            case "*":
                                right = stack.Pop();
                                left = stack.Pop();
                                if (left is VariadicOperatorExpression && (left as VariadicOperatorExpression).Type == OperatorType.Multiply)
                                {
                                    (left as VariadicOperatorExpression).Add(right);
                                    root = left;
                                    stack.Push(root);
                                }
                                else
                                {
                                    root = new VariadicOperatorExpression(OperatorType.Multiply, left, right);
                                    stack.Push(root);
                                }
                                break;

                            case "/":
                                right = stack.Pop();
                                left = stack.Pop();
                                root = new BinaryOperatorExpression(left, right, OperatorType.Divide);
                                stack.Push(root);
                                break;

                            case "^":
                                right = stack.Pop();
                                left = stack.Pop();
                                root = new BinaryOperatorExpression(left, right, OperatorType.Power);
                                stack.Push(root);
                                break;
                        }

                        break;
                }
            }
            return root;
        }
 public override ExpressionBase Clone()
 {
     if (Count < 2)
         throw new InvalidOperationException("Tried to clone invalid VariadicExpression.");
     var expression = new VariadicOperatorExpression(Type, this[0].Clone(), this[1].Clone()) { Selected = Selected };
     foreach (var expr in this.Skip(2))
     {
         expression.Add(expr.Clone());
     }
     return expression;
 }
示例#5
0
 //{a*b}/c = a/c * b/c
 public static ExpressionBase SplittingFractions(ExpressionBase expression, List<ExpressionBase> selection)
 {
     //If expression is a fraction. e.g. {a*b}/c
     BinaryOperatorExpression binaryExpression = expression as BinaryOperatorExpression;
     if (binaryExpression != null && binaryExpression.Type == OperatorType.Divide)
     {
         //If the fraction's numerator is a sum e.g. a*b in fraction {a*b}/c
         VariadicOperatorExpression numerators = binaryExpression.Left.Clone() as VariadicOperatorExpression;
         if (numerators != null && numerators.Type == OperatorType.Add && numerators.Count > 1)
         {
             List<ExpressionBase> fractionList = new List<ExpressionBase>();
             //Foeach operand in the numerator's sum. e.g. a and b in fraction {a*b}/c
             foreach (var i in numerators)
             {
                 //Initialize a fraction with the operand as numerator and add to list. e.g. a/c and b/c
                 fractionList.Add(new BinaryOperatorExpression(i, binaryExpression.Right.Clone(), OperatorType.Divide));
             }
             //Initialize and return the product of all the fractions in the list. e.g. a/c * b/c
             VariadicOperatorExpression suggestion = new VariadicOperatorExpression(OperatorType.Add, fractionList[0], fractionList[1]);
             foreach (var i in fractionList.Skip(2))
             {
                 suggestion.Add(i);
             }
             return suggestion;
         }
     }
     return null;
 }
示例#6
0
 //(a*b)^c = a^c * b^c
 public static ExpressionBase ReverseCommonPowerParenthesisRule(ExpressionBase expression, List<ExpressionBase> selection)
 {
     List<ExpressionBase> itemsInParenthesis = new List<ExpressionBase>();
     VariadicOperatorExpression suggestion;
     //If expression is a power
     var binaryExpression = expression as BinaryOperatorExpression;
     if (binaryExpression != null && binaryExpression.Type == OperatorType.Power)
     {
         var commonparrent = binaryExpression.Right.Clone();
         //If power's base is a parenthesis
         if (binaryExpression.Left is DelimiterExpression)
         {
             var delimiterExpression = binaryExpression.Left as DelimiterExpression;
             //If the parenthesis' content is a product
             if (delimiterExpression.Expression is VariadicOperatorExpression)
             {
                 var variadicExpression = delimiterExpression.Expression.Clone() as VariadicOperatorExpression;
                 if (variadicExpression.Type == OperatorType.Multiply)
                 {
                     //Raise every operand to the power's exponent.
                     foreach (var item in variadicExpression)
                     {
                         itemsInParenthesis.Add(new BinaryOperatorExpression(item, commonparrent, OperatorType.Power));
                     }
                     //Initialize and reutrn product of exponents
                     suggestion = new VariadicOperatorExpression(OperatorType.Multiply, itemsInParenthesis[0].Clone(), itemsInParenthesis[1].Clone());
                     if (itemsInParenthesis.Count > 2)
                     {
                         foreach (var item in itemsInParenthesis.Skip(2))
                         {
                             suggestion.Add(item.Clone());
                         }
                         return suggestion;
                     }
                     else
                     {
                         return suggestion;
                     }
                 }
             }
         }
     }
     return null;
 }
示例#7
0
        //a*b+a*c = (b+c)*a
        //a*b-a*c = (b-c)*a
        public static ExpressionBase ProductParenthesis(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is a sum. e.g. a*b*c - a*b*d
            VariadicOperatorExpression sum = expression as VariadicOperatorExpression;
            if (sum != null && sum.Type == OperatorType.Add)
            {
                List<ExpressionBase> suggestionSum = new List<ExpressionBase>();
                List<ExpressionBase> commonProductOperands = new List<ExpressionBase>();
                //Foreach operand in sum e.g. a*b*c and a*b*d
                foreach (var actualOperand in sum)
                {
                    ExpressionBase operand;
                    bool negative;

                    //If operand is unary minus take its operand and set negative = true. e.g. -a*b*d => operand = a*b*d, negative = true
                    UnaryMinusExpression minus = actualOperand as UnaryMinusExpression;
                    if (minus != null)
                    {
                        operand = minus.Expression;
                        negative = true;
                    }
                    else
                    {
                        operand = actualOperand;
                        negative = false;
                    }
                    List<ExpressionBase> selectedProductOperands = new List<ExpressionBase>() { operand };
                    List<ExpressionBase> nonSelectedProductOperands = new List<ExpressionBase>() { };
                    VariadicOperatorExpression product = operand as VariadicOperatorExpression;
                    //If operand in the sum is a product. e.g. a*b*d
                    if (product != null && product.Type == OperatorType.Multiply)
                    {
                        //Store all selected and nonselected operands in the product.
                        selectedProductOperands = product.Where((o) => (o.Selected == true || o.GetNodesRecursive().Any((n) => n.Selected))).ToList();
                        nonSelectedProductOperands = product.Where((o) => o.Selected == false && o.GetNodesRecursive().Any((n) => n.Selected) == false).ToList();
                    }
                    bool allEqual = true;
                    //Determine if all selected operands of the product are equal and in same order to the commen product operands.
                    if (commonProductOperands.Count == 0 || commonProductOperands.Count == selectedProductOperands.Count)
                    {
                        for (int index = 0; index < commonProductOperands.Count; index++)
                        {
                            if (commonProductOperands[index] != selectedProductOperands[index])
                            {
                                allEqual = false;
                            }
                        }
                    }
                    else
                    {
                        return null;
                    }

                    //If all selected operands in the product are in the common products operands.
                    if (allEqual || commonProductOperands.Count == 0)
                    {
                        commonProductOperands = selectedProductOperands;
                        //If the whole operand of the sum is selected leave 1 or -1 at its placing when factor outside parenthesis.
                        if (nonSelectedProductOperands.Count == 0)
                        {
                            suggestionSum.Add(negative ? ToNumeric(-1) : ToNumeric(1));
                        }
                        else if (nonSelectedProductOperands.Count == 1)
                        {
                            //If one operand of the product is not selected leave it when factorize the rest outside.
                            ExpressionBase clone = nonSelectedProductOperands[0].Clone();
                            suggestionSum.Add(negative ? new UnaryMinusExpression(clone) : clone);
                        }
                        else
                        {
                            //If two or more operands of the product is not selected leave these when factorize the rest outside.
                            VariadicOperatorExpression nonSelectedProduct = new VariadicOperatorExpression(OperatorType.Multiply, nonSelectedProductOperands[0].Clone(), nonSelectedProductOperands[1].Clone());
                            nonSelectedProduct.Add(nonSelectedProductOperands.Skip(2).Select((o) => o.Clone()).ToList());
                            suggestionSum.Add(negative ? (ExpressionBase)new UnaryMinusExpression(nonSelectedProduct) : nonSelectedProduct);
                        }
                    }
                    else
                    {
                        //If two operands in the sum has two different selections return null
                        return null;
                    }
                }
                //Return product where the common product selection is factorized outside a parenthesis. e.g. (c - d)*a*b
                VariadicOperatorExpression sumExpression = new VariadicOperatorExpression(OperatorType.Add, suggestionSum[0], suggestionSum[1]);
                sumExpression.Add(suggestionSum.Skip(2).ToList());
                VariadicOperatorExpression suggestion = new VariadicOperatorExpression(OperatorType.Multiply, sumExpression, new NumericExpression(-1));
                suggestion.Add(commonProductOperands.Select((o) => o.Clone()).ToList());
                suggestion.RemoveAt(1);
                return suggestion;
            }
            return null;
        }
示例#8
0
        // a/b * c/d = {a*c}/{b*d}
        public static ExpressionBase ProductOfFractions(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is product if two or more operands
            VariadicOperatorExpression variadicExpression = expression as VariadicOperatorExpression;
            if (variadicExpression != null && variadicExpression.Type == OperatorType.Multiply && variadicExpression.Count >= 2)
            {
                List<ExpressionBase> listOfNumerators = new List<ExpressionBase>();
                List<ExpressionBase> listOfDenominators = new List<ExpressionBase>();
                //Foreach operand in product
                foreach (ExpressionBase operand in variadicExpression)
                {
                    //If operand is a fraction
                    BinaryOperatorExpression binaryExpression = operand as BinaryOperatorExpression;
                    if(binaryExpression != null && binaryExpression.Type == OperatorType.Divide)
                    {
                        //Add numerator and donimator to list
                        listOfNumerators.Add(binaryExpression.Left.Clone());
                        listOfDenominators.Add(binaryExpression.Right.Clone());
                    }
                    else
                    {
                        //If operands i not a fraction return null
                        return null;
                    }
                }

                //Convert list to product of numerators
                VariadicOperatorExpression suggestionNumerator = new VariadicOperatorExpression(OperatorType.Multiply, listOfNumerators[0], listOfNumerators[1]);
                foreach (var item in listOfNumerators.Skip(2))
                {
                    suggestionNumerator.Add(item);
                }
                //Convert list to product of denominators
                VariadicOperatorExpression suggestionDenominator = new VariadicOperatorExpression(OperatorType.Multiply, listOfDenominators[0], listOfDenominators[1]);
                foreach (var item in listOfDenominators.Skip(2))
                {
                    suggestionDenominator.Add(item);
                }
                //Return fraction with product of numerators and denominators
                return new BinaryOperatorExpression(suggestionNumerator, suggestionDenominator, OperatorType.Divide);
            }
            return null;
        }
示例#9
0
        // a*{b/c} = {a*b}/c
        public static ExpressionBase ProductOfConstantAndFraction(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is a product with to operands
            var variadicExpression = expression as VariadicOperatorExpression;
            if (variadicExpression != null && variadicExpression.Type == OperatorType.Multiply && variadicExpression.Count == 2)
            {
                BinaryOperatorExpression fraction = null;
                ExpressionBase other = null;
                //Find which operand is a fraction
                if ((fraction = variadicExpression[0] as BinaryOperatorExpression) != null && fraction.Type == OperatorType.Divide)
                {
                    other = variadicExpression[1];
                }
                else if ((fraction = variadicExpression[1] as BinaryOperatorExpression) != null && fraction.Type == OperatorType.Divide)
                {
                    other = variadicExpression[0];
                }
                else
                {
                    //Return null of non of the operands is a fraction
                    return null;
                }

                //Multiply numerator with other operand
                VariadicOperatorExpression numerators = new VariadicOperatorExpression(OperatorType.Multiply, fraction.Left.Clone(), other.Clone());

                //Return fraction
                BinaryOperatorExpression suggestion = new BinaryOperatorExpression(numerators.Clone(), fraction.Right.Clone(), OperatorType.Divide);
                return suggestion;
            }
            return null;
        }
示例#10
0
 //a/b = a*b^-1
 public static ExpressionBase FractionToProductRule(ExpressionBase expression, List<ExpressionBase> selection)
 {
     //If expression a fraction. e.g. a/b
     BinaryExpression fraction = expression as BinaryExpression;
     if (fraction != null && fraction.Type == OperatorType.Divide)
     {
         //Convert denominator to power of -1. b => b^-1
         ExpressionBase exponent = new BinaryOperatorExpression(
             fraction.Right.Clone(),
             new UnaryMinusExpression(new NumericExpression(1)),
             OperatorType.Power
         );
         //Return product of numerator and power. a*b^-1
         ExpressionBase suggestion = new VariadicOperatorExpression(
             OperatorType.Multiply,
             fraction.Left.Clone(),
             exponent
         );
         return suggestion;
     }
     else
     {
         return null;
     }
 }
示例#11
0
 //-a = (-1)*a
 public static ExpressionBase FactorizeUnaryMinus(ExpressionBase expression, List<ExpressionBase> selection)
 {
     //If expression is unary minus
     var unaryMinusExpression = expression as UnaryMinusExpression;
     if (unaryMinusExpression != null)
     {
         //Return product of operand and (-1)
         var numericExpression = new NumericExpression(1);
         var suggestion = new VariadicOperatorExpression(OperatorType.Multiply, new UnaryMinusExpression(numericExpression), unaryMinusExpression.Expression.Clone());
         return suggestion;
     }
     return null;
 }
示例#12
0
        //6 = 2*3
        public static ExpressionBase FactorizationRule(ExpressionBase expression, List<ExpressionBase> selection)
        {
            VariadicOperatorExpression suggestion;
            //If expression is a number
            if (expression is NumericExpression && expression != null)
            {
                var numericExpression = selection[0] as NumericExpression;
                var n = numericExpression.Number;
                //Find integers a != 1 and b != 1 such that n = a*b
                for (int count = 2; count < n; count++)
                {
                    if (n % count == 0)
                    {
                        NumericExpression a = new NumericExpression(count);
                        NumericExpression b = new NumericExpression(n / count);

                        //Return product of a and b
                        suggestion = new VariadicOperatorExpression(OperatorType.Multiply, a, b);
                        return suggestion;
                    }
                }
            }
            return null;
        }
示例#13
0
 //a^n = a*a*...*a where n is an integer.
 public static ExpressionBase ExponentToProductRule(ExpressionBase expression, List<ExpressionBase> selection)
 {
     //If expression is a power.
     BinaryOperatorExpression exponent = expression as BinaryOperatorExpression;
     if (exponent != null && exponent.Type == OperatorType.Power)
     {
         //If exponent is a number.
         NumericExpression numericExpression = exponent.Right as NumericExpression;
         if (numericExpression != null)
         {
             int number = (int)numericExpression.Number;
             if (number == 0)
             {
                 //a^0 = 1
                 return new NumericExpression(1);
             }
             else if (number == 1)
             {
                 //a^1 = a
                 return exponent.Left.Clone();
             }
             else if (number > 1)
             {
                 //a^n = a*a*..*a
                 VariadicOperatorExpression result = new VariadicOperatorExpression(OperatorType.Multiply, exponent.Left.Clone(), exponent.Left.Clone());
                 for (int i = 2; i < number; i++)
                 {
                     result.Add(exponent.Left.Clone());
                 }
                 return result;
             }
         }
         else
         {
             return null;
         }
     }
     return null;
 }
示例#14
0
        //a^n*a^m = a^{n+m}
        public static ExpressionBase ExponentProduct(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is a product. e.g. a*a^2
            VariadicOperatorExpression product = expression as VariadicOperatorExpression;
            if (product != null && product.Type == OperatorType.Multiply)
            {
                List<ExpressionBase> sum = new List<ExpressionBase>();
                ExpressionBase commonBase = null;

                //Foreach operand in product
                foreach (var operand in product)
                {
                    ExpressionBase operandLeft = operand;
                    ExpressionBase operandRight = new NumericExpression(1);
                    BinaryOperatorExpression power = operand as BinaryOperatorExpression;
                    if (power != null && power.Type == OperatorType.Power)
                    {
                        operandLeft = power.Left;
                        operandRight = power.Right;
                    }
                    //If operand's base equals commonBase.
                    if (operandLeft == commonBase || commonBase == null)
                    {
                        //Add operands exponent to sum.
                        commonBase = operandLeft;
                        sum.Add(operandRight.Clone());
                    }
                    else
                    {
                        return null;
                    }
                }
                if (sum.Count > 1)
                {
                    //Return power with common base and sum of all operands' exponents.
                    VariadicOperatorExpression suggestionRight = new VariadicOperatorExpression(OperatorType.Add, sum[0], sum[1]);
                    suggestionRight.Add(sum.Skip(2).ToList());
                    return new BinaryOperatorExpression(commonBase, suggestionRight, OperatorType.Power);
                }
            }
            return null;
        }
示例#15
0
        //a^c * b^c = (a*b)^c
        public static ExpressionBase CommonPowerParenthesisRule(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is a product. e.g. a^c * b^c
            VariadicOperatorExpression product = expression as VariadicOperatorExpression;
            if (product != null && product.Type == OperatorType.Multiply)
            {
                ExpressionBase commonPower = null;
                List<ExpressionBase> baseList = new List<ExpressionBase>();

                //Foreach operand in product
                foreach (ExpressionBase operand in product)
                {
                    //If operand is a power
                    BinaryOperatorExpression power = operand as BinaryOperatorExpression;
                    if (power != null && power.Type == OperatorType.Power)
                    {
                        //If power's exponent equals the common exponent
                        if (power.Right == commonPower || commonPower == null)
                        {
                            //Add power's base to list
                            commonPower = power.Right;
                            baseList.Add(power.Left);
                        }
                        else
                        {
                            return null;
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
                if (baseList.Count > 1)
                {
                    //Initialize product of all bases in the list.
                    VariadicOperatorExpression resultProduct = new VariadicOperatorExpression(OperatorType.Multiply, baseList[0].Clone(), baseList[1].Clone());
                    resultProduct.Add(baseList.Skip(2).Select((b) => b.Clone()).ToList());
                    //return exponent with product as base and common exponent. e.g. (a*b)^c
                    BinaryOperatorExpression result = new BinaryOperatorExpression(resultProduct, commonPower.Clone(), OperatorType.Power);
                    return result;
                }
            }
            return null;
        }