Simplification with side relations (which Markiyan demonstrates in another Answer) can be an easy way to get such an effect. It's a good answer.

But it can also be noted that there are times and other examples when some of the simplifications done to an expression might not be what is wanted. Consider the case that the input expression is conjugate(z)*z^2*(ln(2*z) and one wishes to replace conjugate(z)*z while also leaving ln(2*z) intact. In other words, the following *might* not be what is wanted,

simplify( conjugate(z)*z^2*(ln(2*z)), {z*conjugate(z)=x} );
(ln(2) + ln(z)) x z

And of course there are related problematic examples where some undesired aspect of simplification is not easily undone after the fact (with `combine` or what have you). In other words, the need for (only) plain substitution is not obviated by fixing the above simplistic example by calling something like `combine` on the result.

So it might be that for some examples one wants just the substitution. And `algsubs` goes awry trying to figure out where and whether z*conjugate(z) is "present". So it's natural to still ask whether `applyrule` could work here.

A difficulty is that `applyrule` does not see z*conjugate(z) as being present within conjugate(z)*z^2 say, and other related situations. An alternative for the rule used might be,

T:=ee->applyrule(z^(m::posint)*conjugate(z)^(n::posint)
= x*z^(m-1)*conjugate(z)^(n-1),ee):

And a few rudimentary examples to compare with the simplification with side effects might include,

R:=ee->simplify(ee,{z*conjugate(z)=x}):
f1:=conjugate(z)^2*z^2:
T(f1), R(f1);
2 2
x , x
T(conjugate(z)*z^2), R(conjugate(z)*z^2);
x z, x z
T(conjugate(z)^5*z^2), R(conjugate(z)^5*z^2);
3 3
2 _ 2 _
x z , x z
T(conjugate(z)/z^2), R(conjugate(z)/z^2); # no change expected
_ _
z z
--, --
2 2
z z

But now we might notice that the above does not handle the case where the z*conjugate(z) appears in the denominator. We could try and clean that up crudely, by just repeating the process.

T:=ee->applyrule(z^(m::negint)*conjugate(z)^(n::negint)
= 1/(x/(z^(m+1)*conjugate(z)^(n+1))),
applyrule(z^(m::posint)*conjugate(z)^(n::posint)
= x*z^(m-1)*conjugate(z)^(n-1),ee)):
T(1/(conjugate(z)*z^2)), R(1/(conjugate(z)*z^2));
1 1
---, ---
x z x z
T(1/(conjugate(z)^2*z^3)), R(1/(conjugate(z)^2*z^3));
1 1
----, ----
2 2
x z x z

And we can see how the two approaches differ with respect to leaving other terms unchanged (or not), for the example previously mentioned,

expr:=conjugate(z)*z^2*(ln(2*z)):
T(expr), R(expr);
x z ln(2 z), (ln(2) + ln(z)) x z

It's unfortunate that `applyrule` is not as robust and easy to use as it might be, since it does seem to fulfil at least some needed functionality. (I would not be very surprised if the usage examples I gave above fall down on some related, problematic examples.)

acer