3
$\begingroup$

I'm trying to define a pattern matching function:

test[x__?MatchQ[Equal[_, _]]] := 1;

Now I give it a series of inputs, and expect each to output 1:

test[1 == a, 1 == b]
test[1 == a, 1 == a]
test[1 == a, a == 1]
test[1 == a]

...none of which evaluate to 1. I can't see what I've done wrong here. So I try the following:

MatchQ[Equal[_, _]][a == b]

Which gives False. I don't understand why. I look at the FullForm of a==b and it gives back Equal[a,b] which should match with the pattern Equal[_,_].

However, for reasons beyond me, this expression...

MatchQ[Equal[_, __]][a == b]

...evaluates to True.

I have no idea what's going on here or why my test pattern match doesn't work. Can someone please explain what is going on? i.e.

  • Why doesn't my test pattern match work as intended?
  • How can I pattern match a sequence of equalities a==b, c==d ...?
  • Why does MatchQ[Equal[_,__]][a==b] yield True while replacing __ with _ yields false?
$\endgroup$
  • 3
    $\begingroup$ A few things going on here. a) look at Equal[_, _]. It's True. So you'll need a HoldPattern. b) ? is a high-precedence operator so you need ?(MatchQ[HoldPattern[Equal[_, _]]]). Even better though would just be x__Equal. It's most concise and the fastest. $\endgroup$ – b3m2a1 Dec 21 '17 at 5:54
  • $\begingroup$ @b3m2a1 - Thanks! That pretty much answers it. Looks like Mathematica doesn't evaluate _==__ so that explains the behaviour of that pattern match. You can write up a brief answer if you want. $\endgroup$ – Myridium Dec 21 '17 at 5:56
  • $\begingroup$ Feel free to self-answer. I'm checking to see if this is a dupe (but a self-answer won't hurt either way). $\endgroup$ – b3m2a1 Dec 21 '17 at 5:58
  • 1
    $\begingroup$ You could also write HoldPattern[_ == _] .. $\endgroup$ – Szabolcs Dec 21 '17 at 8:52
5
$\begingroup$

As b3m2a1 answered in the comments, a couple of things were wrong with my code.

  • ? is a high-precedence operator, and so its argument should be encased in parentheses. i.e. ?(MatchQ[HoldPattern[Equal[_, _]]]) instead of ?MatchQ[HoldPattern[Equal[_, _]]]
  • Mathematica is evaluating Equal[_,_] to True before pattern matching! We need to use HoldPattern[Equal[_,_]].
$\endgroup$
  • $\begingroup$ One more thing to add: test[x__Equal] := 1 will work, too (and probably be faster) $\endgroup$ – b3m2a1 Dec 21 '17 at 6:14
  • $\begingroup$ @b3m2a1 - they have different behaviour, however. If the user enters x==y==z, I don't want this to be pattern matched. $\endgroup$ – Myridium Dec 21 '17 at 7:01
  • $\begingroup$ Ahh. Okay. I assumed you were only working with a==b type expressions. $\endgroup$ – b3m2a1 Dec 21 '17 at 7:02

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.