Group Abstract Group Abstract

Message Boards Message Boards

0
|
811 Views
|
5 Replies
|
8 Total Likes
View groups...
Share
Share this post:

How to reproduce the behavior of MemberQ[{a, b}, a] using MatchQ instead

Posted 4 months ago

I have been thinking how MemberQ is a sort of special case of MatchQ. MemberQ assumes a list, rather than simply a pattern, as MatchQ does -- as its second argument. For example:

MemberQ[{a, b}, a]
MatchQ[{a, b}, {___, a, ___}]
MatchQ[{a, b}, {___, ___, a, ___, ___}]
MatchQ[{a, b}, List[___, a, ___]]
MatchQ[{a, b}, List[___, ___, a, ___, ___]]

(* OUTPUT: *)
(* True *)
(* True *)
(* True *)
(* True *)
(* True *)

Is there any way to write the pattern in MatchQ without explicitly specifying the List? I'm thinking of something like the following: MatchQ[{a, b}, ___ ~~ a ~~ ___]

...but that's incorrect syntax (and returns False) because the use of ~~ implies a StringExpression, and {a, b} is clearly not a StringExpression. So, how can I write a pattern representing "any subexpression containing the symbol a anywhere"?

I could accomplish this using the resource function ContainsQ:

ResourceFunction["ContainsQ"][{a, b}, a]

(* OUTPUT: *)
(* True *)

But what is the built-in way to do this?

Looking at the source notebook for the resource function ContainsQ, I see that the definition of ContainsQ is simply:

ContainsQ[args___] := (Needs["GeneralUtilities`"]; GeneralUtilities`ContainsQ[args])
POSTED BY: Andrew D
5 Replies

Is _[___, a, ___]_ a regex-like syntax?

It's a good idea to examine the FullForm of things when trying to figure out pattern-matching:

FullForm[ _[___,a,___]_ ]
(*  Times[Blank[], Blank[][BlankNullSequence[],a,BlankNullSequence[]]]  *)

Since Blank[] and _ are the same, and BlankNullSequence[] and ___ are the same, the form can be written as the following, using * to indicate the head Times:

_ * _[___, a, ___]

It is probably clear that _[___, a, ___] matches any expression with any head and a as one of its arguments, like Power[x, a] in the test expression Times[Power[x, a], Power[y, b], Power[z, c]]. Probably less clear are the implications for pattern-matching because Times has the attributes Flat and Orderless. The test expression Times[Power[x, a], Power[y, b], Power[z, c]] is equivalent to

Times[ Times[Power[y, b], Power[z, c]], Power[x, a] ]

And therefore, the blank _ before the Times symbol * can match Times[Power[y, b], Power[z, c]] while the _[___, a, ___] after the Times symbol matches the other factor Power[x, a]. This is why one gets

MatchQ[Times[Power[x, a], Power[y, b], Power[z, c]], _[___, a, ___]_]
(*  True  *)
POSTED BY: Michael Rogers

Is there a way to write a pattern representing "any expression with a subexpression a anywhere" for use as the second argument to MatchQ?

This is a different question to the one about MemberQ equivalent codes.

I think what you want is ! FreeQ[expr, a]. It will return True if expr contains a anywhere. It is commonly used to detect the presence or absence of a pattern in an expression. There is also a useful option, FreeQ[expr, a, Heads -> False], which ignores whether the heads contain a and checks only the arguments.

POSTED BY: Michael Rogers
Posted 4 months ago
POSTED BY: Andrew D
Posted 4 months ago
POSTED BY: Eric Rimbey

Note MemberQ[a + b + c, a] returns True, so any head is allowed.

I think you want MatchQ[list, {___, a, ___}]. Or more generally, MatchQ[expr, _[___, a, ___]].

POSTED BY: Michael Rogers
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard