5
$\begingroup$

I would like to release only the rules in an expression that held. Is that possible?

ClearAll[a, b, c, expr];
expr = HoldForm[a = 2 b c /. c -> 5]
(* a=2 b c/. c->5 *)

I can release the whole expression:

ReleaseHold@expr
(* 10 b *)

But I would like to do this:

ReleasePattern@expr
(* a = 10 b *)

Unfortunately there is no ReleasePattern command. Is it possible to do this by other means?

$\endgroup$
3
  • $\begingroup$ You seem to really need this. Borderline duplicate, but I hesitate to claim that it is full dupe. Let's see what others think. $\endgroup$ Oct 16 '16 at 20:15
  • $\begingroup$ @LeonidShifrin I too am on the fence about whether this one is a duplicate. Whoops, just slid onto one side of the fence... :) $\endgroup$
    – WReach
    Oct 16 '16 at 22:15
  • $\begingroup$ @WReach Actually, IMO it's great that you did. $\endgroup$ Oct 16 '16 at 22:41
5
$\begingroup$

We can define a helper function that will release any component of a held expression that matches a particular pattern:

releaseHeldMatches[patt_] := ReplaceAll[p:patt :> RuleCondition[p]]

We can then use it to release the ReplaceAll that appears in the expression from the question:

expr // releaseHeldMatches[_ReplaceAll]
(* HoldForm[a = 10 b] *)

The function releasePattern from the question can then be defined thus:

releasePattern = releaseHeldMatches[_ReplaceAll];

expr // releasePattern
(* HoldForm[a = 10 b] *)

Both of these work upon some part of the expression that matches a pattern. Perhaps we would like to release a part found at a particular index instead:

releaseAt[i__][expr_] := ReplacePart[expr, {i} -> expr[[i]]]

expr // releaseAt[1, 2]
(* HoldForm[a = 10 b] *)

Note: one might object to releaseHeldMatches operating upon level zero of the held expression, or lament that extracted subexpressions may be held in their own right. I purposely choose not to worry about either of these contingencies, but should one care:

releaseHeldMatchesPedantic[patt_, expr_] :=
    Replace[expr, p: patt :> RuleCondition[ReleaseHold[p]], {1, Infinity}]
releaseHeldMatchesPedantic[patt_][expr_] :=
    releaseHeldMatchesPedantic[patt, expr]
$\endgroup$
4
  • $\begingroup$ Having specialized and detailed answer here is probably much better than just announcing this as a dupe. +1 as always. $\endgroup$ Oct 16 '16 at 22:40
  • $\begingroup$ @WReach - Thanks for the answer. I had trouble making releaseAt work with a different expression: expr2=(f[a+2 b c]==g[a,c])/. c->5; Changing the arguments from [1,2] to several other alternatives did not work. Also, is there a way to make releasePatterns work with selected patterns like c->5, leaving others unevaluated? $\endgroup$
    – Soldalma
    Oct 17 '16 at 15:35
  • $\begingroup$ @WReach - Sorry, I forgot the HoldForm around the code for expr2 in my previous comment. $\endgroup$
    – Soldalma
    Oct 17 '16 at 15:42
  • $\begingroup$ If we have expr3 = HoldForm[(f[a+2 b c] /. a -> 2) == (g[a,c]/. c -> 5)] and define releaseCOnly = releaseHeldMatches[HoldPattern[_ /. c-> 5]];, then we can write expr3 // releaseCOnly to get HoldForm[(f[a + 2*b*c] /. a -> 2) == g[a, 5]]. $\endgroup$
    – WReach
    Oct 17 '16 at 15:54

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.