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?

  • $\begingroup$ 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? $\endgroup$ – Rojo Mar 2 '13 at 16:07
  • $\begingroup$ Or you want "find the x in whatever order and one by one try changing them and checking if the result is valid"? $\endgroup$ – Rojo Mar 2 '13 at 16:07
  • $\begingroup$ @Rojo One instance will be sufficient but if it will return every possible valid result that would be awesome. $\endgroup$ – swish Mar 2 '13 at 16:11

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))}
|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))}*)
|improve this answer|||||
  • $\begingroup$ If this is based on Rolf Mertig's answer, as it appears to be, you should say so. $\endgroup$ – m_goldberg Mar 2 '13 at 18:04

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.