Repository: sympy/sympy
File: sympy/assumptions/handlers/sets.py (Python)

Code before:
    return test_closed_group(expr, assumptions, Q.rational)

@RationalPredicate.register(Pow)
def _(expr, assumptions):
    """
    * Rational ** Integer      -> Rational
    * Irrational ** Rational   -> Irrational
    * Rational ** Irrational   -> ?
    """
    if expr.base == E:
        x = expr.exp
        if ask(Q.rational(x), assumptions):
            return ask(~Q.nonzero(x), assumptions)
        return

    is_exp_integer = ask(Q.integer(expr.exp), assumptions)
    if is_exp_integer:
        is_base_rational = ask(Q.rational(expr.base),assumptions)
        if is_base_rational is True:
            is_base_zero = ask(Q.zero(expr.base),assumptions)
            if is_base_zero is False:
                return True
            if is_base_zero is True and ask(Q.positive(expr.exp)) is True:
                return True
        if ask(Q.algebraic(expr.base),assumptions) is False:
            return ask(~Q.nonzero(expr.exp), assumptions)
        return
    elif ask(Q.rational(expr.exp), assumptions):
        if ask(Q.prime(expr.base), assumptions) and is_exp_integer is False:
            return False
        if ask(Q.zero(expr.base)) and ask(Q.positive(expr.exp)) is True:
            return True
        if ask(Q.eq(expr.base,1)):
            return True

@RationalPredicate.register_many(asin, atan, cos, sin, tan)
def _(expr, assumptions):
    x = expr.args[0]
    if ask(Q.rational(x), assumptions):
        return ask(~Q.nonzero(x), assumptions)

@RationalPredicate.register(exp)
def _(expr, assumptions):
    x = expr.exp
    if ask(Q.rational(x), assumptions):
        return ask(~Q.nonzero(x), assumptions)

@RationalPredicate.register_many(acot, cot)
def _(expr, assumptions):
    x = expr.args[0]
    if ask(Q.rational(x), assumptions):

Review comment (bug):
I believe this will wrongly return True and fail the following assertion.
`assert ask(x**y, Q.integer(y) & ~Q.algebriac(x) & Q.imaginary(x)) is None`

Could you add this as another test?

Code after:
    return test_closed_group(expr, assumptions, Q.rational)

@RationalPredicate.register(Pow)
def _(expr, assumptions):
    """
    * Rational ** Integer      -> Rational
    * Irrational ** Rational   -> Irrational
    * Rational ** Irrational   -> ?
    """
    if expr.base == E:
        x = expr.exp
        if ask(Q.rational(x), assumptions):
            return ask(Q.zero(x), assumptions)
        return

    is_exp_integer = ask(Q.integer(expr.exp), assumptions)
    if is_exp_integer:
        is_base_rational = ask(Q.rational(expr.base),assumptions)
        if is_base_rational:
            is_base_zero = ask(Q.zero(expr.base),assumptions)
            if is_base_zero is False:
                return True
            if is_base_zero and ask(Q.positive(expr.exp)):
                return True
        if ask(Q.algebraic(expr.base),assumptions) is False:
            return ask(Q.zero(expr.exp), assumptions)
        if ask(Q.irrational(expr.base),assumptions) and ask(Q.eq(expr.exp,-1)):
            return False
        return
    elif ask(Q.rational(expr.exp), assumptions):
        if ask(Q.prime(expr.base), assumptions) and is_exp_integer is False:
            return False
        if ask(Q.zero(expr.base)) and ask(Q.positive(expr.exp)):
            return True
        if ask(Q.eq(expr.base,1)):
            return True

@RationalPredicate.register_many(asin, atan, cos, sin, tan)
def _(expr, assumptions):
    x = expr.args[0]
    if ask(Q.rational(x), assumptions):
        return ask(~Q.nonzero(x), assumptions)

@RationalPredicate.register(exp)
def _(expr, assumptions):
    x = expr.exp
    if ask(Q.rational(x), assumptions):
        return ask(~Q.nonzero(x), assumptions)

@RationalPredicate.register_many(acot, cot)
def _(expr, assumptions):