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$
4
  • 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, 2017 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, 2017 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, 2017 at 5:58
  • 1
    $\begingroup$ You could also write HoldPattern[_ == _] .. $\endgroup$
    – Szabolcs
    Dec 21, 2017 at 8:52

1 Answer 1

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$
3
  • $\begingroup$ One more thing to add: test[x__Equal] := 1 will work, too (and probably be faster) $\endgroup$
    – b3m2a1
    Dec 21, 2017 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, 2017 at 7:01
  • $\begingroup$ Ahh. Okay. I assumed you were only working with a==b type expressions. $\endgroup$
    – b3m2a1
    Dec 21, 2017 at 7:02

Your Answer

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

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