Repository: sympy/sympy

Issue:
solveset needs to handle exceptions for some trigonometric equations
```
>>> f = sin(2*x)*cos(x) + cos(2*x)*sin(x)-1
>>> solveset(f, x, S.Reals)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/sympy/sympy/solvers/solveset.py in _solve_trig(f, symbol, domain)
    458     try:
--> 459         return _solve_trig1(f, symbol, domain)
    460 

~/sympy/sympy/solvers/solveset.py in _solve_trig1(f, symbol, domain)
    482 
--> 483     solns = solveset_complex(g, y) - solveset_complex(h, y)
    484 

~/sympy/sympy/sets/sets.py in __sub__(self, other)
    550     def __sub__(self, other):
--> 551         return Complement(self, other)
    552 

~/sympy/sympy/sets/sets.py in __new__(cls, a, b, evaluate)
   1353         if evaluate:
-> 1354             return Complement.reduce(a, b)
   1355 

~/sympy/sympy/sets/sets.py in reduce(A, B)
   1363         """
-> 1364         if B == S.UniversalSet or A.is_subset(B):
   1365             return EmptySet()

~/sympy/sympy/sets/sets.py in is_subset(self, other)
    308         if isinstance(other, Set):
--> 309             return self.intersect(other) == self
    310         else:

~/sympy/sympy/sets/sets.py in intersect(self, other)
    108         """
--> 109         return Intersection(self, other)
    110 

~/sympy/sympy/sets/sets.py in __new__(cls, *args, **kwargs)
   1219         if evaluate:
-> 1220             return simplify_intersection(args)
   1221 

~/sympy/sympy/sets/sets.py in simplify_intersection(args)
   1909     # Handle Finite sets
-> 1910     rv = Intersection._handle_finite_sets(args)
   1911 

~/sympy/sympy/sets/sets.py in _handle_finite_sets(args)
   1273             c = fuzzy_and(fuzzy_bool(o.contains(x))
-> 1274                 for o in fs_args + other)
   1275             if c:

~/sympy/sympy/core/logic.py in fuzzy_and(args)
    138     rv = True
--> 139     for ai in args:
    140         ai = fuzzy_bool(ai)

~/sympy/sympy/sets/sets.py in <genexpr>(.0)
   1273             c = fuzzy_and(fuzzy_bool(o.contains(x))
-> 1274                 for o in fs_args + other)
   1275             if c:

~/sympy/sympy/sets/conditionset.py in contains(self, other)
     57     def contains(self, other):
---> 58         return And(Lambda(self.sym, self.condition)(
     59             other), self.base_set.contains(other))

~/sympy/sympy/core/function.py in __new__(cls, variables, expr)
   1640             if not getattr(i, 'is_Symbol', False):
-> 1641                 raise TypeError('variable is not a symbol: %s' % i)
   1642         if len(v) == 1 and v[0] == expr:

TypeError: variable is not a symbol: -_y**6*I - 2*_y**3 + I

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-101-1c5f48254086> in <module>()
----> 1 pprint(solveset(f, x, S.Reals))

~/sympy/sympy/solvers/solveset.py in solveset(f, symbol, domain)
   1058             try:
   1059                 r = Dummy('r', **assumptions)
-> 1060                 return solveset(f.xreplace({symbol: r}), r, domain
   1061                     ).xreplace({r: symbol})
   1062             except InconsistentAssumptions:

~/sympy/sympy/solvers/solveset.py in solveset(f, symbol, domain)
   1076     f = piecewise_fold(f)
   1077 
-> 1078     return _solveset(f, symbol, domain, _check=True)
   1079 
   1080 

~/sympy/sympy/solvers/solveset.py in _solveset(f, symbol, domain, _check)
    821     elif _is_function_class_equation(TrigonometricFunction, f, symbol) or \
    822             _is_function_class_equation(HyperbolicFunction, f, symbol):
--> 823         result = _solve_trig(f, symbol, domain)
    824     elif isinstance(f, arg):
    825         a = f.args[0]

~/sympy/sympy/solvers/solveset.py in _solve_trig(f, symbol, domain)
    460 
    461     except BaseException as error:
--> 462         return _solve_trig2(f, symbol, domain)
    463 
    464     else :

~/sympy/sympy/solvers/solveset.py in _solve_trig2(f, symbol, domain)
    519 
    520     x = Dummy('x')
--> 521     mu = Rational(2)*ilcm(*denominators)/igcd(*numerators)
    522     f = f.subs(symbol, mu*x)
    523     f = f.rewrite(tan)

~/sympy/sympy/core/numbers.py in ilcm(*args)
    387     if len(args) < 2:
    388         raise TypeError(
--> 389             'ilcm() takes at least 2 arguments (%s given)' % len(args))
    390     if 0 in args:
    391         return 0

TypeError: ilcm() takes at least 2 arguments (1 given)

```

I guess the exception should be handled in a proper way. Similar for equation `sin(sqrt(cos(x**2 + 1)))`.

Discussion:
jashan498: @normalhuman have a look

Patch:
diff --git a/sympy/solvers/solveset.py b/sympy/solvers/solveset.py
index 581ba96a72..afa5291e1f 100644
--- a/sympy/solvers/solveset.py
+++ b/sympy/solvers/solveset.py
@@ -501,16 +501,26 @@ def _solve_as_rational(f, symbol, domain):
 
 def _solve_trig(f, symbol, domain):
     """Function to call other helpers to solve trigonometric equations """
+    sol1 = sol = None
     try:
-        return _solve_trig1(f, symbol, domain)
-
+        sol1 = _solve_trig1(f, symbol, domain)
     except BaseException as error:
-        return _solve_trig2(f, symbol, domain)
-
-    else :
+        pass
+    if sol1 is None or isinstance(sol1, ConditionSet):
+        try:
+            sol = _solve_trig2(f, symbol, domain)
+        except BaseException as error:
+            sol = sol1
+        if isinstance(sol1, ConditionSet) and isinstance(sol, ConditionSet):
+            if sol1.count_ops() < sol.count_ops():
+                sol = sol1
+    else:
+        sol = sol1
+    if sol is None:
         raise NotImplementedError(filldedent('''
             Solution to this kind of trigonometric equations
             is yet to be implemented'''))
+    return sol
 
 
 def _solve_trig1(f, symbol, domain):
@@ -564,7 +574,14 @@ def _solve_trig2(f, symbol, domain):
         denominators.append(Rational(c).q)
 
     x = Dummy('x')
-    mu = Rational(2)*ilcm(*denominators)/igcd(*numerators)
+
+    # ilcm() and igcd() require more than one argument
+    if len(numerators) > 1:
+        mu = Rational(2)*ilcm(*denominators)/igcd(*numerators)
+    else:
+        assert len(numerators) == 1
+        mu = Rational(2)*denominators[0]/numerators[0]
+
     f = f.subs(symbol, mu*x)
     f = f.rewrite(tan)
     f = expand_trig(f)


Test patch:
diff --git a/sympy/solvers/tests/test_solveset.py b/sympy/solvers/tests/test_solveset.py
index 554a8ed3c3..14d443d54e 100644
--- a/sympy/solvers/tests/test_solveset.py
+++ b/sympy/solvers/tests/test_solveset.py
@@ -798,6 +798,9 @@ def test_solve_trig():
     assert solveset(sin(y + a) - sin(y), a, domain=S.Reals) == \
         imageset(Lambda(n, 2*n*pi), S.Integers)
 
+    assert solveset_real(sin(2*x)*cos(x) + cos(2*x)*sin(x)-1, x) == \
+                            ImageSet(Lambda(n, 2*n*pi/3 + pi/6), S.Integers)
+
     # Tests for _solve_trig2() function
     assert solveset_real(2*cos(x)*cos(2*x) - 1, x) == \
           Union(ImageSet(Lambda(n, 2*n*pi + 2*atan(sqrt(-2*2**(S(1)/3)*(67 +