# Why does {2, 9, 3, 16, 81, 0.09} //. {x_Integer -> Sqrt[x]} evaluate infinite times? [closed]

Here is my code.

{2, 9, 3, 16, 81, 0.09} //. {x_Integer -> Sqrt[x]}


The pop-up message ReplaceRepeated::rrlim suggests that this rule can be applied an infinite number of times.

I am supposed to get {Sqrt[2],Sqrt[3],Sqrt[3],Sqrt[2],Sqrt[3],0.09}

What's wrong with my code here?

• Hint: After the first pass, what is the head of the first list element's (Sqrt[2]) contents?
– ciao
Commented Feb 29, 2020 at 10:16
• @ciao, Power. How to make it work ? {Sqrt[2],Sqrt[3],Sqrt[3],Sqrt[2],Sqrt[3],0.09}
– kile
Commented Feb 29, 2020 at 10:18
• One way might be {y : Power[_, _] -> y, x_Integer -> Sqrt[x]} for the rules. More importantly, do you see why the example evaluates infinitely?
– ciao
Commented Feb 29, 2020 at 10:20
• @ciao,x_Integer still assumes Sqrt[2] and Sqrt[3] are Integer.
– kile
Commented Feb 29, 2020 at 10:26
• Perhaps a better response to @OkkesDulgerci would be to point out that his code changes 9 to 3, not to Sqrt[3] as desired. Commented Feb 29, 2020 at 14:36

## 2 Answers

The documentation specifically states:

You should be very careful to avoid infinite loops when you use the //. operator. The command x //. x -> x + 1 will, for example, lead to an infinite loop.

Since only the first rule that matches is applied to a given expression you can, as ciao commented, use:

{2, 9, 3, 16, 81, 0.09} //. {skip_Power :> skip, x_Integer :> Sqrt[x]}

{Sqrt[2], Sqrt[3], Sqrt[3], Sqrt[2], Sqrt[3], 0.09}


Recommended reading:

• Very nice solution, exactly as was asked in OP. Maybe one can add that some confusion arises due to the fact that Replace has levelspec option, whereas ReplaceAll and ReplceRepeated---no. Commented Mar 1, 2020 at 9:16
• A slight generalization: list //. {x_Integer :> Sqrt[x], skip_?NumericQ :> With[{x = Simplify[skip]}, If[IntegerQ[x], Sqrt[x], skip]]}. In case other numeric expression are in the original list. Commented Mar 1, 2020 at 18:04

I think the proper answer here is to use FixedPoint, because //. dives in to the expression. Sqrt[2] contains an integer inside so it replaces it over and over.

FixedPoint[Replace[#, x_Integer :> Sqrt[x], {1}] &, {2, 9, 3, 16, 81, 0.09}]

Notice that I specifically said that it should replace at level 1.

• Can you please point to the place in the documentation where it is written that //. should dive into subexpressions. Commented Feb 29, 2020 at 11:28
• It is basically doing /. repeatedly until it doesn't change any more. The documentation of /. (ReplaceAll). Which has as first line: applies a rule or list of rules in an attempt to transform each subpart of an expression expr. Commented Feb 29, 2020 at 11:30
• @yarchik "expr//.rules effectively applies /. repeatedly, until the results it gets no longer change." (Docs for ReplaceRepeated) See also the documentation for the error message Commented Feb 29, 2020 at 14:38
• @MichaelE2 Why then this {2, 9, 3, 16, 81, 0.09} //. {x_ /; (Head[x] == Integer) -> Sqrt[x]} does not work? Sorry, if it is something obvious. Commented Feb 29, 2020 at 18:12
• it works, but again, it dives deeper in to the expression because you're using //. (or /.) Commented Feb 29, 2020 at 20:54