# Why does ReplaceAll match pattern while MatchQ fails

Why does the following pattern with MatchQ fail

MatchQ[1+Sin[1] I, a_Complex /; Im[a] > 0]
(* False *)


Whereas, the same pattern with ReplaceAll works?

1 + Sin[1] I /. {a_Complex /; Im[a] > 0 -> 3}
(* 1+3Sin[1] *)
1 - Sin[1] I /. {a_Complex /; Im[a] > 0 -> 3}
(* 1-iSin[1] *)


If I look at the FullForm of my expression it is Plus[1,Times[Complex[0,1],Sin[1]]]. Shouldn't a_Complex match Complex[0,1] and Im[a] == 1 > 0 evaluate to True? At least that's what seems to be happening with ReplaceAll but I can't quite figure out why MatchQ fails.

MatchQ matches the whole expression. It doesn't match inner rules.

In[1]:= MatchQ[12345, _Integer]
Out[1]= True

In[2]:= MatchQ[{12345}, _Integer]
Out[2]= False


ReplaceAll works recursively over a whole function, replacing all instances of that pattern it finds. That's the meaning of All in the function name.

A careful reading of the usage messages for MatchQ and ReplaceAll would have explained this.

• +1 We can detect whether any subexpression matches the pattern by using !FreeQ[...], for example... ! FreeQ[1 + Sin[1] I, a_Complex /; Im[a] > 0]. Commented Oct 11, 2018 at 22:55
• I did read the documentation before asking. It wasn't really specified that MatchQ only looks to match the outer expression. Although ReplaceAll did note that it attempts to 'transform each subpart of an expression'. Commented Oct 11, 2018 at 23:05
• @void, instead of "outer expression", it's "entire expression"; the intent of MatchQ[expr, patt] is to check if expr itself matches the pattern patt, not any sub-expressions expr might have. Commented Oct 12, 2018 at 1:04
• @J.M.issomewhatokay. Ah ok. Thank you for the clarification, that makes more sense. So essentially Im[a] > 0 would evaluate to be true, but a_Complex wouldn't match as the head of the entire expression is Plus not Complex. If I wanted to match the Complex I'd have to have a pattern that matches nested Heads right? Commented Oct 12, 2018 at 16:29
• @void, something like that, yes; however, a_ /; Im[a] > 0 is already fine, or you can do a_?NumericQ /; Im[a] > 0 for stricter matching. Commented Oct 12, 2018 at 16:33