/// <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); } }
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); }
/// <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)); }
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); }
public override bool CallMatches(IEnumerable <Expression> Arguments, Expression E, MatchContext Matched) { return(base.CallMatches(Arguments, E, Matched) || ex.Matches(E, Matched)); }
private bool IsChild(Expression P) { return(ReferenceEquals(pattern, null) || pattern.Matches(P) != null); }
private bool IsChild(Expression P) { return((pattern is null) || pattern.Matches(P) != null); }