# Unexpected behaviour of Condition with Cases/MatchQ?

When using the unsorted version of Complement in this question I met the following unexpected result,

list1 = {a -> b /; c, a -> b, a};
Cases[list1, Alternatives @@ list1]

Out[]={a -> b, a}


Similarly for MatchQ,

MatchQ[Condition[a, b], Condition[a, b]]

Out[]=False

ClearAll@f;
SetAttributes[f, HoldAll];
MatchQ[f[x, y], f[x, y]]

Out[]=True


and I need to inactivate Condition in expressions.

How to understand this behaviour?

• MatchQ[f[x, y], f[x, y]] returns True whether or not f has the attribute HoldAll. Jun 16 at 18:42

Condition[a, b] is pattern that matches a provided b is True. But Condition[a, b] (the first argument to MatchQ) does not match a nor is b true.

Verbatim is designed for expressions which are usually interpreted as patterns.

MatchQ[Condition[a, b], Verbatim[Condition][a, b]]
(*  True  *)

• The same applies to list1. a -> b /; c matches Rule[a, b], provided c is True. It doesn't really matter whether one puts the condition inside or out in this case, i.e., Rule[a, b /; c] or Rule[a, b] /; c. Jun 16 at 18:45
• Thx! I never used Verbatim before. Does this function have other usages besides matching rules with rules? Jun 18 at 7:20
• @Lilyric Verbatim can be wrapped around anything that you want to match as literal code and not to function as a pattern. E.g. a_ -> b /. Verbatim[a_] :> x results in x -> b, whereas a_ -> b /. a_ :> x results in x. Sometimes you see it used where HoldPattern would be better expressive of the intent. For instance, the following are effectively equivalent: Verbatim[Integrate][f_, x_], HoldPattern[Integrate][f_, x_], HoldPattern[Integrate[f_, x_]]. The difference is what gets evaluated, but what is evaluated does not change; so they end up matching the same things. Jun 18 at 13:23
• I see, thx! Does Verbatim have a partner like Hold vs. ReleaseHold, Inactivate vs. Activate? I read the documentation but hasn't found one. Jun 20 at 12:19
• @Lilyric No, I don't think so. Usually Verbatim is on the pattern-matching side of a rule and does not propagate through a computation. Hold and Inactive are used to stop an expression from evaluation until it reaches a certain step in a computation, at which point ReleaseHold or Activate is needed. HoldPattern is similar to Verbatim in this respect. While ReleaseHold works on it, I don't recall ever doing that. If you need a way to "release" Verbatim, try something like expr /. Verbatim[Verbatim][h_] :> h. Jun 20 at 14:36

To start with, Condition has semantic meaning in Cases/MatchQ:

With[
{b = True},
Cases[{Condition[a, b], a}, Condition[a, b]]]
(* {a} *)


That explains why MatchQ[Condition[a, b], Condition[a, b]] returns False. Just for grins, let's try this:

MatchQ[3, 3 /; False]
(* False *)


Now let's work through your first example. A couple of variables to hold our expressions:

list1 = {a -> b /; c, a -> b, a};
alts = Alternatives @@ list1;


Cases[list1, alts[[1]]]
(* {b /; c} *)


What happened? Well, in Cases you can give a rule to actually replace the value that matched. alts[[1]] is a -> b /; c, so we matched on a and replaced it with b/;c. Similarly:

Cases[list1, alts[[2]]]
(* {b} *)


Next, something a bit more complicated:

Cases[list1, alts[[2 ;; 2]]]
(* {a -> b} *)


This time we matched against an Alternatives, not a Rule, so we don't do replacement. However, we did find an exact match.

Okay, moving on again:

Cases[list1, alts[[1 ;; 1]]]
(* {} *)


No matches! We're matching against Alternatives, not Rule, so we should be looking at the whole a -> b /; c expression. The problem is that the Condition still comes into play. Rather than try to explain directly, it's easier to find something that does match:

Cases[{a -> b}, Alternatives[a -> b /; True]]
(* {a -> b} *)

MatchQ[a -> b, a -> b /; True]
(* True *)


We're matching the b part as long as the Condition[b, True] is satisfied, which it is by definition. The condition of Condition[b, c] is not satisfied, so we're not matching the b.

Verbatim is used in patterns where you want to match exactly--no transformation or interpretation. So, you could try this:

Cases[list1, Alternatives @@ Verbatim /@ list1]
(* {a -> b /; c, a -> b, a} *)

• Thx for the detailed explanation! Jun 18 at 7:14