public static bool Contains(Expression expr, Expression sub) { if (expr.GetType().Equals(sub.GetType())) return expr.Equals(sub); if (expr is BinaryExpression) { BinaryExpression bexpr = (BinaryExpression)expr; return Contains(bexpr.Left, sub) && Contains(bexpr.Right, sub); } else if (expr is LinearExpression) { LinearExpression lexpr = (LinearExpression)expr; bool contains = true; foreach (Expression item in lexpr.List) contains = contains && Contains(item, sub); return contains; } else if (expr is FunctionExpression) { FunctionExpression fexpr = (FunctionExpression)expr; bool contains = true; foreach (Expression arg in fexpr.Arguments) contains = contains && Contains(arg, sub); return contains; } return false; }
private bool match(Expression expr, Expression pattern) { if (!(pattern is VariableExpression)) { if (!expr.GetType().Equals(pattern.GetType())) return false; if (pattern is BinaryExpression) { BinaryExpression bexpr = (BinaryExpression)expr; BinaryExpression bpattern = (BinaryExpression)pattern; if (bexpr.Operator != bpattern.Operator) return false; return match(bexpr.Left, bpattern.Left) && match(bexpr.Right, bpattern.Right); } else if (pattern is FunctionExpression) { FunctionExpression fexpr = (FunctionExpression)expr; FunctionExpression fpattern = (FunctionExpression)pattern; if (fexpr.Name != fpattern.Name || fexpr.Arguments.Count != fpattern.Arguments.Count) return false; bool matching = true; for (int i = 0; i < fexpr.Arguments.Count; i++) matching = matching && match(fexpr.Arguments[i], fpattern.Arguments[i]); return matching; } return expr.Equals(pattern); } else { VariableExpression vpattern = (VariableExpression)pattern; string name = vpattern.Name; if (matches.ContainsKey(name)) { Expression fmatch = matches[name]; if (!expr.Equals(fmatch)) return false; } matches[name] = expr; return true; } }