(b, c, n, DE)
return q
Poly Risch Differential Equation - No cancellation: deg(b) == deg(D) - 1

    Given a derivation D on k[t] with deg(D) >= 2, n either an integer
    or +oo, and b, c in k[t] with deg(b) == deg(D) - 1, 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, or the tuple (h, m, C) such that h
    in k[t], m in ZZ, and C in k[t], and for any solution q in k[t] of
    degree at most n of Dq + b*q == c, y == q - h is a solution in k[t]
    of degree at most m of Dy + b*y == C.
Poly Risch Differential Equation - No cancellation: deg(b) == deg(D) - 1
Poly Risch Differential Equation - No cancellation : deg ( b ) == deg ( D ) - 1
def no_cancel_equal(b, c, n, DE):
    """
    Poly Risch Differential Equation - No cancellation: deg(b) == deg(D) - 1

    Given a derivation D on k[t] with deg(D) >= 2, n either an integer
    or +oo, and b, c in k[t] with deg(b) == deg(D) - 1, 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, or the tuple (h, m, C) such that h
    in k[t], m in ZZ, and C in k[t], and for any solution q in k[t] of
    degree at most n of Dq + b*q == c, y == q - h is a solution in k[t]
    of degree at most m of Dy + b*y == C.
    """
    q = Poly(0, DE.t)
    lc = cancel(-b.as_poly(DE.t).LC()/DE.d.as_poly(DE.t).LC())
    if lc.is_Integer and lc.is_positive:
        M = lc
    else:
        M = -1

    while not c.is_zero:
        m = max(M, c.degree(DE.t) - DE.d.degree(DE.t) + 1)

        if not 0 <= m <= n:  # n < 0 or m < 0 or m > n
            raise NonElementaryIntegralException

        u = cancel(m*DE.d.as_poly(DE.t).LC() + b.as_poly(DE.t).LC())
        if u.is_zero:
            return (q, m, c)
        if m > 0:
            p = Poly(c.as_poly(DE.t).LC()/u*DE.t**m, DE.t, expand=False)
        else:
            if c.degree(DE.t) != DE.d.degree(DE.t) - 1:
                raise NonElementaryIntegralException
            else:
                p = c.as_poly(DE.t).LC()/b.as_poly(DE.t).LC()

        q = q + p
        n = m - 1
        c = c - derivation(p, DE) - b*p

    return q
def no_cancel_equal ( b , c , n , DE ) : q = Poly ( 0 , DE . t ) lc = cancel ( - b . as_poly ( DE . t ) . LC ( ) / DE . d . as_poly ( DE . t ) . LC ( ) ) if lc . is_Integer and lc . is_positive : M = lc else : M = - 1 while not c . is_zero : m = max ( M , c . degree ( DE . t ) - DE . d . degree ( DE . t ) + 1 ) if not 0 <= m <= n : # n < 0 or m < 0 or m > n raise NonElementaryIntegralException u = cancel ( m * DE . d . as_poly ( DE . t ) . LC ( ) + b . as_poly ( DE . t ) . LC ( ) ) if u . is_zero : return ( q , m , c ) if m > 0 : p = Poly ( c . as_poly ( DE . t ) . LC ( ) / u * DE . t ** m , DE . t , expand = False ) else : if c . degree ( DE . t ) != DE . d . degree ( DE . t ) - 1 : raise NonElementaryIntegralException else : p = c . as_poly ( DE . t ) . LC ( ) / b . as_poly ( DE . t ) . LC ( ) q = q + p n = m - 1 c = c - derivation ( p , DE ) - b * p return q