/

# Source code for sympy.assumptions.handlers.ntheory

"""
Handlers for keys related to number theory: prime, even, odd, etc.
"""
from __future__ import print_function, division

from sympy.assumptions import Q, ask
from sympy.assumptions.handlers import CommonHandler
from sympy.ntheory import isprime
from sympy.core import S

"""
Handler for key 'prime'
Test that an expression represents a prime number. When the
expression is a number the result, when True, is subject to
the limitations of isprime() which is used to return the result.
"""

@staticmethod
def _number(expr, assumptions):
# helper method
try:
i = int(expr.round())
if not (expr - i).equals(0):
raise TypeError
except TypeError:
return False
return isprime(i)

@staticmethod
def Basic(expr, assumptions):
# Just use int(expr) once
# https://github.com/sympy/sympy/issues/4561
# is solved
if expr.is_number:

@staticmethod
def Mul(expr, assumptions):
if expr.is_number:
for arg in expr.args:
pass
else:
break
else:
# a product of integers can't be a prime
return False

@staticmethod
[docs]    def Pow(expr, assumptions):
"""
Integer**Integer     -> !Prime
"""
if expr.is_number:
if ask(Q.integer(expr.exp), assumptions) and \
return False

@staticmethod
def Integer(expr, assumptions):
return isprime(expr)

Rational, Infinity, NegativeInfinity, ImaginaryUnit = [staticmethod(CommonHandler.AlwaysFalse)]*4

@staticmethod
def Float(expr, assumptions):

@staticmethod
def NumberSymbol(expr, assumptions):

@staticmethod
def Basic(expr, assumptions):
_positive = ask(Q.positive(expr), assumptions)
if _positive:
_integer = ask(Q.integer(expr), assumptions)
if _integer:
_prime = ask(Q.prime(expr), assumptions)
if _prime is None:
return
return not _prime
else:
return _integer
else:
return _positive

@staticmethod
def _number(expr, assumptions):
# helper method
try:
i = int(expr.round())
if not (expr - i).equals(0):
raise TypeError
except TypeError:
return False
return i % 2 == 0

@staticmethod
def Basic(expr, assumptions):
if expr.is_number:

@staticmethod
def Mul(expr, assumptions):
"""
Even * Integer    -> Even
Even * Odd        -> Even
Integer * Odd     -> ?
Odd * Odd         -> Odd
Even * Even       -> Even
Integer * Integer -> Even if Integer + Integer = Odd
-> ? otherwise
"""
if expr.is_number:
even, odd, irrational, acc = False, 0, False, 1
for arg in expr.args:
# check for all integers and at least one even
even = True
odd += 1
elif not even and acc != 1:
if ask(Q.odd(acc + arg), assumptions):
even = True
# one irrational makes the result False
# two makes it undefined
if irrational:
break
irrational = True
else:
break
acc = arg
else:
if irrational:
return False
if even:
return True
if odd == len(expr.args):
return False

@staticmethod
"""
Even + Odd  -> Odd
Even + Even -> Even
Odd  + Odd  -> Even

"""
if expr.is_number:
_result = True
for arg in expr.args:
pass
_result = not _result
else:
break
else:
return _result

@staticmethod
def Pow(expr, assumptions):
if expr.is_number:
elif ask(~Q.negative(expr.exp) & Q.odd(expr.base), assumptions):
return False
elif expr.base is S.NegativeOne:
return False

@staticmethod
def Integer(expr, assumptions):
return not bool(expr.p & 1)

Rational, Infinity, NegativeInfinity, ImaginaryUnit = [staticmethod(CommonHandler.AlwaysFalse)]*4

@staticmethod
def Float(expr, assumptions):
return expr % 2 == 0

@staticmethod
def NumberSymbol(expr, assumptions):

@staticmethod
def Abs(expr, assumptions):

@staticmethod
def re(expr, assumptions):

@staticmethod
def im(expr, assumptions):
return True

"""
Handler for key 'odd'
Test that an expression represents an odd number
"""

@staticmethod
def Basic(expr, assumptions):
_integer = ask(Q.integer(expr), assumptions)
if _integer:
_even = ask(Q.even(expr), assumptions)
if _even is None:
return None
return not _even
return _integer