# Problem with replacement rules

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.

• Just replace -> by :>, which is RuleDelayed[ ] – user18792 Dec 5 '19 at 11:21
• I tried, it but it still doesn't work unfortunately. – Einj Dec 5 '19 at 16:38
• 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[] – user18792 Dec 5 '19 at 16:46

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


whatever

Looking at the Trace of the replacement shows

Sprod["1", "2"]


ends at

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

and

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]]


False

and with the unrestricted definitions

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


True