# How can I identify symbols within an expression which are wrapped in a local HoldForm?

Let's assume a=b, that is, a has value b. In a given expression like e.g.

a + i + HoldForm[a + k] + l

I would like to substitute - while the whole expression is being held globally - every symbol by its value, unless the symbol is wrapped in a local HoldForm. The form

HoldForm[a + i + HoldForm[a + k] + l] /. s_Symbol :> RuleCondition[s,ValueQ[s]]

returns b + i + (b + k) + l,

that is, all symbols of the expression have been substituted by their values, including the second appearance of a. How can I identify symbols which are wrapped in a local HoldForm and exclude them from this substitution procedure? Or do I have to take a completely different approach?

Thanks for help!

• DeveloperReplaceAllUnheld[Unevaluated[a + i + HoldForm[a + k] + l], s_Symbol :> RuleCondition[s, ValueQ[s]]] would probably do the job. But what you ask is so incredibly clumsy, I recommend you rethink your code in the first place. – QuantumDot Jan 26 '20 at 20:39
• Thanks. This goes into the right direction, but I need to keep the outer HoldForm. The Unevaluated is not enough. Except for the substitutions mentioned, no evaluation of the expression should take place. – Roland Salz Jan 26 '20 at 21:52

ReplaceAll works top-down, so you can add a rule to your replacement to leave HoldForm objects alone. Assuming the outer Hold wrapper isn't HoldForm you could do:

held = Hold[a + i + HoldForm[a + k] + l];
rule = {h_HoldForm :> h, HoldPattern[s_Symbol] :> RuleCondition[s]};

held /. rule


Hold[b + i + HoldForm[a + k] + l]

If the outer Hold wrapper is a HoldForm, then you would need to change the wrapper before applying the above rule, so you could do something like:

held = HoldForm[a + i + HoldForm[a + k] + l];

Apply[HoldForm] @ ReplaceAll[rule] @ Apply[Hold] @ held
`

HoldForm[b + i + HoldForm[a + k] + l]

• Thanks a lot. This is exactly what I was looking for. And I learned a lot from your answer, too. – Roland Salz Jan 27 '20 at 19:04