Source code for sympy.assumptions.handlers.sets

"""
Handlers for predicates related to set membership: integer, rational, etc.
"""
from sympy.assumptions.handlers import CommonHandler

"""
Handler for Q.integer
Test that an expression belongs to the field of integer numbers
"""

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

@staticmethod
"""
Integer + Integer       -> Integer
Integer + !Integer      -> !Integer
!Integer + !Integer -> ?
"""
if expr.is_number:
return test_closed_group(expr, assumptions, Q.integer)

@staticmethod
[docs]    def Mul(expr, assumptions):
"""
Integer*Integer      -> Integer
Integer*Irrational   -> !Integer
Odd/Even             -> !Integer
Integer*Rational     -> ?
"""
if expr.is_number:
_output = True
for arg in expr.args:
if arg.is_Rational:
if arg.q == 2:
if ~(arg.q & 1):
return None
if _output:
_output = False
else:
return
else:
return
else:
return _output

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

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

@staticmethod
def Rational(expr, assumptions):
# rationals with denominator one get
# evaluated to Integers
return False

@staticmethod
def Float(expr, assumptions):
return int(expr) == expr

@staticmethod
def Pi(expr, assumptions):
return False

@staticmethod
def Exp1(expr, assumptions):
return False

@staticmethod
def Infinity(expr, assumptions):
return False

@staticmethod
def NegativeInfinity(expr, assumptions):
return False

@staticmethod
def ImaginaryUnit(expr, assumptions):
return False

@staticmethod
def Abs(expr, assumptions):

"""
Handler for Q.rational
Test that an expression belongs to the field of rational numbers
"""

@staticmethod
"""
Rational + Rational     -> Rational
Rational + !Rational    -> !Rational
!Rational + !Rational   -> ?
"""
if expr.is_number:
if expr.as_real_imag()[1]:
return False
return test_closed_group(expr, assumptions, Q.rational)

@staticmethod
[docs]    def Pow(expr, assumptions):
"""
Rational ** Integer      -> Rational
Irrational ** Rational   -> Irrational
Rational ** Irrational   -> ?
"""
return False

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

@staticmethod
def Float(expr, assumptions):
# it's finite-precision
return True

@staticmethod
def ImaginaryUnit(expr, assumptions):
return False

@staticmethod
def Infinity(expr, assumptions):
return False

@staticmethod
def NegativeInfinity(expr, assumptions):
return False

@staticmethod
def Pi(expr, assumptions):
return False

@staticmethod
def Exp1(expr, assumptions):
return False

@staticmethod
def Basic(expr, assumptions):
if _real:
if _rational is None: return None
return not _rational
else: return _real

"""
Handler for Q.real
Test that an expression belongs to the field of real numbers
"""

@staticmethod
def _number(expr, assumptions):
return not expr.as_real_imag()[1]

@staticmethod
"""
Real + Real              -> Real
Real + (Complex & !Real) -> !Real
"""
if expr.is_number:
return test_closed_group(expr, assumptions, Q.real)

@staticmethod
[docs]    def Mul(expr, assumptions):
"""
Real*Real               -> Real
Real*Imaginary          -> !Real
Imaginary*Imaginary     -> Real
"""
if expr.is_number:
result = True
for arg in expr.args:
pass
result = result ^ True
else:
break
else:
return result

@staticmethod
[docs]    def Pow(expr, assumptions):
"""
Real**Integer         -> Real
Positive**Real        -> Real
Real**(Integer/Even)  -> Real if base is nonnegative
Real**(Integer/Odd)   -> Real
"""
if expr.is_number:
return True
elif expr.exp.is_Rational:
if (expr.exp.q % 2 == 0):
else: return True
return True

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

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

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

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

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

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

im = re

@staticmethod
def ImaginaryUnit(expr, assumptions):
return False

@staticmethod
def Infinity(expr, assumptions):
return False

@staticmethod
def NegativeInfinity(expr, assumptions):
return False

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

cos, exp = sin, sin

"""
Handler for Q.extended_real
Test that an expression belongs to the field of extended real numbers,
that is real numbers union {Infinity, -Infinity}
"""

@staticmethod
return test_closed_group(expr, assumptions, Q.extended_real)

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

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

"""
Handler for Q.hermitian
Test that an expression belongs to the field of Hermitian operators
"""

@staticmethod
"""
Hermitian + Hermitian  -> Hermitian
Hermitian + !Hermitian -> !Hermitian
"""
if expr.is_number:
return test_closed_group(expr, assumptions, Q.hermitian)

@staticmethod
[docs]    def Mul(expr, assumptions):
"""
As long as there is at most only one noncommutative term:
Hermitian*Hermitian         -> Hermitian
Hermitian*Antihermitian     -> !Hermitian
Antihermitian*Antihermitian -> Hermitian
"""
if expr.is_number:
nccount = 0
result = True
for arg in expr.args:
result = result ^ True
break
nccount += 1
if nccount > 1:
break
else:
return result

@staticmethod
[docs]    def Pow(expr, assumptions):
"""
Hermitian**Integer -> Hermitian
"""
if expr.is_number:
return True

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

cos, exp = sin, sin

"""
Handler for Q.complex
Test that an expression belongs to the field of complex numbers
"""

@staticmethod
return test_closed_group(expr, assumptions, Q.complex)

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

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

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

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

@staticmethod
def Infinity(expr, assumptions):
return False

@staticmethod
def NegativeInfinity(expr, assumptions):
return False

sin, cos, exp, re, im = [Abs]*5 # they are all complex functions

"""
Handler for Q.imaginary
Test that an expression belongs to the field of imaginary numbers,
that is, numbers in the form x*I, where x is real
"""

@staticmethod
def _number(expr, assumptions):
# helper method
return not expr.as_real_imag()[0]

@staticmethod
"""
Imaginary + Imaginary -> Imaginary
Imaginary + Complex   -> ?
Imaginary + Real      -> !Imaginary
"""
if expr.is_number:
reals = 0
for arg in expr.args:
pass
reals += 1
else:
break
else:
if reals == 0:
return True
if reals == 1 or (len(expr.args) == reals):
# two reals could sum 0 thus giving an imaginary
return False

@staticmethod
[docs]    def Mul(expr, assumptions):
"""
Real*Imaginary      -> Imaginary
Imaginary*Imaginary -> Real
"""
if expr.is_number:
result = False
reals = 0
for arg in expr.args:
result = result ^ True
break
else:
if reals == len(expr.args):
return False
return result

@staticmethod
def Number(expr, assumptions):
return not (expr.as_real_imag()[1] == 0)

NumberSymbol = Number

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

"""
Handler for Q.antihermitian
Test that an expression belongs to the field of anti-Hermitian operators,
that is, operators in the form x*I, where x is Hermitian
"""

@staticmethod
"""
Antihermitian + Antihermitian  -> Antihermitian
Antihermitian + !Antihermitian -> !Antihermitian
"""
if expr.is_number:
return test_closed_group(expr, assumptions, Q.antihermitian)

@staticmethod
[docs]    def Mul(expr, assumptions):
"""
As long as there is at most only one noncommutative term:
Hermitian*Hermitian         -> !Antihermitian
Hermitian*Antihermitian     -> Antihermitian
Antihermitian*Antihermitian -> !Antihermitian
"""
if expr.is_number:
nccount = 0
result = False
for arg in expr.args:
result = result ^ True
break
nccount += 1
if nccount > 1:
break
else:
return result

@staticmethod
[docs]    def Pow(expr, assumptions):
"""
Hermitian**Integer  -> !Antihermitian
Antihermitian**Even -> !Antihermitian
Antihermitian**Odd  -> Antihermitian
"""
if expr.is_number:
return False
return False
return True

"""Handler for Q.algebraic key. """

@staticmethod
return test_closed_group(expr, assumptions, Q.algebraic)

@staticmethod
def Mul(expr, assumptions):
return test_closed_group(expr, assumptions, Q.algebraic)

@staticmethod
def Pow(expr, assumptions):

@staticmethod
def Number(expr, assumptions):
return False

@staticmethod
def Rational(expr, assumptions):
return expr.q != 0

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

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

#### Helper methods

[docs]def test_closed_group(expr, assumptions, key):
"""
Test for membership in a group with respect
to the current operation
"""
result = True
for arg in expr.args: