Repository: sympy/sympy

Issue:
Add debugging messages to manualintegrate
Some of the more complex algorithms in SymPy, such as Gruntz for limits and Meijer G for integrals, issue debugging messages. Examples from meijergint: 
```
from sympy.utilities.misc import debug
debug('Integrating', f, 'wrt %s from %s to %s.' % (x, a, b))
debug('Trying recursive Mellin transform method.')
debug('Try rewriting hyperbolics in terms of exp.')
```
These are shown if one uses `export SYMPY_DEBUG=True` before starting Python. I found them helpful in tracing integration issues, and I guess it's not just me.

I propose that manualintegrate.py should also issue `debug` messages when it attempts some transformation rule. It could be a message like 
```
debug("Trying to integrate {} by using {}".format(function, rule))
```
This way, when integration does something strange or goes into an infinite loop, we'll know where the problem is without tracing the different integration routines. 

Discussion:

Patch:
diff --git a/sympy/integrals/manualintegrate.py b/sympy/integrals/manualintegrate.py
index cf0fe22ae9..1c3b15ea27 100644
--- a/sympy/integrals/manualintegrate.py
+++ b/sympy/integrals/manualintegrate.py
@@ -32,6 +32,7 @@
 from sympy.core.relational import Eq, Ne
 from sympy.polys.polytools import degree
 from sympy.ntheory.factor_ import divisors
+from sympy.utilities.misc import debug
 
 ZERO = sympy.S.Zero
 
@@ -181,7 +182,7 @@ def test_subterm(u, u_diff):
         if symbol not in substituted.free_symbols:
             # replaced everything already
             return False
-
+        debug("substituted: {}, u: {}, u_var: {}".format(substituted, u, u_var))
         substituted = manual_subs(substituted, u, u_var).cancel()
 
         if symbol not in substituted.free_symbols:
@@ -266,6 +267,7 @@ def rewriter(condition, rewrite):
     """Strategy that rewrites an integrand."""
     def _rewriter(integral):
         integrand, symbol = integral
+        debug("Integral: {} is rewritten with {} on symbol: {}".format(integrand, rewrite, symbol))
         if condition(*integral):
             rewritten = rewrite(*integral)
             if rewritten != integrand:
@@ -282,6 +284,7 @@ def proxy_rewriter(condition, rewrite):
     def _proxy_rewriter(criteria):
         criteria, integral = criteria
         integrand, symbol = integral
+        debug("Integral: {} is rewritten with {} on symbol: {} and criteria: {}".format(integrand, rewrite, symbol, criteria))
         args = criteria + list(integral)
         if condition(*args):
             rewritten = rewrite(*args)
@@ -304,7 +307,12 @@ def alternatives(*rules):
     """Strategy that makes an AlternativeRule out of multiple possible results."""
     def _alternatives(integral):
         alts = []
+        count = 0
+        debug("List of Alternative Rules")
         for rule in rules:
+            count = count + 1
+            debug("Rule {}: {}".format(count, rule))
+
             result = rule(integral)
             if (result and not isinstance(result, DontKnowRule) and
                 result != integral and result not in alts):
@@ -600,6 +608,7 @@ def parts_rule(integral):
     steps = []
     if result:
         u, dv, v, du, v_step = result
+        debug("u : {}, dv : {}, v : {}, du : {}, v_step: {}".format(u, dv, v, du, v_step))
         steps.append(result)
 
         if isinstance(v, sympy.Integral):
@@ -614,6 +623,7 @@ def parts_rule(integral):
 
         # Try cyclic integration by parts a few times
         for _ in range(4):
+            debug("Cyclic integration {} with v: {}, du: {}, integrand: {}".format(_, v, du, integrand))
             coefficient = ((v * du) / integrand).cancel()
             if coefficient == 1:
                 break
@@ -1075,10 +1085,15 @@ def substitution_rule(integral):
 
     u_var = sympy.Dummy("u")
     substitutions = find_substitutions(integrand, symbol, u_var)
+    count = 0
     if substitutions:
+        debug("List of Substitution Rules")
         ways = []
         for u_func, c, substituted in substitutions:
             subrule = integral_steps(substituted, u_var)
+            count = count + 1
+            debug("Rule {}: {}".format(count, subrule))
+
             if contains_dont_know(subrule):
                 continue
 


Test patch:
diff --git a/sympy/utilities/tests/test_misc.py b/sympy/utilities/tests/test_misc.py
index 78a5ee301e..b873486819 100644
--- a/sympy/utilities/tests/test_misc.py
+++ b/sympy/utilities/tests/test_misc.py
@@ -1,6 +1,8 @@
 from textwrap import dedent
 from sympy.core.compatibility import range, unichr
 from sympy.utilities.misc import translate, replace, ordinal, rawlines, strlines
+import sys
+from subprocess import Popen, PIPE
 
 def test_translate():
     abc = 'abc'
@@ -102,3 +104,15 @@ def test_translate_args():
         pass # Exception raised successfully
     else:
         assert False
+
+
+def test_debug_output():
+    env = {'SYMPY_DEBUG':'True'}
+    cmd = 'from sympy import *; x = Symbol("x"); print(integrate((1-cos(x))/x, x))'
+    cmdline = [sys.executable, '-c', cmd]
+    proc = Popen(cmdline, env=env, stdout=PIPE, stderr=PIPE)
+    out, err = proc.communicate()
+    out = out.decode('ascii') # utf-8?
+    err = err.decode('ascii')
+    expected = 'substituted: -x*(cos(x) - 1), u: 1/x, u_var: _u'
+    assert expected in err