(L, R, limits)
Tries to perform the summation using the telescopic property

    return None if not possible
Tries to perform the summation using the telescopic property
Tries to perform the summation using the telescopic property
def telescopic(L, R, limits):
    '''Tries to perform the summation using the telescopic property

    return None if not possible
    '''
    (i, a, b) = limits
    if L.is_Add or R.is_Add:
        return None

    # We want to solve(L.subs(i, i + m) + R, m)
    # First we try a simple match since this does things that
    # solve doesn't do, e.g. solve(f(k+m)-f(k), m) fails

    k = Wild("k")
    sol = (-R).match(L.subs(i, i + k))
    s = None
    if sol and k in sol:
        s = sol[k]
        if not (s.is_Integer and L.subs(i, i + s) == -R):
            #sometimes match fail(f(x+2).match(-f(x+k))->{k: -2 - 2x}))
            s = None

    # But there are things that match doesn't do that solve
    # can do, e.g. determine that 1/(x + m) = 1/(1 - x) when m = 1

    if s is None:
        m = Dummy('m')
        try:
            sol = solve(L.subs(i, i + m) + R, m) or []
        except NotImplementedError:
            return None
        sol = [si for si in sol if si.is_Integer and
               (L.subs(i, i + si) + R).expand().is_zero]
        if len(sol) != 1:
            return None
        s = sol[0]

    if s < 0:
        return telescopic_direct(R, L, abs(s), (i, a, b))
    elif s > 0:
        return telescopic_direct(L, R, s, (i, a, b))
def telescopic ( L , R , limits ) : ( i , a , b ) = limits if L . is_Add or R . is_Add : return None # We want to solve(L.subs(i, i + m) + R, m) # First we try a simple match since this does things that # solve doesn't do, e.g. solve(f(k+m)-f(k), m) fails k = Wild ( "k" ) sol = ( - R ) . match ( L . subs ( i , i + k ) ) s = None if sol and k in sol : s = sol [ k ] if not ( s . is_Integer and L . subs ( i , i + s ) == - R ) : #sometimes match fail(f(x+2).match(-f(x+k))->{k: -2 - 2x})) s = None # But there are things that match doesn't do that solve # can do, e.g. determine that 1/(x + m) = 1/(1 - x) when m = 1 if s is None : m = Dummy ( 'm' ) try : sol = solve ( L . subs ( i , i + m ) + R , m ) or [ ] except NotImplementedError : return None sol = [ si for si in sol if si . is_Integer and ( L . subs ( i , i + si ) + R ) . expand ( ) . is_zero ] if len ( sol ) != 1 : return None s = sol [ 0 ] if s < 0 : return telescopic_direct ( R , L , abs ( s ) , ( i , a , b ) ) elif s > 0 : return telescopic_direct ( L , R , s , ( i , a , b ) )