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
    $\begingroup$ +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]. $\endgroup$ – WReach Oct 11 '18 at 22:55
  • $\begingroup$ 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'. $\endgroup$ – void life Oct 11 '18 at 23:05
  • $\begingroup$ @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. $\endgroup$ – J. M. will be back soon Oct 12 '18 at 1:04
  • $\begingroup$ @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? $\endgroup$ – void life Oct 12 '18 at 16:29
  • $\begingroup$ @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. $\endgroup$ – J. M. will be back soon Oct 12 '18 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.