A rule such that x+x^2/.x->0 gives x^2

The normal behaviour of ReplaceAll as in

n[1]:= x+x^2/.x->0
Out[1]= 0

makes it impossible to deal with x^1 separately.
But x^2 can be replaced as in

In[2]:= x+x^2/.x^2->0
Out[2]= x

The Replace function, operating at level 1 can do the trick

In[3]:= Replace[ x+x^2,x->0,{1}]
Out[3]= x^2

But if x has a multiplier

In[4]:= Replace[ a x+x^2,x->0,{1}]
Out[4]= a x + x^2

no level specification will replace only a x with 0.

Is there some way to deal with a x + b x^2 so that the first power term in x can be identified?

I’m not at all sure what result you want but if you want x and x^2 (or x to any power) to be treated separately, you can do something like the following:

a x + b x^2 /. {x^m_ -> y, x -> z}

which results in the following:

b y + a z

I would say:

Replace[a x + x^2, n_ x_ :> 0 /; FreeQ[n, x] \[And] FreeQ[x, n], {1}]

Where you check for an expression of the form n_ x_ where n should not contain x and vice versa.

Replace[(1 + x) x + x^2,  n_ x_ :> 0 /; FreeQ[n, x] \[And] FreeQ[x, n], {1}]

such that the above does not get transformed… In case you also consider that to be a*x then remove the condition at the end…

Thank you, Bill and Sander.

I’m trying to write a collect[eqn,{vars}] to mimic the Collect[] function that behaves as Konstantin Nosov proposed in his thread Desired Behavior Of Collect[]. Collect[eqn,x^n] will collect all powers of x, not just x^n. I’m getting close, but the default behaviour of ReplaceAll[] is causing a problem.

I’m beginning to think that a new function, something like ReplaceVerbatim[] or ReplaceOnly[], say, could be used postfix like this:

In[1]:= a x + b x^2 ///. x->0  (*x is treated as x^1, different from x^2 *)
Out[1]= b x^2

So, I’m going to attempt to write ReplaceOnly[expr,var] and ReplaceOnly[expr,{vars}]. It might be beyond my capability, though.

Any suggestions would be welcome.

Here is the first approach:

Clear[ReplaceOnly];

ReplaceOnly[expr_,var_,subst_]:=
Module[{e,e1,e2,var?},
var?:=var^?//PowerExpand;
e:=expr/.var->var?;
e1:=e//PowerExpand;
e2:=e1/.var?->subst;
e2/.?->1
]

ReplaceOnly[expr_,{vars__},{subst__}]:=
Module[{e,e1,e2,vars?},
vars?:={vars}^?//PowerExpand;
e:=expr/.Thread[Rule[{vars},vars?]];
e1:=e//PowerExpand;
e2:=e1/.Thread[Rule[vars?,{subst}]];
e2/.?->1
]

Rather than turn the modules into an incomprehensible expression, I’ve left the steps visible.

Every variable that is to be replaced is raised to the power ?, both in the variables and the expression. Then the usual ReplaceAll can be applied, leaving no potential variables to the first power. After the substitutions, the ? is replaced by 1, erasing its presence.

ReplaceOnly[x+b x^3,x,y]
b x^3+y
ReplaceOnly[x+b x^3,x^3,y]
x+b y
ReplaceOnly[x+b x^3+3 y + 2 y^4,{x,x^3,y},{X,X^3,Y}]
X+b X^3+2 y^4+3 Y

Now to figure out how to turn this into a infix operator ///.

A notebook is attached.

A further refinement:

ReplaceOnly[expr_, var_ -> subst_] :=
 Module[{e, e1, e2, var?},
  var? := var^? // PowerExpand;
  e := expr /. var -> var?;
  e1 := e // PowerExpand;
  e2 := e1 /. var? -> subst;
  e2 /. ? -> 1
  ]

ReplaceOnly[expr_, {vars__} -> {subst__}] :=
 Module[{e, e1, e2, vars?},
  vars? := {vars}^? // PowerExpand;
  e := expr /. Thread[Rule[{vars}, vars?]];
  e1 := e // PowerExpand;
  e2 := e1 /. Thread[Rule[vars?, {subst}]];
  e2 /. ? -> 1
  ]

This matches ReplaceAll inputs. Going to need that for ///.

Notebook attached.

I just voted this one up because of the usage of hearts…

Thanks, Sander. My first vote!

This might be the final post. Some rigorous testing needs to be done, so if you can find an error, please respond.

The last post was in error about the correct format. Here is the way it looks now:

    ReplaceOnly[expr_, var_ -> subst_] :=
     Module[{e, e1, e2, var?},
      var? := var^? // PowerExpand;
      e := expr /. var -> var?;
      e1 := e // PowerExpand;
      e2 := e1 /. var? -> subst;
      e2 /. ? -> 1
      ]
    
    ReplaceOnly[expr_, {rules__}] :=
     Module[{e, e1, e2, vars, subst, vars?},
      vars := First[List @@ (Thread[{rules}, Rule])];
      subst := Last[List @@ (Thread[{rules}, Rule])];
      vars? := vars^? // PowerExpand;
      (*Print["1   ",vars?,subst];*)
      e := expr /. Thread[Rule[vars, vars?]];
      (*Print["2   ",Thread[Rule[vars,vars?]]];*)
      (*Print["3   ",e];*)
      e1 := e // PowerExpand;
      e2 := e1 /. Thread[Rule[vars?, subst]];
      e2 /. ? -> 1
      ]

It turns out that the proposed ///. operator doesn’t work because it is parsed into // /. I tried . but that is the prefix for an octal number. Suggestions for other operators ?

    <<Notation`
    InfixNotation[>>>,ReplaceOnly]

(*testing*)
    3 x^3+x +y>>>(x->ss)
    ss+3 x^3+y
    3 x^3+x +y>>>{x->ss,x^3->XX,y->x}
    ss+x+3 XX

Unfortunately, when using a single replacement, the rhs has to be parenthesized. This probably has something to do with precedence. Any ideas?