Repository: sympy/sympy

Issue:
Comparing two operations that contain `log` sometimes leads to TypeError exception
This originally comes from PrairieLearn/PrairieLearn#4793, but it seems the problem is in sympy. We weren't able to narrow it down much further, other than to identify that this is specific to `log` (other functions like square root don't seem to have this problem).

In essence, two expressions can lead to an exception when being compared if the `log` expression is multiplied by a variable instead of a fixed coefficient.

```
Python 3.8.5 (default, May 27 2021, 13:30:53)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy.parsing.sympy_parser import parse_expr
>>> x = parse_expr("log((2*V/3-V)/C)/-(R+r)*C")
>>> y = parse_expr("log((2*V/3-V)/C)/-(R+r)*2")
>>> x.equals(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/expr.py", line 751, in equals
    constant = diff.is_constant(simplify=False, failing_number=True)
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/expr.py", line 674, in is_constant
    if b is not None and b is not S.NaN and b.equals(a) is False:
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/expr.py", line 741, in equals
    diff = factor_terms(simplify(self - other), radical=True)
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 635, in simplify
    _e = cancel(expr)
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/polys/polytools.py", line 6688, in cancel
    f = factor_terms(f, radical=True)
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/exprtools.py", line 1274, in factor_terms
    return do(expr)
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/exprtools.py", line 1271, in do
    rv = _keep_coeff(cont, p, clear=clear, sign=sign)
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/mul.py", line 2069, in _keep_coeff
    if r == int(r):
  File "/home/jonatan/.local/lib/python3.8/site-packages/sympy/core/expr.py", line 332, in __int__
    raise TypeError("can't convert %s to int" % r)
TypeError: can't convert oo to int
>>>
```

Discussion:

Patch:
diff --git a/sympy/core/mul.py b/sympy/core/mul.py
index 9933eb601a..89bfc40b05 100644
--- a/sympy/core/mul.py
+++ b/sympy/core/mul.py
@@ -2112,7 +2112,7 @@ def _keep_coeff(coeff, factors, clear=True, sign=False):
         if not clear and coeff.is_Rational and coeff.q != 1:
             args = [i.as_coeff_Mul() for i in factors.args]
             args = [(_keep_coeff(c, coeff), m) for c, m in args]
-            if any(c == int(c) for c, _ in args):
+            if any(c.is_Integer for c, _ in args):
                 return Add._from_args([Mul._from_args(
                     i[1:] if i[0] == 1 else i) for i in args])
         return Mul(coeff, factors, evaluate=False)


Test patch:
diff --git a/sympy/core/tests/test_expr.py b/sympy/core/tests/test_expr.py
index 5dc061c16f..5d63cc44c3 100644
--- a/sympy/core/tests/test_expr.py
+++ b/sympy/core/tests/test_expr.py
@@ -2113,6 +2113,13 @@ def test_ExprBuilder():
     assert eb.build() == x**2
 
 
+def test_issue_22020():
+    from sympy.parsing.sympy_parser import parse_expr
+    x = parse_expr("log((2*V/3-V)/C)/-(R+r)*C")
+    y = parse_expr("log((2*V/3-V)/C)/-(R+r)*2")
+    assert x.equals(y) is False
+
+
 def test_non_string_equality():
     # Expressions should not compare equal to strings
     x = symbols('x')
diff --git a/sympy/simplify/tests/test_simplify.py b/sympy/simplify/tests/test_simplify.py
index f787592c3c..41846d9182 100644
--- a/sympy/simplify/tests/test_simplify.py
+++ b/sympy/simplify/tests/test_simplify.py
@@ -984,6 +984,13 @@ def test_issue_7950():
     expr = And(Eq(x, 1), Eq(x, 2))
     assert simplify(expr) == S.false
 
+
+def test_issue_22020():
+    expr = I*pi/2 -oo
+    assert simplify(expr) == expr
+    # Used to throw an error
+
+
 def test_issue_19484():
     assert simplify(sign(x) * Abs(x)) == x