'Returns evaluation over an interval.  For most functions this is:
self.subs(x, b) - self.subs(x, a),
possibly using limit() if NaN is returned from subs.
If b or a is None, it only evaluates -self.subs(x, a) or self.subs(b, x),
respectively.'

def _eval_interval(self, x, a, b):

    from sympy.series import limit, Limit
    from sympy.solvers.solveset import solveset
    from sympy.sets.sets import Interval
    if ((a is None) and (b is None)):
        raise ValueError('Both    interval    ends    cannot    be    None.')
    if (a == b):
        return 0
    if (a is None):
        A = 0
    else:
        A = self.subs(x, a)
        if A.has(S.NaN, S.Infinity, S.NegativeInfinity, S.ComplexInfinity):
            if ((a < b) != False):
                A = limit(self, x, a, '+')
            else:
                A = limit(self, x, a, '-')
            if (A is S.NaN):
                return A
            if isinstance(A, Limit):
                raise NotImplementedError('Could    not    compute    limit')
    if (b is None):
        B = 0
    else:
        B = self.subs(x, b)
        if B.has(S.NaN, S.Infinity, S.NegativeInfinity, S.ComplexInfinity):
            if ((a < b) != False):
                B = limit(self, x, b, '-')
            else:
                B = limit(self, x, b, '+')
            if isinstance(B, Limit):
                raise NotImplementedError('Could    not    compute    limit')
    if ((a and b) is None):
        return (B - A)
    value = (B - A)
    if (a.is_comparable and b.is_comparable):
        if (a < b):
            domain = Interval(a, b)
        else:
            domain = Interval(b, a)
        singularities = list(solveset(self.cancel().as_numer_denom()[1], x, domain=domain))
        for s in singularities:
            if (a < s < b):
                value += ((- limit(self, x, s, '+')) + limit(self, x, s, '-'))
            elif (b < s < a):
                value += (limit(self, x, s, '+') - limit(self, x, s, '-'))
    return value
