# 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_]]]]. – b.gates.you.know.what Jun 22 '13 at 20:52
• Yeah,but I couldn't generalize that to make a it work for any amount of summands. – Anonymous82398 Jun 22 '13 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? – Stefan Jun 22 '13 at 20:59
• @Stefan I suppose it depends on what you expect it to match but perhaps I don't understand your concern. – Mr.Wizard Jun 22 '13 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... – Stefan Jun 22 '13 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? – Mr.Wizard Jun 22 '13 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. – Stefan Jun 22 '13 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.... – Stefan Jun 22 '13 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[_, _] – Mr.Wizard Jun 22 '13 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. – Stefan Jun 22 '13 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") – Mr.Wizard Jun 22 '13 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. – Stefan Jun 22 '13 at 21:31