Ejemplo n.º 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 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;
 }
Ejemplo n.º 4
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;
 }
Ejemplo n.º 5
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;
 }
Ejemplo n.º 6
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;
        }
Ejemplo n.º 7
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;
        }
Ejemplo n.º 8
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;
 }
Ejemplo n.º 9
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;
        }
Ejemplo n.º 10
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;
        }