'Integrates the given holonomic function.
Examples
>>> from sympy.holonomic.holonomic import HolonomicFunction, DifferentialOperators
>>> from sympy.polys.domains import ZZ, QQ
>>> from sympy import symbols
>>> x = symbols(\'x\')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),\'Dx\')
>>> HolonomicFunction(Dx - 1, x, 0, [1]).integrate((x, 0, x))  # e^x - 1
HolonomicFunction((-1)*Dx + (1)*Dx**2, x, 0, [0, 1])
>>> HolonomicFunction(Dx**2 + 1, x, 0, [1, 0]).integrate((x, 0, x))
HolonomicFunction((1)*Dx + (1)*Dx**3, x, 0, [0, 1, 0])'

def integrate(self, limits, initcond=False):

    D = self.annihilator.parent.derivative_operator
    if (self.is_singularics() == True):
        r = self._singularics_to_ord()
        if r:
            return r.integrate(limits, initcond=initcond)
        y0 = {}
        for i in self.y0:
            c = self.y0[i]
            c2 = []
            for j in range(len(c)):
                if (c[j] == 0):
                    c2.append(S(0))
                elif (((i + j) + 1) == 0):
                    raise NotImplementedError('logarithmic    terms    in    the    series    are    not    supported')
                else:
                    c2.append((c[j] / S(((i + j) + 1))))
            y0[(i + 1)] = c2
        if hasattr(limits, '__iter__'):
            raise NotImplementedError('Definite    integration    for    singular    initial    conditions')
        return HolonomicFunction((self.annihilator * D), self.x, self.x0, y0)
    if (not self._have_init_cond()):
        if initcond:
            return HolonomicFunction((self.annihilator * D), self.x, self.x0, [S(0)])
        return HolonomicFunction((self.annihilator * D), self.x)
    if hasattr(limits, '__iter__'):
        if ((len(limits) == 3) and (limits[0] == self.x)):
            x0 = self.x0
            a = limits[1]
            b = limits[2]
            definite = True
    else:
        definite = False
    y0 = [S(0)]
    y0 += self.y0
    indefinite_integral = HolonomicFunction((self.annihilator * D), self.x, self.x0, y0)
    if (not definite):
        return indefinite_integral
    if (x0 != a):
        try:
            indefinite_expr = indefinite_integral.to_expr()
        except (NotHyperSeriesError, NotPowerSeriesError):
            indefinite_expr = None
        if indefinite_expr:
            lower = indefinite_expr.subs(self.x, a)
            if isinstance(lower, NaN):
                lower = indefinite_expr.limit(self.x, a)
        else:
            lower = indefinite_integral.evalf(a)
        if (b == self.x):
            y0[0] = (y0[0] - lower)
            return HolonomicFunction((self.annihilator * D), self.x, x0, y0)
        elif S(b).is_Number:
            if indefinite_expr:
                upper = indefinite_expr.subs(self.x, b)
                if isinstance(upper, NaN):
                    upper = indefinite_expr.limit(self.x, b)
            else:
                upper = indefinite_integral.evalf(b)
            return (upper - lower)
    if (b == self.x):
        return HolonomicFunction((self.annihilator * D), self.x, a, y0)
    elif S(b).is_Number:
        try:
            s = HolonomicFunction((self.annihilator * D), self.x, a, y0).to_expr()
            indefinite = s.subs(self.x, b)
            if (not isinstance(indefinite, NaN)):
                return indefinite
            else:
                return s.limit(self.x, b)
        except (NotHyperSeriesError, NotPowerSeriesError):
            return HolonomicFunction((self.annihilator * D), self.x, a, y0).evalf(b)
    return HolonomicFunction((self.annihilator * D), self.x)
