def _invert_real(f, g_ys, symbol):
    'Helper function for _invert.'
    if (f == symbol):
        return (f, g_ys)
    n = Dummy('n', real=True)
    if (hasattr(f, 'inverse') and (not isinstance(f, (TrigonometricFunction, HyperbolicFunction)))):
        if (len(f.args) > 1):
            raise ValueError('Only functions with one argument are supported.')
        return _invert_real(f.args[0], imageset(Lambda(n, f.inverse()(n)), g_ys), symbol)
    if isinstance(f, Abs):
        pos = Interval(0, S.Infinity)
        neg = Interval(S.NegativeInfinity, 0)
        return _invert_real(f.args[0], Union(imageset(Lambda(n, n), g_ys).intersect(pos), imageset(Lambda(n, (- n)), g_ys).intersect(neg)), symbol)
    if f.is_Add:
        (g, h) = f.as_independent(symbol)
        if (g is not S.Zero):
            return _invert_real(h, imageset(Lambda(n, (n - g)), g_ys), symbol)
    if f.is_Mul:
        (g, h) = f.as_independent(symbol)
        if (g is not S.One):
            return _invert_real(h, imageset(Lambda(n, (n / g)), g_ys), symbol)
    if f.is_Pow:
        (base, expo) = f.args
        base_has_sym = base.has(symbol)
        expo_has_sym = expo.has(symbol)
        if (not expo_has_sym):
            res = imageset(Lambda(n, real_root(n, expo)), g_ys)
            if expo.is_rational:
                (numer, denom) = expo.as_numer_denom()
                if ((numer == S.One) or (numer == (- S.One))):
                    return _invert_real(base, res, symbol)
                elif ((numer % 2) == 0):
                    n = Dummy('n')
                    neg_res = imageset(Lambda(n, (- n)), res)
                    return _invert_real(base, (res + neg_res), symbol)
                else:
                    return _invert_real(base, res, symbol)
            else:
                if (not base.is_positive):
                    raise ValueError('x**w where w is irrational is not defined for negative x')
                return _invert_real(base, res, symbol)
        if (not base_has_sym):
            return _invert_real(expo, imageset(Lambda(n, (log(n) / log(base))), g_ys), symbol)
    if isinstance(f, TrigonometricFunction):
        if isinstance(g_ys, FiniteSet):

            def inv(trig):
                if isinstance(f, (sin, csc)):
                    F = (asin if isinstance(f, sin) else acsc)
                    return ((lambda a: ((n * pi) + (((- 1) ** n) * F(a)))),)
                if isinstance(f, (cos, sec)):
                    F = (acos if isinstance(f, cos) else asec)
                    return ((lambda a: (((2 * n) * pi) + F(a))), (lambda a: (((2 * n) * pi) - F(a))))
                if isinstance(f, (tan, cot)):
                    return ((lambda a: ((n * pi) + f.inverse()(a))),)
            n = Dummy('n', integer=True)
            invs = S.EmptySet
            for L in inv(f):
                invs += Union(*[imageset(Lambda(n, L(g)), S.Integers) for g in g_ys])
            return _invert_real(f.args[0], invs, symbol)
    return (f, g_ys)
Helper function for _invert.
def _invert_real(f, g_ys, symbol):
    
    if (f == symbol):
        return (f, g_ys)
    n = Dummy('n', real=True)
    if (hasattr(f, 'inverse') and (not isinstance(f, (TrigonometricFunction, HyperbolicFunction)))):
        if (len(f.args) > 1):
            raise ValueError('Only functions with one argument are supported.')
        return _invert_real(f.args[0], imageset(Lambda(n, f.inverse()(n)), g_ys), symbol)
    if isinstance(f, Abs):
        pos = Interval(0, S.Infinity)
        neg = Interval(S.NegativeInfinity, 0)
        return _invert_real(f.args[0], Union(imageset(Lambda(n, n), g_ys).intersect(pos), imageset(Lambda(n, (- n)), g_ys).intersect(neg)), symbol)
    if f.is_Add:
        (g, h) = f.as_independent(symbol)
        if (g is not S.Zero):
            return _invert_real(h, imageset(Lambda(n, (n - g)), g_ys), symbol)
    if f.is_Mul:
        (g, h) = f.as_independent(symbol)
        if (g is not S.One):
            return _invert_real(h, imageset(Lambda(n, (n / g)), g_ys), symbol)
    if f.is_Pow:
        (base, expo) = f.args
        base_has_sym = base.has(symbol)
        expo_has_sym = expo.has(symbol)
        if (not expo_has_sym):
            res = imageset(Lambda(n, real_root(n, expo)), g_ys)
            if expo.is_rational:
                (numer, denom) = expo.as_numer_denom()
                if ((numer == S.One) or (numer == (- S.One))):
                    return _invert_real(base, res, symbol)
                elif ((numer % 2) == 0):
                    n = Dummy('n')
                    neg_res = imageset(Lambda(n, (- n)), res)
                    return _invert_real(base, (res + neg_res), symbol)
                else:
                    return _invert_real(base, res, symbol)
            else:
                if (not base.is_positive):
                    raise ValueError('x**w where w is irrational is not defined for negative x')
                return _invert_real(base, res, symbol)
        if (not base_has_sym):
            return _invert_real(expo, imageset(Lambda(n, (log(n) / log(base))), g_ys), symbol)
    if isinstance(f, TrigonometricFunction):
        if isinstance(g_ys, FiniteSet):

            def inv(trig):
                if isinstance(f, (sin, csc)):
                    F = (asin if isinstance(f, sin) else acsc)
                    return ((lambda a: ((n * pi) + (((- 1) ** n) * F(a)))),)
                if isinstance(f, (cos, sec)):
                    F = (acos if isinstance(f, cos) else asec)
                    return ((lambda a: (((2 * n) * pi) + F(a))), (lambda a: (((2 * n) * pi) - F(a))))
                if isinstance(f, (tan, cot)):
                    return ((lambda a: ((n * pi) + f.inverse()(a))),)
            n = Dummy('n', integer=True)
            invs = S.EmptySet
            for L in inv(f):
                invs += Union(*[imageset(Lambda(n, L(g)), S.Integers) for g in g_ys])
            return _invert_real(f.args[0], invs, symbol)
    return (f, g_ys)