4
$\begingroup$

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?

$\endgroup$
1
  • $\begingroup$ MatchQ[f[x, y], f[x, y]] returns True whether or not f has the attribute HoldAll. $\endgroup$
    – Michael E2
    Jun 16 at 18:42

2 Answers 2

6
$\begingroup$

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  *)
$\endgroup$
5
  • 1
    $\begingroup$ 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. $\endgroup$
    – Michael E2
    Jun 16 at 18:45
  • $\begingroup$ Thx! I never used Verbatim before. Does this function have other usages besides matching rules with rules? $\endgroup$
    – lilyric
    Jun 18 at 7:20
  • $\begingroup$ @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. $\endgroup$
    – Michael E2
    Jun 18 at 13:23
  • $\begingroup$ I see, thx! Does Verbatim have a partner like Hold vs. ReleaseHold, Inactivate vs. Activate? I read the documentation but hasn't found one. $\endgroup$
    – lilyric
    Jun 20 at 12:19
  • $\begingroup$ @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. $\endgroup$
    – Michael E2
    Jun 20 at 14:36
4
$\begingroup$

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;

Start with something simpler:

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} *)
$\endgroup$
1
  • $\begingroup$ Thx for the detailed explanation! $\endgroup$
    – lilyric
    Jun 18 at 7:14

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.