Repository: sympy/sympy

Issue:
Method is_constant() doesn't work for mul expression with diffucult domain
```
In [1]: from sympy import *

In [2]: x = Symbol('x', real=True)

In [3]: e = (-1 + x)/(1 - x)

In [4]: e.is_constant(x)
Out[4]: True

In [5]: simple_e = simplify(e)

In [6]: e_subs_x = e.subs({x: 1})

In [7]: simple_e_subs_x = simple_e.subs({x: 1})

In [8]: e_subs_x == simple_e_subs_x
Out[8]: False

In [9]: e_subs_x, simple_e_subs_x
Out[9]: (nan, -1)
```

Expression **e** isn't defined if x == 1, then **e** isn't constant. 
But _e.is_constant()_ says, **e** is constant. It's wrong


Discussion:

Patch:
diff --git a/sympy/core/expr.py b/sympy/core/expr.py
index 547195955b..5a12227e26 100644
--- a/sympy/core/expr.py
+++ b/sympy/core/expr.py
@@ -578,7 +578,7 @@ def is_constant(self, *wrt, **flags):
         If an expression has no free symbols then it is a constant. If
         there are free symbols it is possible that the expression is a
         constant, perhaps (but not necessarily) zero. To test such
-        expressions, two strategies are tried:
+        expressions, a few strategies are tried:
 
         1) numerical evaluation at two random points. If two such evaluations
         give two different values and the values have a precision greater than
@@ -593,6 +593,10 @@ def is_constant(self, *wrt, **flags):
         all derivatives are zero then self is constant with respect to the
         given symbols.
 
+        3) finding out zeros of denominator expression with free_symbols.
+        It won't be constant if there are zeros. It gives more negative
+        answers for expression that are not constant.
+
         If neither evaluation nor differentiation can prove the expression is
         constant, None is returned unless two numerical values happened to be
         the same and the flag ``failing_number`` is True -- in that case the
@@ -639,6 +643,20 @@ def is_constant(self, *wrt, **flags):
         True
         """
 
+        def check_denominator_zeros(expression):
+            from sympy.solvers.solvers import denoms
+
+            retNone = False
+            for den in denoms(expression):
+                z = den.is_zero
+                if z is True:
+                    return True
+                if z is None:
+                    retNone = True
+            if retNone:
+                return None
+            return False
+
         simplify = flags.get('simplify', True)
 
         if self.is_number:
@@ -715,6 +733,11 @@ def is_constant(self, *wrt, **flags):
                         # dead line provided _random returns None in such cases
                         return None
                 return False
+        cd = check_denominator_zeros(self)
+        if cd is True:
+            return False
+        elif cd is None:
+            return None
         return True
 
     def equals(self, other, failing_expression=False):


Test patch:
diff --git a/sympy/core/tests/test_expr.py b/sympy/core/tests/test_expr.py
index 7d732844ef..a777dd8ace 100644
--- a/sympy/core/tests/test_expr.py
+++ b/sympy/core/tests/test_expr.py
@@ -5,7 +5,7 @@
                    simplify, together, collect, factorial, apart, combsimp, factor, refine,
                    cancel, Tuple, default_sort_key, DiracDelta, gamma, Dummy, Sum, E,
                    exp_polar, expand, diff, O, Heaviside, Si, Max, UnevaluatedExpr,
-                   integrate, gammasimp, Gt)
+                   integrate, gammasimp, Gt, cot)
 from sympy.core.expr import ExprBuilder, unchanged
 from sympy.core.function import AppliedUndef
 from sympy.core.compatibility import range, round, PY3
@@ -1857,6 +1857,19 @@ def test_issue_11122():
     assert (x > 0) is S.false
 
 
+def test_issue_10651():
+    x = Symbol('x', real=True)
+    e1 = (-1 + x)/(1 - x)
+    e3 = (4*x**2 - 4)/((1 - x)*(1 + x))
+    e4 = 1/(cos(x)**2) - (tan(x))**2
+    x = Symbol('x', positive=True)
+    e5 = (1 + x)/x
+    assert e1.is_constant() is None
+    assert e3.is_constant() is None
+    assert e4.is_constant() is None
+    assert e5.is_constant() is False
+
+
 def test_issue_10161():
     x = symbols('x', real=True)
     assert x*abs(x)*abs(x) == x**3