class_docstr: A container for all the information relating to a differential extension.
  
  Explanation
  ===========
  
  The attributes of this object are (see also the docstring of __init__):
  
  - f: The original (Expr) integrand.
  - x: The variable of integration.
  - T: List of variables in the extension.
  - D: List of derivations in the extension; corresponds to the elements of T.
  - fa: Poly of the numerator of the integrand.
  - fd: Poly of the denominator of the integrand.
  - Tfuncs: Lambda() representations of each element of T (except for x).
    For back-substitution after integration.
  - backsubs: A (possibly empty) list of further substitutions to be made on
    the final integral to make it look more like the integrand.
  - exts:
  - extargs:
  - cases: List of string representations of the cases of T.
  - t: The top level extension variable, as defined by the current level
    (see level below).
  - d: The top level extension derivation, as defined by the current
    derivation (see level below).
  - case: The string representation of the case of self.d.
  (Note that self.T and self.D will always contain the complete extension,
  regardless of the level.  Therefore, you should ALWAYS use DE.t and DE.d
  instead of DE.T[-1] and DE.D[-1].  If you want to have a list of the
  derivations or variables only up to the current level, use
  DE.D[:len(DE.D) + DE.level + 1] and DE.T[:len(DE.T) + DE.level + 1].  Note
  that, in particular, the derivation() function does this.)
  
  The following are also attributes, but will probably not be useful other
  than in internal use:
  - newf: Expr form of fa/fd.
  - level: The number (between -1 and -len(self.T)) such that
    self.T[self.level] == self.t and self.D[self.level] == self.d.
    Use the methods self.increment_level() and self.decrement_level() to change
    the current level.
class_docstr_tok: ["A","container","for","all","the","information","relating","to","a","differential","extension",".","Explanation","===========","The","attributes","of","this","object","are","(","see","also","the","docstring","of","__init__",")",":","-","f",":","The","original","(","Expr",")","integrand",".","-","x",":","The","variable","of","integration",".","-","T",":","List","of","variables","in","the","extension",".","-","D",":","List","of","derivations","in","the","extension",";","corresponds","to","the","elements","of","T.","-","fa",":","Poly","of","the","numerator","of","the","integrand",".","-","fd",":","Poly","of","the","denominator","of","the","integrand",".","-","Tfuncs",":","Lambda","(",")","representations","of","each","element","of","T","(","except","for","x",")",".","For","back-substitution","after","integration",".","-","backsubs",":","A","(","possibly","empty",")","list","of","further","substitutions","to","be","made","on","the","final","integral","to","make","it","look","more","like","the","integrand",".","-","exts",":","-","extargs",":","-","cases",":","List","of","string","representations","of","the","cases","of","T.","-","t",":","The","top","level","extension","variable",",","as","defined","by","the","current","level","(","see","level","below",")",".","-","d",":","The","top","level","extension","derivation",",","as","defined","by","the","current","derivation","(","see","level","below",")",".","-","case",":","The","string","representation","of","the","case","of","self.d",".","(","Note","that","self.T","and","self.D","will","always","contain","the","complete","extension",",","regardless","of","the","level",".","Therefore",",","you","should","ALWAYS","use","DE.t","and","DE.d","instead","of","DE.T","[","-1","]","and","DE.D","[","-1","]",".","If","you","want","to","have","a","list","of","the","derivations","or","variables","only","up","to","the","current","level",",","use","DE.D","[",":","len","(","DE.D",")","+","DE.level","+","1","]","and","DE.T","[",":","len","(","DE.T",")","+","DE.level","+","1","]",".","Note","that",",","in","particular",",","the","derivation","(",")","function","does","this",".",")","The","following","are","also","attributes",",","but","will","probably","not","be","useful","other","than","in","internal","use",":","-","newf",":","Expr","form","of","fa\/fd",".","-","level",":","The","number","(","between","-1","and","-len","(","self.T",")",")","such","that","self.T","[","self.level","]","==","self.t","and","self.D","[","self.level","]","==","self.d",".","Use","the","methods","self.increment_level","(",")","and","self.decrement_level","(",")","to","change","the","current","level","."]
docstr: Rewrite logs for better processing.
docstr_tok: ["Rewrite","logs","for","better","processing","."]
code: def _rewrite_logs(self, logs, symlogs):
      """
      Rewrite logs for better processing.
      """
      atoms = self.newf.atoms(log)
      logs = update_sets(
          logs,
          atoms,
          lambda i: i.args[0].is_rational_function(*self.T)
          and i.args[0].has(*self.T),
      )
      symlogs = update_sets(
          symlogs,
          atoms,
          lambda i: i.has(*self.T)
          and i.args[0].is_Pow
          and i.args[0].base.is_rational_function(*self.T)
          and not i.args[0].exp.is_Integer,
      )
  
      # We can handle things like log(x**y) by converting it to y*log(x)
      # This will fix not only symbolic exponents of the argument, but any
      # non-Integer exponent, like log(sqrt(x)).  The exponent can also
      # depend on x, like log(x**x).
      for i in ordered(symlogs):
          # Unlike in the exponential case above, we do not ever
          # potentially add new monomials (above we had to add log(a)).
          # Therefore, there is no need to run any is_deriv functions
          # here.  Just convert log(a**b) to b*log(a) and let
          # log_new_extension() handle it from there.
          lbase = log(i.args[0].base)
          logs.append(lbase)
          new = i.args[0].exp * lbase
          self.newf = self.newf.xreplace({i: new})
          self.backsubs.append((new, i))
  
      # remove any duplicates
      logs = sorted(set(logs), key=default_sort_key)
  
      return logs, symlogs
  
imports: from types import GeneratorType
  from functools import reduce
  from sympy.core.function import Lambda
  from sympy.core.mul import Mul
  from sympy.core.intfunc import ilcm
  from sympy.core.numbers import I, oo
  from sympy.core.power import Pow
  from sympy.core.relational import Ne
  from sympy.core.singleton import S
  from sympy.core.sorting import ordered, default_sort_key
  from sympy.core.symbol import Dummy, Symbol
  from sympy.functions.elementary.exponential import log, exp
  from sympy.functions.elementary.hyperbolic import cosh, coth, sinh, tanh
  from sympy.functions.elementary.piecewise import Piecewise
  from sympy.functions.elementary.trigonometric import atan, sin, cos, tan, acot, cot, asin, acos
  from .integrals import integrate, Integral
  from .heurisch import _symbols
  from sympy.polys.polyerrors import DomainError, PolynomialError
  from sympy.polys.polytools import real_roots, cancel, Poly, gcd, reduced
  from sympy.polys.rootoftools import RootSum
  from sympy.utilities.iterables import numbered_symbols
label_desc: Use image node_id 4 for calling the DifferentialExtension obj's underlying member method code with example usage: obj._rewrite_logs(logs, symlogs) and returns: logs,  symlogs