# Matching HoldPattern expressions

My original problem is to delete all rules starts with a[1] from SubValues[a]

For example,

{HoldPattern[a[1][2]] :> 1, HoldPattern[a[2][3]] :> 5,
HoldPattern[a[1][x_, y_]] :> x + y,
HoldPattern[a[2][x_, y_]] :> x - y, HoldPattern[a[2][x_]] :> x}


would become

{HoldPattern[a[2][3]] :> 5, HoldPattern[a[2][x_, y_]] :> x - y,
HoldPattern[a[2][x_]] :> x}


I tried to use patterns at first, but I found that when matching patterns with HoldPattern head, results become unpredictable.

I found 2 general pattern matching results with HoldPattern I don't understand (doc on HoldPattern and related did not say anything on this):

1.MatchQ[HoldPattern[a[1]], HoldPattern[_[_]]] is True, but include some names, and MatchQ[HoldPattern[a[1]], HoldPattern[a[_]]] is False.

2.MatchQ[HoldPattern[a[1]], HoldPattern[_[_]]] is True, but MatchQ[HoldPattern[a[1][1]], HoldPattern[_[_][_]]] is False.

I solved my problem with

FilterRules[SubValues[a], _?(FreeQ[#, name] &)]


But I would still like to know about matching HoldPattern expressions.

• You can use Verbatim: MatchQ[HoldPattern[a[1]], Verbatim[HoldPattern][a[_]]] will return True.
– user31159
Apr 17, 2016 at 18:57
• @Xavier can you explain more? I only know how Verbatim work with blanks, and I have no idea what HoldPattern did to the expression that caused this mismatch. Apr 17, 2016 at 19:00

Clarification of HoldPattern usage:

HoldPattern[expr] is equivalent to expr for pattern matching, but maintains expr in an unevaluated form.

I think this can be ambiguous for beginners. One could think that what we are doing in

MatchQ[HoldPattern[a[1]], HoldPattern[_[_]]]


is to more or less

MatchQ[ a[1], _[_] ]


where both arguments are kept unevaluated. That's not the case. "for pattern matching" from the usage message means "when used in pattern". And here a pattern is the second argument.

Knowing that we can easily explain your examples:

So, case 1,

MatchQ[HoldPattern[a[1]], HoldPattern[_[_]]]


is really trying to match _[_] to HoldPattern[a[1]], with success because it really is (HoldPattern)[(a[1])].

Furthermore, it will fail to match a[_] because this represents an expression which outer head is a while it should be HoldPattern.

Case 2 can be explained this way too. When the HoldPattern is stripped, _[_][_] doesn't match HoldPattern[a[1][1]] as it really is _[_[_][_]]:

MatchQ[HoldPattern[a[1][1]], HoldPattern[_[_[_][_]]]]

True


Possible issues with Verbatim:

To prevent HoldPattern from being stripped you can use Verbatim. But it can't be used mindlessly. E.g. let's say you have defined:

a[_]:=2


This will create

HoldPattern[a[_]] :> 2


down value. As discussed your approach won't work:

MatchQ[ HoldPattern[a[_]] :> 2, HoldPattern[a[_]] :> 2 ] (*False*)


but also

MatchQ[ HoldPattern[a[_]] :> 2, Verbatim[HoldPattern][a[_]] :> 2 ]


fails because there isn't anything preventing a[_] from evaluating to 2.

Here we are safe:

MatchQ[
HoldPattern[a[_]] :> 2,
Verbatim[HoldPattern][a[_]] :> 2 // HoldPattern
]


DeleteCases[
values,
_[a[1][__]] :> _ // HoldPattern
]

• That's exactly what I misunderstood, you even gave me an answer to the "preventing pattern from evaluated" problem I actually encountered but didn't mention. Thanks! Apr 18, 2016 at 3:04
• @happyfish related: mathematica.stackexchange.com/a/2804/121 :^) Apr 3, 2017 at 5:02
• @Mr.Wizard nice! Sometimes evaluation control is beyond my usual problem solving logic, and I'll end up with a pile of spaghetti code. The answers from you and a few others on this topic are always eye opening. Apr 3, 2017 at 7:37

My go to method for handling *Values is to just use _ everywhere. So, I would use:

values = {HoldPattern[a[1][2]] :> 1, HoldPattern[a[2][3]] :> 5,
HoldPattern[a[1][x_, y_]] :> x + y,
HoldPattern[a[2][x_, y_]] :> x - y, HoldPattern[a[2][x_]] :> x};

DeleteCases[values, _[_[a[1][__]],_]]


{HoldPattern[a[2][3]] :> 5, HoldPattern[a[2][x_, y_]] :> x - y, HoldPattern[a[2][x_]] :> x}