public void ExpressionSerializerSerialize()
        {
            var parser = new ExpressionSerializer();
            ExpressionBase exp;

            exp = new BinaryOperatorExpression(
                new NumericExpression(1),
                new NumericExpression(1),
                OperatorType.Add);
            Assert.AreEqual("{1}+{1}", parser.Serialize(exp), "{1}+{1}");

            exp = new BinaryOperatorExpression(
                new NumericExpression(1),
                new NumericExpression(1),
                OperatorType.Divide);
            Assert.AreEqual("{1}/{1}", parser.Serialize(exp), "{1}/{1}");

            exp = new BinaryOperatorExpression(
                new NumericExpression(1),
                new NumericExpression(1),
                OperatorType.Multiply);
            Assert.AreEqual("{1}*{1}", parser.Serialize(exp), "{1}*{1}");

            exp = new BinaryOperatorExpression(
                new NumericExpression(1),
                new NumericExpression(1),
                OperatorType.Power);
            Assert.AreEqual("{1}^{1}", parser.Serialize(exp), "{1}^{1}");

            exp = new BinaryOperatorExpression(
                new NumericExpression(1),
                new NumericExpression(1),
                OperatorType.Subtract);
            Assert.AreEqual("{1}-{1}", parser.Serialize(exp), "{1}-{1}");
        }
Пример #2
0
 //a^-n = 1/a^n
 public static ExpressionBase VariableWithNegativeExponent(ExpressionBase expression, List<ExpressionBase> selection)
 {
     //If expression is a power. e.g. a^-n
     BinaryOperatorExpression binaryexpression = expression as BinaryOperatorExpression;
     if (binaryexpression != null && binaryexpression.Type == OperatorType.Power)
     {
         //If exponent of power is unary minus. e.g. -n
         UnaryMinusExpression unaryexpression = binaryexpression.Right as UnaryMinusExpression;
         if (unaryexpression != null && binaryexpression.Left != null && binaryexpression.Right != null)
         {
             //Return reciprocal of power with unary minus removed in exponent. e.g. 1/a^n
             BinaryExpression power = new BinaryOperatorExpression(binaryexpression.Left.Clone(), unaryexpression.Expression.Clone(), OperatorType.Power);
             return new BinaryOperatorExpression(new NumericExpression(1), power, OperatorType.Divide);
         }
     }
     return null;
 }
        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;
        }
Пример #4
0
        //1/a^n = a^-n
        public static ExpressionBase ReverseVariableWithNegativeExponent(ExpressionBase expression, List<ExpressionBase> selection)
        {
            //If expression is a fraction. e.g. 1/a^n
            BinaryOperatorExpression binaryexpression = expression as BinaryOperatorExpression;
            if (binaryexpression != null && binaryexpression.Type == OperatorType.Divide)
            {
                //If numerator is 1 and denominator is power. e.g. 1 and a^n
                NumericExpression numericexpression = binaryexpression.Left as NumericExpression;
                BinaryExpression power = binaryexpression.Right as BinaryExpression;
                if (numericexpression != null && numericexpression.Value == "1" && power != null && power.Type == OperatorType.Power)
                {
                    //return power with minus exponent. e.g. a^-n
                    UnaryMinusExpression unaryminus = new UnaryMinusExpression(power.Right.Clone());
                    BinaryExpression mysuggestion = new BinaryOperatorExpression(power.Left.Clone(), unaryminus.Clone(), OperatorType.Power);
                    return mysuggestion;
                }
            }

            return null;
        }
Пример #5
0
 //a*a*...*a = a^n where n is an integer.
 public static ExpressionBase ProductToExponentRule(ExpressionBase expression, List<ExpressionBase> selection)
 {
     //If expression is a product.
     VariadicExpression product = expression as VariadicOperatorExpression;
     if (product != null && product.Type == OperatorType.Multiply)
     {
         //If all operands are equal.
         if (product.Where((operand) => product[0] == operand).Count() == product.Count)
         {
             //Return power.
             BinaryExpression suggestion = new BinaryOperatorExpression(product[0].Clone(), new NumericExpression(product.Count), OperatorType.Power);
             return suggestion;
         }
     }
     return null;
 }
Пример #6
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;
        }
Пример #7
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;
     }
 }
Пример #8
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;
        }