'Differentiation of 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(ZZ.old_poly_ring(x),\'Dx\')
>>> HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).diff().to_expr()
cos(x)
>>> HolonomicFunction(Dx - 2, x, 0, [1]).diff().to_expr()
2*exp(2*x)
See Also
.integrate()'

def diff(self, *args):

    if args:
        if (args[0] != self.x):
            return S(0)
        elif (len(args) == 2):
            sol = self
            for i in range(args[1]):
                sol = sol.diff(args[0])
            return sol
    ann = self.annihilator
    dx = ann.parent.derivative_operator
    if ((ann.listofpoly[0] == ann.parent.base.zero) and (ann.order == 1)):
        return S(0)
    elif (ann.listofpoly[0] == ann.parent.base.zero):
        sol = DifferentialOperator(ann.listofpoly[1:], ann.parent)
        if self._have_init_cond():
            if (self.is_singularics() == False):
                return HolonomicFunction(sol, self.x, self.x0, self.y0[1:])
            return HolonomicFunction(sol, self.x)
        else:
            return HolonomicFunction(sol, self.x)
    R = ann.parent.base
    K = R.get_field()
    seq_dmf = [K.new(i.rep) for i in ann.listofpoly]
    rhs = [(i / seq_dmf[0]) for i in seq_dmf[1:]]
    rhs.insert(0, K.zero)
    sol = _derivate_diff_eq(rhs)
    sol = _add_lists(sol, [K.zero, K.one])
    sol = _normalize(sol[1:], self.annihilator.parent, negative=False)
    if ((not self._have_init_cond()) or (self.is_singularics() == True)):
        return HolonomicFunction(sol, self.x)
    y0 = _extend_y0(self, (sol.order + 1))[1:]
    return HolonomicFunction(sol, self.x, self.x0, y0)
