Repository: sympy/sympy

Issue:
limit((log(E + 1/x) - 1)**(1 - sqrt(E + 1/x)), x, oo) returns 0 instead of oo
Originally reported on https://groups.google.com/g/sympy/c/wV0FsQ86ooE/m/TliUrKjMrhkJ
I came across an issue which is similar to the one above , I searched whether any similar/related issue has been reported already and found one on the google groups . `gruntz` is responsible for this .Not too sure about the fix though !
```
>>> x = Symbol('x', real=True, positive=True)
>>> m = Symbol('m', real=True, positive=True)
>>> limit((log(E + 1/x) - 1)**(1 - sqrt(E + 1/x)), x, oo)
0
>>> gruntz((log(E + 1/x) - 1)**(1 - sqrt(E + 1/x)), x, oo)
0
```
Close relatives of the expression work fine 
```
>>> limit((log(E + 1/x) )**(1 - sqrt(E + 1/x)), x, oo)
1
>>> limit((log(E + 1/x) - 1)**(- sqrt(E + 1/x)), x, oo)
oo
```
Pic from wolfram for reference
![image](https://user-images.githubusercontent.com/87052487/151969221-3d80ddcf-d911-4712-a02c-eb7743e224d5.png)

As this has already been reported on the google group , it might have been raised before . Though I did a basic check for myself, if found to be reported earlier ...feel free to close . Thanks!


Discussion:
sympy-bot: :white_check_mark:

Hi, I am the [SymPy bot](https://github.com/sympy/sympy-bot). I'm here to help you write a release notes entry. Please read the [guide on how to write release notes](https://github.com/sympy/sympy/wiki/Writing-Release-Notes).



Your release notes are in good order.

Here is what the release notes will look like:
* series
  * Fixed issues regarding auto-simplification of expressions of the form `exp(log(...))` in gruntz. ([#26848](https://github.com/sympy/sympy/pull/26848) by [@arnabnandikgp](https://github.com/arnabnandikgp))

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.14.

<details><summary>Click here to see the pull request description that was parsed.</summary>

    <!-- Your title above should be a short description of what
    was changed. Do not include the issue number in the title. -->

    #### References to other Issues or PRs
    <!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
    format, e.g. "Fixes #1234" (see
    https://tinyurl.com/auto-closing for more information). Also, please
    write a comment on that issue linking back to this pull request once it is
    open. -->
    Fixes #22982
    Fixes #15323 

    #### Brief description of what is fixed or changed
    SymPy currently in many cases auto simplifes terms of the form exp(log(...)), this behaviour causes problems with workings of gruntz as this complicates the comparison of terms in their respective comparability classes. This branch solves this anomaly by ensuring that every symbolic pow term is expressed in  the form `exp(exp*log(base))`
    #### Other comments


    #### Release Notes

    <!-- Write the release notes for this release below between the BEGIN and END
    statements. The basic format is a bulleted list with the name of the subpackage
    and the release note for this PR. For example:

    * solvers
      * Added a new solver for logarithmic equations.

    * functions
      * Fixed a bug with log of integers. Formerly, `log(-x)` incorrectly gave `-log(x)`.

    * physics.units
      * Corrected a semantical error in the conversion between volt and statvolt which
        reported the volt as being larger than the statvolt.

    or if no release note(s) should be included use:

    NO ENTRY

    See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
    information on how to write release notes. The bot will check your release
    notes automatically to see if they are formatted correctly. -->

    <!-- BEGIN RELEASE NOTES -->
    * series
      * Fixed issues regarding auto-simplification of expressions of the form `exp(log(...))` in gruntz.
    <!-- END RELEASE NOTES -->


</details><p>

arnabnandikgp: ping @anutosh491 and @oscarbenjamin for reviews.

oscarbenjamin: I think this looks reasonable.
arnabnandikgp: I think this is ready to go, if there aren't any other concerns.
oscarbenjamin: I was hoping that @anutosh491 would give the final review.

The failing numpy job is unrelated (gh-26862).
github-actions[bot]: Benchmark results from GitHub Actions

Lower numbers are good, higher numbers are bad. A ratio less than 1
means a speed up and greater than 1 means a slowdown. Green lines
beginning with `+` are slowdowns (the PR is slower then master or
master is slower than the previous release). Red lines beginning
with `-` are speedups.

Significantly changed benchmark results (PR vs master)
```diff

```
Significantly changed benchmark results (master vs previous release)
```diff

```
Full benchmark results can be found as artifacts in GitHub Actions
(click on checks at the top of the PR).
anutosh491: I think this is ready now. Can you squash the commits too ? @arnabnandikgp 
oscarbenjamin: Looks okay to me.
arnabnandikgp: I do not know if the slow test failing is related to this PR. let me resolve the conflicts and re-run the tests.

Patch:
diff --git a/sympy/core/expr.py b/sympy/core/expr.py
index a29b829801..f502625c7e 100644
--- a/sympy/core/expr.py
+++ b/sympy/core/expr.py
@@ -3241,7 +3241,8 @@ def aseries(self, x=None, n=6, bound=0, hir=False):
             logw = log(1/res)
 
         s = func.series(k, 0, n)
-
+        from sympy.core.function import expand_mul
+        s = expand_mul(s)
         # Hierarchical series
         if hir:
             return s.subs(k, exp(logw))
diff --git a/sympy/series/gruntz.py b/sympy/series/gruntz.py
index 407df70fdc..0bf3bf3e50 100644
--- a/sympy/series/gruntz.py
+++ b/sympy/series/gruntz.py
@@ -118,7 +118,7 @@
 """
 from functools import reduce
 
-from sympy.core import Basic, S, Mul, PoleError, expand_mul
+from sympy.core import Basic, S, Mul, PoleError
 from sympy.core.cache import cacheit
 from sympy.core.intfunc import ilcm
 from sympy.core.numbers import I, oo
@@ -550,6 +550,11 @@ def mrv_leadterm(e, x):
     #
     w = Dummy("w", positive=True)
     f, logw = rewrite(exps, Omega, x, w)
+
+    # Ensure expressions of the form exp(log(...)) don't get simplified automatically in the previous steps.
+    # see: https://github.com/sympy/sympy/issues/15323#issuecomment-478639399
+    f = f.replace(lambda f: f.is_Pow and f.has(x), lambda f: exp(log(f.base)*f.exp))
+
     try:
         lt = f.leadterm(w, logx=logw)
     except (NotImplementedError, PoleError, ValueError):
@@ -657,7 +662,7 @@ def rewrite(e, Omega, x, wsym):
             if not isinstance(rewrites[var], exp):
                 raise ValueError("Value should be exp")
             arg = rewrites[var].args[0]
-        O2.append((var, exp((arg - c*g.exp).expand())*wsym**c))
+        O2.append((var, exp((arg - c*g.exp))*wsym**c))
 
     # Remember that Omega contains subexpressions of "e". So now we find
     # them in "e" and substitute them for our rewriting, stored in O2
@@ -688,7 +693,6 @@ def rewrite(e, Omega, x, wsym):
     # -exp(p/(p + 1)) + exp(-p**2/(p + 1) + p). No current simplification
     # methods reduce this to 0 while not expanding polynomials.
     f = bottom_up(f, lambda w: getattr(w, 'normal', lambda: w)())
-    f = expand_mul(f)
 
     return f, logw
 


Test patch:
diff --git a/sympy/series/tests/test_aseries.py b/sympy/series/tests/test_aseries.py
index 055d6b8aef..cae0ac0a43 100644
--- a/sympy/series/tests/test_aseries.py
+++ b/sympy/series/tests/test_aseries.py
@@ -1,6 +1,5 @@
 from sympy.core.function import PoleError
 from sympy.core.numbers import oo
-from sympy.core.singleton import S
 from sympy.core.symbol import Symbol
 from sympy.functions.elementary.exponential import (exp, log)
 from sympy.functions.elementary.miscellaneous import sqrt
@@ -32,9 +31,9 @@ def test_simple():
 
     e3 = lambda x:exp(exp(exp(x)))
     e = e3(x)/e3(x - 1/e3(x))
-    assert e.aseries(x, n=3) == 1 + exp(x + exp(x))*exp(-exp(exp(x)))\
-            + ((-exp(x)/2 - S.Half)*exp(x + exp(x))\
-            + exp(2*x + 2*exp(x))/2)*exp(-2*exp(exp(x))) + O(exp(-3*exp(exp(x))), (x, oo))
+    assert e.aseries(x, n=3) == 1 + exp(2*x + 2*exp(x))*exp(-2*exp(exp(x)))/2\
+            - exp(2*x + exp(x))*exp(-2*exp(exp(x)))/2 - exp(x + exp(x))*exp(-2*exp(exp(x)))/2\
+            + exp(x + exp(x))*exp(-exp(exp(x))) + O(exp(-3*exp(exp(x))), (x, oo))
 
     e = exp(exp(x)) * (exp(sin(1/x + 1/exp(exp(x)))) - exp(sin(1/x)))
     assert e.aseries(x, n=4) == -1/(2*x**3) + 1/x + 1 + O(x**(-4), (x, oo))
diff --git a/sympy/series/tests/test_gruntz.py b/sympy/series/tests/test_gruntz.py
index 4565c87608..c11d243c7c 100644
--- a/sympy/series/tests/test_gruntz.py
+++ b/sympy/series/tests/test_gruntz.py
@@ -5,7 +5,6 @@
 from sympy.functions.elementary.exponential import (exp, log)
 from sympy.functions.elementary.miscellaneous import sqrt
 from sympy.functions.elementary.trigonometric import (acot, atan, cos, sin)
-from sympy.functions.elementary.complexes import sign as _sign
 from sympy.functions.special.error_functions import (Ei, erf)
 from sympy.functions.special.gamma_functions import (digamma, gamma, loggamma)
 from sympy.functions.special.zeta_functions import zeta
@@ -314,7 +313,7 @@ def test_rewrite1():
     e = exp(x + 1/x)
     assert mrewrite(mrv(e, x), x, m) == (1/m, -x - 1/x)
     e = 1/exp(-x + exp(-x)) - exp(x)
-    assert mrewrite(mrv(e, x), x, m) == (1/(m*exp(m)) - 1/m, -x)
+    assert mrewrite(mrv(e, x), x, m) == ((-m*exp(m) + m)*exp(-m)/m**2, -x)
 
 
 def test_rewrite2():
@@ -329,7 +328,7 @@ def test_rewrite3():
     e = exp(-x + 1/x**2) - exp(x + 1/x)
     #both of these are correct and should be equivalent:
     assert mrewrite(mrv(e, x), x, m) in [(-1/m + m*exp(
-        1/x + 1/x**2), -x - 1/x), (m - 1/m*exp(1/x + x**(-2)), x**(-2) - x)]
+        (x**2 + x)/x**3), -x - 1/x), ((m**2 - exp((x**2 + x)/x**3))/m, x**(-2) - x)]
 
 
 def test_mrv_leadterm1():
@@ -404,7 +403,7 @@ def test_gruntz_I():
     assert gruntz(I*x, x, oo) == I*oo
     assert gruntz(y*I*x, x, oo) == y*I*oo
     assert gruntz(y*3*I*x, x, oo) == y*I*oo
-    assert gruntz(y*3*sin(I)*x, x, oo).simplify().rewrite(_sign) == _sign(y)*I*oo
+    assert gruntz(y*3*sin(I)*x, x, oo) == y*I*oo
 
 
 def test_issue_4814():
diff --git a/sympy/series/tests/test_limits.py b/sympy/series/tests/test_limits.py
index ac28ad3eaf..4f2760f8e8 100644
--- a/sympy/series/tests/test_limits.py
+++ b/sympy/series/tests/test_limits.py
@@ -1417,3 +1417,10 @@ def test_issue_26250():
 def test_issue_26916():
     assert limit(Ei(x)*exp(-x), x, +oo) == 0
     assert limit(Ei(x)*exp(-x), x, -oo) == 0
+
+
+def test_issue_22982_15323():
+    assert limit((log(E + 1/x) - 1)**(1 - sqrt(E + 1/x)), x, oo) == oo
+    assert limit((1 - 1/x)**x*(log(1 - 1/x) + 1/(x*(1 - 1/x))), x, 1, dir='+') == 1
+    assert limit((log(E + 1/x) )**(1 - sqrt(E + 1/x)), x, oo) == 1
+    assert limit((log(E + 1/x) - 1)**(- sqrt(E + 1/x)), x, oo) == oo