6
$\begingroup$

Seemingly a relatively simple problem, I can't seem to find a solution...

I want to build a pattern that will match any symbol whose name starts with V, and is elevated at any power. Something on the line of:

MatchQ[#1, (V1 | V2 | V3)^_.] & /@ {V1, V1^2, V2}

That returns true for each of the entries. I haven't found a way to put constrains on the symbol name, if not by using SymbolName[] and working with string patterns:

MatchQ[#1, (_)?(StringMatchQ[SymbolName[#1], "V" ~~ __] &)^_.] & /@ {V1, V1^2, V2}

However, it doesn't look exactly beautiful... (only to me?) :-) Is there a more compact and elegant way of putting constraints on a symbol name? I'm feeling like I'm totally missing a very obvious function that would do that...

$\endgroup$
7
$\begingroup$

I believe that if you want to match a Symbol by its constituent characters that you do need to use string patterns, therefore your solution is reasonable. I recommend a variation:

p2 = s_Symbol^_. /; StringMatchQ[SymbolName[s], "V*"]

s_Symbol makes sure that the expression that is passed to SymbolName is actually a Symbol. I also find it somewhat more readable. Test:

MatchQ[p2] /@ {V1, V1^2, V2, x^2, y}   (* v10 operator form syntax *)
{True, True, True, False, False}

The use of Condition rather than PatternTest makes it easier if you may be working with held expressions and need to add Unevaluated:

p3 = s_Symbol^_. /; StringMatchQ[SymbolName[Unevaluated@s], "V*"]

This allows:

V1 = "Fail!";
Cases[Hold[V1, V1^2, V2, x^2, y], x : p2 :> Hold[x]]
V1 =.;
{Hold[V1], Hold[V1^2], Hold[V2]}

To make the code a bit prettier consider an abstraction such as:

symPat = s_Symbol /; StringMatchQ[SymbolName[Unevaluated@s], #] &;

Then simply:

Cases[{V1, V1^2, V2, x^2, y}, symPat["V*"]^_.]
{V1, V1^2, V2}
$\endgroup$
  • $\begingroup$ Thank you, not only for he answer to the point, but for the additional info as well. $\endgroup$ – Giacomo Ciani Feb 18 '15 at 22:45
  • $\begingroup$ Just for the sake of sharing, what drew me off was the (semi-)unconscious and naive belief that by writing 'MatcQ[V1, V1]' (that I never really wrote) I was comparing the names of the symbols. Thus my reasoning was: if I can compare entire names, and "any" by using _ (sort of * for symbol names), then there musts be a syntax to compare only part of the name (eventually completed by wildcards). Now I realize that 'MatchQ' compares the content of the symbols, hence the need to use SymbolName if you want to put constraints on the name... probably this was very clear to everyone except me! :-) $\endgroup$ – Giacomo Ciani Feb 19 '15 at 3:34

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.