I would like to apply substitution rules to an object I have defined, but I must be doing something wrong. Here are the relevant pieces of code. First I have defined a function Vec which is:

Vec[x_, y_String] := Subscript[Style[x, Italic, Bold], y]

Then I defined a function Sprod which is:

Sprod[x_String, y_String] := Vec[q, x]\[CenterDot]Vec[q, y]

Now I would like to apply the following substitution rule, for example:

Sprod["1", "2"] /. Sprod[i_String, j_String] -> whatever

However, when I do that, nothing happens. Does anyone have an idea of why?

I have tried the explicit rule

Sprod["1", "2"] /. Sprod["1", "2"] -> whatever

which works just fine. However, I'd like to write something a bit more general.

  • 2
    $\begingroup$ Just replace -> by :>, which is RuleDelayed[ ] $\endgroup$
    – Acus
    Dec 5, 2019 at 11:21
  • $\begingroup$ I tried, it but it still doesn't work unfortunately. $\endgroup$
    – Einj
    Dec 5, 2019 at 16:38
  • $\begingroup$ Since your have a definition Sprod[x_String, y_String] := Vec[q, x][CenterDot]Vec[q, y] after entering Sprod["1", "2"] your get Vec[q, "1"][CenterDot]Vec[q, "2"]. So, then there is nothing to replace. You can wrap expression with Hold: Hold[Sprod["1", "2"] ]/. Sprod[i_String, j_String] :> whatever and then after replacement use ReleaseHold[] $\endgroup$
    – Acus
    Dec 5, 2019 at 16:46

1 Answer 1


Because Vec and Sprod have restrictions on the heads of the arguments (namely to be strings), the lhs of the replacement doesn't evaluate because i_String has the Pattern head.

If we remove the head restrictions, it works just fine

Vec[x_, y_] := Subscript[Style[x, Italic, Bold], y]
Sprod[x_, y_] := Vec[q, x]\[CenterDot]Vec[q, y]
Sprod["1", "2"] /. Sprod[i_String, j_String] -> whatever


Looking at the Trace of the replacement shows

Sprod["1", "2"]

ends at

Subscript[q, 1][CenterDot]Subscript[q, 2]


Sprod[i_String, j_String]

ends at

Subscript[q, i_String][CenterDot]Subscript[q, j_String]

which yields a matching format/structure that can be replaced.

Instead of always using Trace, you can use MatchQ in debugging replacement (or any pattern matching) issues.

With the original definitions

MatchQ[Sprod["1", "2"], Sprod[i_String, j_String]]


and with the unrestricted definitions

MatchQ[Sprod["1", "2"], Sprod[i_String, j_String]]



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.