Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I make a replacement rule that will only be applied to those parts of an expression that will not break a condition placed on the whole expression?

For example, suppose I have $\frac{xy}{(x-y)(x+y)}$ and I want to change $y$ to $x$ getting the result $\frac{x^2}{(x-y)2x}$; i.e., without turning original expression into infinity. Further, I don't want the replacement to raise warnings or errors.

At the least, I need a way to do a replacement just once, which seems like it should be very easy, but I have no idea how to do it.

I came up with

ReplaceOnce[expr_, rule_Rule] := MapAt[# /. rule &, expr, Position[expr, rule[[1]]][[1]]]

How can I get to my goal from here?

share|improve this question
I don't think this is well specified. For example, what if by turning some subset of the "x" you get the warning but with some others not, how do you decide which changes you want? – Rojo Mar 2 '13 at 16:07
Or you want "find the x in whatever order and one by one try changing them and checking if the result is valid"? – Rojo Mar 2 '13 at 16:07
@Rojo One instance will be sufficient but if it will return every possible valid result that would be awesome. – swish Mar 2 '13 at 16:11
up vote 3 down vote accepted

Not perfect, but a start (I cannot quickly add a working FixedPoint at the end) :

   repl[expr_, rule_Rule] := Module[{ex, fun}, 
           fun[ex_] := Union[Flatten[Quiet[Select[
                      (ReplacePart[ex, #1 -> rule[[2]]] & ) /@ 
                          rule[[1]]], FreeQ[#1, ComplexInfinity] & ]]]]; 
            Union[Flatten[fun /@ fun[expr]]]]; 
    repl[expr, y -> x]

(* ==> *)

{x/(2 (x - y))}
share|improve this answer

Finally made some progress:

ReplaceOnce[expr_, rule_Rule] :=
  MapAt[# /. rule &, expr, #] & /@ Position[expr, rule[[1]]]

ReplaceIf[expr_, rule_Rule, cond_] := 
    Flatten[(Select[ReplaceOnce[#, rule], cond]) & /@ #] &, {expr}, 
    cond[#] && # != {} &, 1, \[Infinity], -1] // Quiet // 

ReplaceIf[(x y)/((x + y) (x - y)), y -> x, # =!= ComplexInfinity &]
(*{x/(2 (x - y))}*)
share|improve this answer
If this is based on Rolf Mertig's answer, as it appears to be, you should say so. – m_goldberg Mar 2 '13 at 18:04

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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