code: def cancel_exp(b, c, n, DE):
      """
      Poly Risch Differential Equation - Cancellation: Hyperexponential case.
  
      Explanation
      ===========
  
      Given a derivation D on k[t], n either an integer or +oo, ``b`` in k, and
      ``c`` in k[t] with Dt/t in k and ``b != 0``, either raise
      NonElementaryIntegralException, in which case the equation Dq + b*q == c
      has no solution of degree at most n in k[t], or a solution q in k[t] of
      this equation with deg(q) <= n.
      """
      from .prde import parametric_log_deriv
  
      eta = DE.d.quo(Poly(DE.t, DE.t)).as_expr()
  
      with DecrementLevel(DE):
          etaa, etad = frac_in(eta, DE.t)
          ba, bd = frac_in(b, DE.t)
          A = parametric_log_deriv(ba, bd, etaa, etad, DE)
          if A is not None:
              a, m, z = A
              if a == 1:
                  raise NotImplementedError(
                      "is_deriv_in_field() is required to "
                      "solve this problem."
                  )
                  # if c*z*t**m == Dp for p in k<t> and q = p/(z*t**m) in k[t] and
                  # deg(q) <= n:
                  #     return q
                  # else:
                  #     raise NonElementaryIntegralException
  
      if c.is_zero:
          return c  # return 0
  
      if n < c.degree(DE.t):
          raise NonElementaryIntegralException
  
      q = Poly(0, DE.t)
      while not c.is_zero:
          m = c.degree(DE.t)
          if n < m:
              raise NonElementaryIntegralException
          # a1 = b + m*Dt/t
          a1 = b.as_expr()
          with DecrementLevel(DE):
              # TODO: Write a dummy function that does this idiom
              a1a, a1d = frac_in(a1, DE.t)
              a1a = a1a * etad + etaa * a1d * Poly(m, DE.t)
              a1d = a1d * etad
  
              a2a, a2d = frac_in(c.LC(), DE.t)
  
              sa, sd = rischDE(a1a, a1d, a2a, a2d, DE)
          stm = Poly(
              sa.as_expr() / sd.as_expr() * DE.t**m,
              DE.t,
              expand=False,
          )
          q += stm
          n = m - 1
          c -= b * stm + derivation(stm, DE)  # deg(c) becomes smaller
      return q
  
imports: from operator import mul
  from functools import reduce
  from sympy.core import oo
  from sympy.core.symbol import Dummy
  from sympy.polys import Poly, gcd, ZZ, cancel
  from sympy.functions.elementary.complexes import im, re
  from sympy.functions.elementary.miscellaneous import sqrt
  from sympy.integrals.risch import gcdex_diophantine, frac_in, derivation, splitfactor, NonElementaryIntegralException, DecrementLevel, recognize_log_derivative
label_desc: Use image node_id 12 for calling a global function with example usage: cancel_exp(b, c, n, DE) and returns: q, c