At the very least the mathematical pattern matcher should be separate (ideally a layer on top of) the structural one. Otherwise you can't do structural only matching, at least without bending over backwards.
Whenever I've used pattern matching in SymPy, I just need it to be as smart as it can. If it can't match something that should be matched, that is fine: it won't lead to wrong results, just an algorithm might not get applied when it could (so e.g., you might get NotImplementedError instead of an answer). Much of the mathematical matching in SymPy could be done away with if we require that people using pattern matching understand how expressions work, and avoid using certain kinds of patterns. For example, matching the pattern u - v is bad (same with u/v), because structurally that's Add(u, Mul(-1, v)). So it will not match x + y as {u: x, v: -y} because the expression doesn't unify with the -1 in the pattern. But if your pattern is instead u + v, and you want to match x - y, that will work (and if you really wanted u - v you can just negate what you get for v). This particular issue likely comes up more often for division than subtraction, as you want to match a numerator and denominator. However, there are other cases that are not so clear to me, such as matching x**4 against the pattern w**2 as {w: x**2}. The only thing I can think of is matching w**n and checking if n is an integer multiple of 2, but it's really nice when you can get the pattern matcher to do this sort of thing for you. OTOH, having that specific behavior automatically can be a bad thing, because that assumes that everyone always wants it, whereas it likely only applies to some situations, but not to others. Finally, I'll point out that subs/xreplace/replace have these exact same problems. If you're looking at cleaning up pattern matching I would look at cleaning up the replacement functions as well. The two are closely related. Essentially expr.subs(old, new) implicitly pattern matches old in the subexpressions of expr. Aaron Meurer On Mon, Sep 1, 2014 at 6:28 AM, F. B. <franz.bona...@gmail.com> wrote: > SymPy's default pattern matcher is not a structural one, i.e. it tries to > match according to some mathematical rules. A structural pattern matcher > would instead just match the structure of the expression-tree. > > While it is necessary to have some mathematical awareness such as, give the > wild w: > > associativity awareness (i.e. f(a, b, c) = f(a, f(b, c)) and similar): > (a+b+c).match(a+w) ==> {w: b+c} > commutativity awareness: > (a+b).match(w+a) ==> {w: b} > one-identity awareness (f is one-identical if f(x) = x for any x): > x.match(Add(w, evaluate=False)) ==> {w: x} > > These rules are also available in Wolfram Mathematica. > > There are some results which come out as an attempt to apply some kind of > equation solving: > > In [20]: (x*y).match(x/w) > Out[20]: > ⎧ 1⎫ > ⎨w: ─⎬ > ⎩ y⎭ > > That is, Mul(x, y) is matched to become Mul(x, Pow(Mul(1, Pow(y, -1)), -1)) > which is equivalent mathematically, but not structurally. > > I would expect this result by calling: > > In [29]: solve(Eq(x*y, x/w), w) > Out[29]: > ⎡1⎤ > ⎢─⎥ > ⎣y⎦ > > I was wondering, what are the pattern matching rules for this awareness? > This goes beyond the three rules I pointed out hereabove. Technically, > mathematical-aware patterns may yield infinite results as long as they are > combined with equation solvers. > > Wolfram Mathematica seems not to have any solver-awareness, that is, the > previous pattern does not match: > > In[12]:= (x y) /. x/w_ -> {w} > Out[12]= x y > > It would be useful to keep SymPy's pattern matching rules as close as > possible to those of Mathematica. I suggest to remove redundant results > relying on solvers, or maybe add a parameter to the matcher to turn it off. > What do you think? > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sympy+unsubscr...@googlegroups.com. > To post to this group, send email to sympy@googlegroups.com. > Visit this group at http://groups.google.com/group/sympy. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/10ad1141-ee19-44ad-bd6e-42c982af3da2%40googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. Visit this group at http://groups.google.com/group/sympy. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6K3RXe_kAjDz_sww9pWfvaWSXiZkR4ktH0TUTE_prOKyA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.