1
$\begingroup$

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.

$\endgroup$

1 Answer 1

2
$\begingroup$

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.

$\endgroup$
5
  • 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, 2018 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, 2018 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$ Oct 12, 2018 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, 2018 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$ Oct 12, 2018 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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