Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.
MatchQ[Hold[1 + 2], Hold[2 + 1]]

returns False. But in the presence of a Blank[] in the matching pattern as in the example below

MatchQ[Hold[1 + 2], Hold[2 + _]]

which returns True, apparently the fact that Plus is Orderless is being respected.

Apart from doing something like removing the Orderless attribute from Plus, how can I make the order matter when pattern-matching in a case like this? Where can I read more about this in the documentation?

share|improve this question
    
I see that you have not Accepted an answer to this question. Are they all unsatisfying? Can I do anything to improve mine? –  Mr.Wizard Sep 4 '13 at 12:52
    
I haven't logged in to this site for a while. I've decided to accept your answer. –  Aky Sep 9 '13 at 18:21
    
Well, thank you. :-) –  Mr.Wizard Sep 9 '13 at 20:13

3 Answers 3

up vote 7 down vote accepted

You need to prevent Plus being an active head in the pattern. One natural method is Block to temporarily change all appearances of Plus as suggested by rcollyer:

Block[{Plus},
  MatchQ[Hold[1 + 2], Hold[2 + _]]
]

False

For that matter you could use With as well, which replaces only explicit appearances:

With[{Plus = Null},
  MatchQ[Hold[1 + 2], Hold[2 + _]]
]

False

More directly you can make the head of [2, _] a pattern so that Plus is not active:

MatchQ[Hold[1 + 2], Hold[(h : Plus)[2, _]]]

False

h here is arbitrary.

Perhaps better is Verbatim:

MatchQ[Hold[1 + 2], Hold[Verbatim[Plus][2, _]]]

False

share|improve this answer

A quick and dirty solution to this would be to match the structure first, and the operator Plus afterwards:

MatchQ[Hold[1 + 2], Hold[f_[2, _]] /; f === Plus]
MatchQ[Hold[2 + 1], Hold[f_[2, _]] /; f === Plus]

(* {False,True} *)

share|improve this answer
    
+1 Very interesting. –  Aky Aug 9 '13 at 16:07

Instead of modifying the definition of such a basic function, change it temporarily. The following code

With[{Plus = tempPlus}, {MatchQ[Hold[1 + 2], Hold[2 + _]], MatchQ[Hold[1 + 2], Hold[1 + _]]}]

yields

{False, True}
share|improve this answer
7  
A simpler, but related, method is to use Block[{Plus}, MatchQ[...]] as the attributes are temporarily stripped from Plus because of Block. –  rcollyer Aug 9 '13 at 13:44
    
+1 Definitely better than modifying the definition of a basic function –  Aky Aug 9 '13 at 16:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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