# More general pattern fails to match everything the more specific pattern does.

When I input this:

MatchQ[x*SF[a,b] + y*SF[c,d], Plus[Times[x,SF[a,b]],Times[y,SF[c,d]]]]


I get "True" as expected. But If I change it to:

MatchQ[x*SF[a,b] + y*SF[c,d], Plus[Times[_,SF[_,_]],Times[_,SF[_,_]]]]


Which ought to be more general, it returns false.

Why does this happen? I think it's evaluate the Plus, and return a pattern like Times[2,,SF[,_]]. But how do I make it stop doing that?

My goal is to Match the pattern for expressions like x*SF[a,b] + y*SF[c,d] + z*SF[e,f] ... So what do I have to do to fix this?

• Try MatchQ[x*SF[a, b] + y*SF[c, d], Plus[Times[x1_, SF[x2_, x3_]], Times[x4_, SF[x5_, x6_]]]]. Commented Jun 22, 2013 at 20:52
• Yeah,but I couldn't generalize that to make a it work for any amount of summands. Commented Jun 22, 2013 at 20:55

You need to realize that pattern expressions evaluate just like any other in Mathematica. Let's look at how this plays out for each pattern you gave:

Plus[Times[x, SF[a, b]], Times[y, SF[c, d]]]

Plus[Times[_, SF[_, _]], Times[_, SF[_, _]]]

x SF[a, b] + y SF[c, d]

2 _ SF[_, _]


Clearly they are not equivalent. In this particular case you can use HoldPattern to prevent this unwanted "simplification" from taking place:

MatchQ[
x*SF[a, b] + y*SF[c, d],
Plus[Times[_, SF[_, _]], Times[_, SF[_, _]]] // HoldPattern
]

True


Be aware that due to the Orderless attribute (and others) of Plus, Times, etc., you may still encounter unexpected behavior, e.g.:

Different behaviours of Default Argument

• don't you think that the first argument to Times _ is to greedy and should be changed to a __ instead? Commented Jun 22, 2013 at 20:59
• @Stefan I suppose it depends on what you expect it to match but perhaps I don't understand your concern. Commented Jun 22, 2013 at 21:01
• if you use _, this is in that specific case the whole expression x,SF[a,b]],Times[y,SF[c,d], since _ is greedy like its regex equivalent *. If you use __ instead it is less greedy (like +?) and the expressions get evaluated correctly... Commented Jun 22, 2013 at 21:04
• @Stefan I'm afraid I don't understand. The parts I expect to correspond appear to, in e.g. Replace[ x*SF[a, b] + y*SF[c, d], q : Plus[r : Times[s : _, t : SF[_, _]], Times[_, SF[_, _]]] :> {q, r, s, t} ] -- is a part of this pattern (q, r, s, t) is not as you expect? Commented Jun 22, 2013 at 21:14
• @Mr.Wizard No. Your answer is brilliant, but what I tried to say (see my answer) is, if you change the pattern in Times from '_' to '__' it matches. Even with your Replacement code. Commented Jun 22, 2013 at 21:16

I always struggle with the pattern matching rules as well.

The first thing that is suspicious to me is the greedy _ in your Times expression.

_, just like its regex counterpart *, is greedy and will match everything. But, if you change that one to __ (regex + or even better +?) your matching succeeds.

MatchQ[x*SF[a, b] + y*SF[c, d], Plus[Times[__, SF[_, _]], Times[_, SF[_, _]]]]

(* Out: True *)

• the more i look at it, the more doubtful my answer seems to me...the best would be maybe to capture the groups if this really matches the expression at all.... Commented Jun 22, 2013 at 21:13
• I don't think the original issue has anything to do with greedy patterns but rather automatic "simplification", which you (partly) avoid here due to use of both _ and __ -- however, if you change both Times expressions to use __: Plus[Times[__, SF[_, _]], Times[__, SF[_, _]]] it will evaluate to 2 __ SF[_, _] Commented Jun 22, 2013 at 21:19
• @Mr.Wizard. Yes exactly. This is the point, where it gets weird to me. And that's why I expressed doubts about my answer...but it works; that you've to agree with. Even with your Replace expression above...I'm confused. Commented Jun 22, 2013 at 21:24
• I imagine we are talking past each other and I apologize for that. I'm merely trying to point out that the original pattern is analogous to Times["x", "other"] + Times["x", "other"] evaluating to 2 "other" "x" and your change is analogous to Times["y", "other"] + Times["x", "other"] remaining separate terms. ("other" "x" + "other" "y") Commented Jun 22, 2013 at 21:27
• @Mr.Wizard You don't have to apologise. It is the fault of the"National Fibromyalgia Association" and her little sister the "non deterministic finite automata". Puzzling creatures... :). Cheers. Always a pleasure to me. Commented Jun 22, 2013 at 21:31