예제 #1
0
        /// <summary>
        /// Transform an expression by matching to the pattern and substituting the result if successful.
        /// </summary>
        /// <param name="E">Expression to transform.</param>
        /// <returns>The transformed expression.</returns>
        public Expression Transform(Expression x)
        {
            MatchContext matched = pattern.Matches(x);

            if (matched != null && conditions.All(i => i.Evaluate(matched).IsTrue()))
            {
                return(ApplyTransform(x, matched));
            }
            else
            {
                return(x);
            }
        }
예제 #2
0
        public override bool Matches(Expression E, MatchContext Matched)
        {
            Index I = E as Index;

            if (!ReferenceEquals(I, null))
            {
                if (Indices.Count() != I.Indices.Count())
                {
                    return(false);
                }

                return(Matched.TryMatch(() =>
                                        target.Matches(I.Target, Matched) &&
                                        indices.Zip(I.Indices, (p, e) => p.Matches(e, Matched)).All()));
            }

            return(false);
        }
예제 #3
0
        /// <summary>
        /// Construct a polynomial of x from f(x).
        /// </summary>
        /// <param name="f"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Polynomial New(Expression f, Expression x)
        {
            // Match each term to A*x^N where A is constant with respect to x, and N is an integer.
            Variable   A           = PatternVariable.New("A", i => !i.DependsOn(x));
            Variable   N           = PatternVariable.New("N", i => i.IsInteger());
            Expression TermPattern = Product.New(A, Power.New(x, N));

            DefaultDictionary <int, Expression> P = new DefaultDictionary <int, Expression>(0);

            foreach (Expression i in Sum.TermsOf(f))
            {
                MatchContext Matched = TermPattern.Matches(i, Arrow.New(x, x));
                if (Matched == null)
                {
                    throw new ArgumentException("f is not a polynomial of x.");
                }

                int n = (int)Matched[N];
                P[n] += Matched[A];
            }

            return(new Polynomial(P, x));
        }
예제 #4
0
        public override bool Matches(Expression E, MatchContext Matched)
        {
            // if E is zero, any term can match to zero to succeed.
            if (E.EqualsZero())
            {
                return(Terms.Any(i => i.Matches(0, Matched)));
            }

            // Move the constants in this pattern to E.
            IEnumerable <Expression> PTerms    = Terms;
            IEnumerable <Expression> Constants = PTerms.OfType <Constant>();

            if (Constants.Any())
            {
                E      = Binary.Divide(E, New(Constants)).Evaluate();
                PTerms = PTerms.Except(Constants, RefComparer);
            }

            IEnumerable <Expression> ETerms = TermsOf(E);

            // Try starting the match at each term of the pattern.
            foreach (Expression p in PTerms)
            {
                // Remaining terms of the pattern.
                Expression P = New(PTerms.ExceptUnique(p, RefComparer));

                // If p is a variable, we have to handle the possibility that more than one term of E might match this term.
                if (p is Variable)
                {
                    // Check if p has already been matched. If it has, treat it as a constant and match the rest of the terms.
                    Expression matched;
                    if (Matched.TryGetValue(p, out matched))
                    {
                        // p has already been matched. Remove it out of E and match the remainder of the pattern.
                        if (P.Matches(E / matched, Matched))
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        // Try matching p to the various combinations of the terms of E.
                        for (int i = 1; i <= ETerms.Count(); ++i)
                        {
                            foreach (IEnumerable <Expression> e in ETerms.Combinations(i))
                            {
                                if (Matched.TryMatch(() =>
                                                     p.Matches(New(e), Matched) &&
                                                     P.Matches(New(ETerms.ExceptUnique(e, RefComparer)), Matched)))
                                {
                                    return(true);
                                }
                            }
                        }

                        // Try matching p to identity.
                        if (Matched.TryMatch(() => p.Matches(1, Matched) && P.Matches(E, Matched)))
                        {
                            return(true);
                        }
                    }
                }
                else
                {
                    // If p is not a variable, try matching it to any of the terms of E.
                    foreach (Expression e in ETerms)
                    {
                        if (Matched.TryMatch(() =>
                                             p.Matches(e, Matched) &&
                                             P.Matches(New(ETerms.ExceptUnique(e, RefComparer)), Matched)))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
예제 #5
0
 public override bool CallMatches(IEnumerable <Expression> Arguments, Expression E, MatchContext Matched)
 {
     return(base.CallMatches(Arguments, E, Matched) || ex.Matches(E, Matched));
 }
예제 #6
0
 private bool IsChild(Expression P)
 {
     return(ReferenceEquals(pattern, null) || pattern.Matches(P) != null);
 }
예제 #7
0
 private bool IsChild(Expression P)
 {
     return((pattern is null) || pattern.Matches(P) != null);
 }