1
$\begingroup$

I am trying to apply a series of individual rules onto an expression sequentially, but also not have to write out the repeated ReplaceAll functions each time I want to perform the same series of rules.

Here's an illustrative example of my problem:

(* r1, r2 and r3 are the individual rule transformations *)
r1[a_] := {a :> 3 a};
r2[a_] := {a :> -a};
r3[a_] := {a :> a + 1};

(* Try to define a single rule operator which applies rules in a given order *)
rall[a_] := r1[a] /. r2[a] /. r3[a];

(* Ideal answer is given by *)
a /. r1[a] /. r2[a] /. r3[a]

Which evaluates to -3(a+1), applying each rule sequentially, whereas

a /. rall[a]

evaluates to a, having not applied any of the rules. This can be understood, since rall[a] evaluates to {-a-1:>3(-(a+1))}, having applied the rules r2[a] and r3[a] to the initial r1[a] term, not just the rhs instances of a in the rules expressions.

How can I build a composite rule function that achieves my aim? Is there a way to delay the evaluation of the rules stated in rall[a] until I apply it to a variable?

$\endgroup$
2
  • $\begingroup$ Functions are already based on replacement rules. You could write: r1[a_] := 3a; r2[a_] := -a; r3[a_] := a+1; rall[a_] := r3@r2@r1[a], then try and evaluate rall[a]. $\endgroup$
    – MarcoB
    Jun 17, 2015 at 21:51
  • $\begingroup$ Well, obviously the logic of defining rall[a_] as you did it, is flawed. You instruct the second and third rule to act on the first, instead of all rules to act on some expression - and that is what you get. Why not doing something like rall[a_] := Function[expr, expr /. r1[a] /. r2[a] /. r3[a]];, and then rall[a][a]? $\endgroup$ Jun 17, 2015 at 21:51

1 Answer 1

4
$\begingroup$

Maybe with the help of Fold or FoldList :

See what happens here:

FoldList[#1 /. #2 &, a, {r1[a], r2[a], r3[a]}]

{a, 3 a, -3 a, -3 (1 + a)}

Replace FoldList with Fold to get directly the last result.

In other words:

rall[a_] := Fold[#1 /. #2 &, a, {r1[a], r2[a], r3[a]}]

then

rall[a]

-3 (1 + a)

$\endgroup$
2
  • $\begingroup$ That's great. How do I extend this to multiple rule arguments, say for r1[a,b]? I tried some variations on syntax such as Fold[{#1,#2}/.#3 &[a,b], {r1[a,b],r2[a,b],r3[a,b]}] but can't seem to find the correct extension. $\endgroup$ Jun 18, 2015 at 8:49
  • $\begingroup$ @SLesslyTall Simply Fold[#1 /. #2 &, expr[a,b], {r1[a, b], r2[a, b], r3[a, b]}] where expr[a,b] stands for any initial expression you want to replace, for example Sin[a]^b, or any list {a,b,a*b^2,...}, ... $\endgroup$
    – SquareOne
    Jun 18, 2015 at 12:32

Your Answer

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

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