Repository: sympy/sympy
Pull request: [GSoC] Series: Fixing incorrect limit evaluations caused due to bug in rewriting
Fixes: #18378
Fixes: #18482 
Closes #18947

#### Brief description of what is fixed or changed

**Incorrect limit evaluation** takes place because of **bug in rewriting.**

The function `xreplace()` in the `rewrite()` function of `gruntz.py` is not substituting properly.
As a result, it has been replaced by the `subs()` function which resolves the issue.

#### Other Comments
Regression Tests have been added.


#### Release Notes


<!-- BEGIN RELEASE NOTES -->
* series
  * Replaces `xreplace()` with `subs()` in `rewrite() function of gruntz.py` resolving incorrect limit evaluations 
<!-- END RELEASE NOTES -->

Problem statement:
Invalid result in Limit
`Limit(ln(exp(3*x)+x)/ln(exp(x)+x**100), x, oo).doit()` gives the output of `9` although `3` was expected.
Sympy 1.5 on CPython 3.7.4 on Windows 10 64 bit.

Incorrect evaluation of limit
`limit(sqrt (x**2 + 6*x) + (x**3 + x**2)/(x**2 + 1),x,-oo)` is `2`
`limit((x**3 + x**2 + sqrt(x*(x + 6))*(x**2 + 1))/(x**2 + 1),x,-oo)` is `1`, but should be `-2`, since expressions are equivalent.

Hints from issue discussion:
On 1.6.dev, I get this:
```
In [10]: Limit(ln(exp(3*x)+x)/ln(exp(x)+x**100), x, oo).doit()
Out[10]: 3
```
1.5.1 also gives 9
Also, `limit((2*exp(3*x)/(exp(2*x) + 1))**(1/x),x,oo)` should be `E`.
Same as above.
`limit(x + (1 - x**2)*exp(1/x)/(x + 2),x,oo)` is `1`. `imit((x*(x + 2) + (1 - x**2)*exp(1/x))/(x + 2),x,oo)` should be `1`, but it is `2`.
No longer an issue. All limits are getting evaluated correctly. The issue can be closed @oscarbenjamin @czgdp1807. 
Most examples do seem to be fixed. When were they fixed?

This example is still incorrect:
```
In [6]: limit((2*exp(3*x)/(exp(2*x) + 1))**(1/x),x,oo)                                                                                         
Out[6]: 
 7/3
ℯ 
```
>Most examples do seem to be fixed. When were they fixed?

I myself don't know, perhaps: https://github.com/sympy/sympy/pull/18340

Merged 18 days ago, and the issue was opened 26 days ago.
> This example is still incorrect:
> 
> ```
> In [6]: limit((2*exp(3*x)/(exp(2*x) + 1))**(1/x),x,oo)                                                                                         
> Out[6]: 
>  7/3
> ℯ 
> ```

Will have to debug mrv_leadterm for this in gruntz.py
@oscarbenjamin can you give some directions on how to start with it? I have gone through all the steps which is involved in calculating the above limit but unable to get the bug
> Same as above.
> `limit(x + (1 - x**2)*exp(1/x)/(x + 2),x,oo)` is `1`. `imit((x*(x + 2) + (1 - x**2)*exp(1/x))/(x + 2),x,oo)` should be `1`, but it is `2`.

The above query is showing the expected result which is 1

Commit message: Fixing incorrect limit evaluations caused due to bug in rewriting

Patch to review:
diff --git a/sympy/series/gruntz.py b/sympy/series/gruntz.py
index e857f14c9d2f..12aa2dd467cb 100644
--- a/sympy/series/gruntz.py
+++ b/sympy/series/gruntz.py
@@ -628,7 +628,7 @@ def rewrite(e, Omega, x, wsym):
     # Some parts of sympy have difficulty computing series expansions with
     # non-integral exponents. The following heuristic improves the situation:
     exponent = reduce(ilcm, denominators, 1)
-    f = f.xreplace({wsym: wsym**exponent})
+    f = f.subs({wsym: wsym**exponent})
     logw /= exponent
 
     return f, logw
diff --git a/sympy/series/tests/test_limits.py b/sympy/series/tests/test_limits.py
index 8da9c0cbfeb4..467f2b7fd62a 100644
--- a/sympy/series/tests/test_limits.py
+++ b/sympy/series/tests/test_limits.py
@@ -652,10 +652,18 @@ def test_issue_18306():
     assert limit(sin(sqrt(x))/sqrt(sin(x)), x, 0, '+') == 1
 
 
+def test_issue_18378():
+    assert limit(log(exp(3*x) + x)/log(exp(x) + x**100), x, oo).doit() == 3
+
+
 def test_issue_18442():
     assert limit(tan(x)**(2**(sqrt(pi))), x, oo, dir='-') == AccumBounds(-oo, oo)
 
 
+def test_issue_18482():
+    assert limit((2*exp(3*x)/(exp(2*x) + 1))**(1/x), x, oo) == exp(1)
+
+
 def test_issue_18501():
     assert limit(Abs(log(x - 1)**3 - 1), x, 1, '+') == oo
 


Code review comments:
diff_hunk: @@ -652,10 +652,18 @@ def test_issue_18306():
     assert limit(sin(sqrt(x))/sqrt(sin(x)), x, 0, '+') == 1
 
 
+def test_issue_18378():
+    assert limit(log(exp(3*x) + x)/log(exp(x) + x**100), x, oo).doit() == 3
path: sympy/series/tests/test_limits.py
text: @user1:
Why `doit()`?

@author:
Yeah actually not needed. Will change it asap. Anything else?