예제 #1
0
        //Exp( p ) is
        //    var t : Tree
        //    t := P
        //    while next is a binary operator and prec(binary(next)) >= p
        //       const op := binary(next)
        //       consume
        //       const q := case associativity(op)
        //                  of Right: prec( op )
        //                     Left:  1+prec( op )
        //       const t1 := Exp( q )
        //       t := mkNode( op, t, t1)
        //    return t
        private Expression Exp(int p)
        {
            Expression l = P();

            Operator op = new Operator();

            while (true)
            {
                if (IsBinaryOperator(tokens.Tok, ref op) && Precedence(op) >= p)
                {
                    tokens.Consume();

                    int        q = Precedence(op) + (IsLeftAssociative(op) ? 1 : 0);
                    Expression r = Exp(q);
                    l = Binary.New(op, l, r);
                }
                else if (IsUnaryPostOperator(tokens.Tok, ref op) && Precedence(op) >= p)
                {
                    tokens.Consume();
                    l = Unary.New(op, l);
                }
                else
                {
                    break;
                }
            }
            return(l);
        }
예제 #2
0
        private static Expression Split(Expression P)
        {
            int child = 0;

            if (P is Sum)
            {
                return(ComputerAlgebra.Sum.New(((ComputerAlgebra.Sum)P).Terms.Select(i => ChildPattern(ref child))));
            }
            if (P is Product)
            {
                return(Product.New(((Product)P).Terms.Select(i => ChildPattern(ref child))));
            }
            if (P is Binary)
            {
                return(Binary.New(((Binary)P).Operator, ChildPattern(ref child), ChildPattern(ref child)));
            }
            if (P is Unary)
            {
                return(Unary.New(((Unary)P).Operator, ChildPattern(ref child)));
            }
            if (P is Call)
            {
                return(Call.New(((Call)P).Target, ((Call)P).Arguments.Select(i => ChildPattern(ref child))));
            }
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Distribute products across sums, using partial fractions if necessary.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Expression Expand(this Expression f, Expression x)
        {
            if (f is Product)
            {
                return(ExpandMultiply(f, x));
            }
            else if (f is Sum)
            {
                return(Sum.New(((Sum)f).Terms.Select(i => i.Expand(x))));
            }
            else if (f is Power)
            {
                return(ExpandPower((Power)f, x));
            }
            else if (f is Binary)
            {
                return(Binary.New(((Binary)f).Operator, ((Binary)f).Left.Expand(), ((Binary)f).Right.Expand()));
            }
            else if (f is Unary)
            {
                return(Unary.New(((Unary)f).Operator, ((Unary)f).Operand.Expand()));
            }

            return(f);
        }
예제 #4
0
        /// <summary>
        /// Distribute products across sums, using partial fractions if necessary.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Expression Expand(this Expression f, Expression x)
        {
            if (f is Product)
            {
                return(ExpandMultiply(f, x));
            }
            else if (f is Sum sum)
            {
                return(Sum.New(sum.Terms.Select(i => i.Expand(x))));
            }
            else if (f is Power power)
            {
                return(ExpandPower(power, x));
            }
            else if (f is Binary binary)
            {
                return(Binary.New(binary.Operator, binary.Left.Expand(x), binary.Right.Expand(x)));
            }
            else if (f is Unary unary)
            {
                return(Unary.New(unary.Operator, unary.Operand.Expand()));
            }

            return(f);
        }
예제 #5
0
        protected override Expression VisitUnary(Unary U)
        {
            Expression O = Visit(U.Operand);

            if (ReferenceEquals(O, null))
            {
                return(null);
            }

            if (ReferenceEquals(O, U.Operand))
            {
                return(U);
            }
            else
            {
                return(Unary.New(U.Operator, O));
            }
        }
예제 #6
0
        protected override Expression VisitUnary(Unary U)
        {
            Expression O = Visit(U.Operand);
            Real?      C = AsReal(O);

            switch (U.Operator)
            {
            case Operator.Not:
                if (IsTrue(C))
                {
                    return(Constant.New(false));
                }
                else if (IsFalse(C))
                {
                    return(Constant.New(true));
                }
                break;
            }

            return(Unary.New(U.Operator, O));
        }
예제 #7
0
        //P is
        //    if next is a unary operator
        //         const op := unary(next)
        //         consume
        //         q := prec( op )
        //         const t := Exp( q )
        //         return mkNode( op, t )
        //    else if next = "("
        //         consume
        //         const t := Exp( 0 )
        //         expect ")"
        //         return t
        //    else if next is a v
        //         const t := mkLeaf( next )
        //         consume
        //         return t
        //    else
        //         error
        private Expression P()
        {
            Operator op = new Operator();

            if (tokens.Tok == "+")
            {
                // Skip unary +.
                tokens.Consume();
                return(P());
            }
            else if (IsUnaryPreOperator(tokens.Tok, ref op))
            {
                // Unary operator.
                tokens.Consume();
                Expression t = Exp(Precedence(op));
                return(Unary.New(op, t));
            }
            else if (tokens.Tok == "(")
            {
                // Group.
                tokens.Consume();
                Expression t = Exp(0);
                tokens.Expect(")");
                return(t);
            }
            else if (tokens.Tok == "{")
            {
                // Set.
                tokens.Consume();
                return(Set.New(L(",", "}")));
            }
            else if (tokens.Tok == "[")
            {
                // Matrix.
                tokens.Consume();
                List <List <Expression> > entries = new List <List <Expression> >();
                while (tokens.Tok == "[")
                {
                    tokens.Consume();
                    entries.Add(L(",", "]"));
                }
                tokens.Expect("]");

                return(Matrix.New(entries));
            }
            else
            {
                string tok = tokens.Consume();

                decimal dec = 0;
                double  dbl = 0.0;
                if (decimal.TryParse(tok, NumberStyles.Float, culture, out dec))
                {
                    return(Constant.New(dec));
                }
                if (double.TryParse(tok, NumberStyles.Float, culture, out dbl))
                {
                    return(Constant.New(dbl));
                }
                else if (tok == "True")
                {
                    return(Constant.New(true));
                }
                else if (tok == "False")
                {
                    return(Constant.New(false));
                }
                else if (tok == "\u221E" || tok == "oo")
                {
                    return(Constant.New(Real.Infinity));
                }
                else if (tokens.Tok == "[")
                {
                    // Bracket function call.
                    tokens.Consume();
                    List <Expression> args = L(",", "]");
                    return(Call.New(Resolve(tok, args), args));
                }
                else if (tokens.Tok == "(")
                {
                    // Paren function call.
                    tokens.Consume();
                    List <Expression> args = L(",", ")");
                    return(Call.New(Resolve(tok, args), args));
                }
                else
                {
                    return(Resolve(tok));
                }
            }
        }