def Mul(expr, assumptions): """ Integer*Integer -> Integer Integer*Irrational -> !Integer Odd/Even -> !Integer Integer*Rational -> ? """ if expr.is_number: return AskIntegerHandler._number(expr, assumptions) _output = True for arg in expr.args: if not ask(arg, Q.integer, assumptions): if arg.is_Rational: if arg.q == 2: return ask(2 * expr, Q.even, assumptions) if ~(arg.q & 1): return None elif ask(arg, Q.irrational, assumptions): if _output: _output = False else: return else: return else: return _output
def test_extended_real(): x = symbols('x') assert ask(x, Q.extended_real, Assume(x, Q.positive)) == True assert ask(-x, Q.extended_real, Assume(x, Q.positive)) == True assert ask(-x, Q.extended_real, Assume(x, Q.negative)) == True assert ask(x+S.Infinity, Q.extended_real, Assume(x, Q.real)) == True
def Basic(expr, assumptions): _integer = ask(expr, Q.integer, assumptions) if _integer: _even = ask(expr, Q.even, assumptions) if _even is None: return None return not _even return _integer
def refine_Pow(expr, assumptions): """ Handler for instances of Pow. >>> from sympy import Symbol, Assume, Q >>> from sympy.refine import refine_Pow >>> x = Symbol("x") >>> refine_Pow((-1)**x, Assume(x, Q.real)) >>> refine_Pow((-1)**x, Assume(x, Q.even)) 1 >>> refine_Pow((-1)**x, Assume(x, Q.odd)) -1 """ from sympy.core import Pow, Rational from sympy.functions import sign if ask(expr.base, Q.real, assumptions): if expr.base.is_number: if ask(expr.exp, Q.even, assumptions): return abs(expr.base) ** expr.exp if ask(expr.exp, Q.odd, assumptions): return sign(expr.base) * abs(expr.base) ** expr.exp if isinstance(expr.exp, Rational): if type(expr.base) is Pow: return abs(expr.base.base) ** (expr.base.exp * expr.exp)
def refine_exp(expr, assumptions): """ Handler for exponential function. >>> from sympy import Symbol, Assume, Q, exp, I, pi >>> from sympy.refine import refine_exp >>> x = Symbol("x") >>> refine_exp(exp(pi*I*2*x), Assume(x, Q.real)) >>> refine_exp(exp(pi*I*2*x), Assume(x, Q.integer)) 1 """ arg = expr.args[0] if arg.is_Mul: coeff = arg.as_coefficient(S.Pi*S.ImaginaryUnit) if coeff: if ask(2*coeff, Q.integer, assumptions): if ask(coeff, Q.even, assumptions): return S.One elif ask(coeff, Q.odd, assumptions): return S.NegativeOne elif ask(coeff + S.Half, Q.even, assumptions): return -S.ImaginaryUnit elif ask(coeff + S.Half, Q.odd, assumptions): return S.ImaginaryUnit
def Mul(expr, assumptions): """ Even * Integer -> Even Even * Odd -> Even Integer * Odd -> ? Odd * Odd -> Odd """ if expr.is_number: return AskEvenHandler._number(expr, assumptions) even, odd, irrational = False, 0, False for arg in expr.args: # check for all integers and at least one even if ask(arg, Q.integer, assumptions): if ask(arg, Q.even, assumptions): even = True elif ask(arg, Q.odd, assumptions): odd += 1 elif ask(arg, Q.irrational, assumptions): # one irrational makes the result False # two makes it undefined if irrational: break irrational = True else: break else: if irrational: return False if even: return True if odd == len(expr.args): return False
def test_global(): """Test ask with global assumptions""" x = symbols('x') assert ask(x, Q.integer) == None global_assumptions.add(Assume(x, Q.integer)) assert ask(x, Q.integer) == True global_assumptions.clear() assert ask(x, Q.integer) == None
def Pow(expr, assumptions): if expr.is_number: return expr.evalf() > 0 if ask(expr.base, Q.positive, assumptions): return True if ask(expr.base, Q.negative, assumptions): if ask(expr.exp, Q.even, assumptions): return True if ask(expr.exp, Q.even, assumptions): return False
def Pow(expr, assumptions): """ Integer**Integer -> !Prime """ if expr.is_number: return AskPrimeHandler._number(expr, assumptions) if ask(expr.exp, Q.integer, assumptions) and \ ask(expr.base, Q.integer, assumptions): return False
def Basic(expr, assumptions): _real = ask(expr, Q.real, assumptions) if _real: _rational = ask(expr, Q.rational, assumptions) if _rational is None: return None return not _rational else: return _real
def Basic(expr, assumptions): _positive = ask(expr, Q.positive, assumptions) if _positive: _integer = ask(expr, Q.integer, assumptions) if _integer: _prime = ask(expr, Q.prime, assumptions) if _prime is None: return return not _prime else: return _integer else: return _positive
def Mul(expr, assumptions): if expr.is_number: return AskPositiveHandler._number(expr, assumptions) result = True for arg in expr.args: if ask(arg, Q.positive, assumptions): continue elif ask(arg, Q.negative, assumptions): result = result ^ True else: return return result
def Pow(expr, assumptions): """ Rational ** Integer -> Rational Irrational ** Rational -> Irrational Rational ** Irrational -> ? """ if ask(expr.exp, Q.integer, assumptions): return ask(expr.base, Q.rational, assumptions) elif ask(expr.exp, Q.rational, assumptions): if ask(expr.base, Q.prime, assumptions): return False
def Mul(expr, assumptions): if expr.is_number: return AskNegativeHandler._number(expr, assumptions) result = None for arg in expr.args: if result is None: result = False if ask(arg, Q.negative, assumptions): result = not result elif ask(arg, Q.positive, assumptions): pass else: return return result
def test_key_extensibility(): """test that you can add keys to the ask system at runtime""" x = Symbol('x') # make sure thie key is not defined raises(KeyError, "ask(x, 'my_key')") class MyAskHandler(AskHandler): @staticmethod def Symbol(expr, assumptions): return True register_handler('my_key', MyAskHandler) assert ask(x, 'my_key') == True assert ask(x+1, 'my_key') == None remove_handler('my_key', MyAskHandler)
def Pow(expr, assumptions): """ Unbounded ** Whatever -> Unbounded Bounded ** Unbounded -> Unbounded if base > 1 Bounded ** Unbounded -> Unbounded if base < 1 """ base_bounded = ask(expr.base, Q.bounded, assumptions) if not base_bounded: return base_bounded if ask(expr.exp, Q.bounded, assumptions) \ and base_bounded: return True if base_bounded and expr.base.is_number: # We need to implement relations for this if abs(expr.base) > 1: return False return True
def Mul(expr, assumptions): """ Infinitesimal*Bounded -> Infinitesimal """ if expr.is_number: return AskInfinitesimalHandler._number(expr, assumptions) result = False for arg in expr.args: if ask(arg, Q.infinitesimal, assumptions): result = True elif ask(arg, Q.bounded, assumptions): continue else: break else: return result
def Pow(expr, assumptions): """ Real ** Even -> NonNegative Real ** Odd -> same_as_base NonNegative ** Positive -> NonNegative """ if expr.is_number: return AskNegativeHandler._number(expr, assumptions) if ask(expr.base, Q.real, assumptions): if ask(expr.base, Q.positive, assumptions): return False if ask(expr.exp, Q.even, assumptions): return False if ask(expr.exp, Q.odd, assumptions): return ask(expr.base, Q.negative, assumptions)
def Add(expr, assumptions): if expr.is_number: return AskPositiveHandler._number(expr, assumptions) for arg in expr.args: if ask(arg, Q.positive, assumptions) is not True: break else: # if all argument's are positive return True
def Mul(expr, assumptions): """ Real*Imaginary -> Imaginary Imaginary*Imaginary -> Real """ if expr.is_number: return AskImaginaryHandler._number(expr, assumptions) result = False reals = 0 for arg in expr.args: if ask(arg, Q.imaginary, assumptions): result = result ^ True elif not ask(arg, Q.real, assumptions): break else: if reals == len(expr.args): return False return result
def Mul(expr, assumptions): """ Real*Real -> Real Real*Imaginary -> !Real Imaginary*Imaginary -> Real """ if expr.is_number: return AskRealHandler._number(expr, assumptions) result = True for arg in expr.args: if ask(arg, Q.real, assumptions): pass elif ask(arg, Q.imaginary, assumptions): result = result ^ True else: break else: return result
def Mul(expr, assumptions): if expr.is_number: return AskPrimeHandler._number(expr, assumptions) for arg in expr.args: if ask(arg, Q.integer, assumptions): pass else: break else: # a product of integers can't be a prime return False
def Add(expr, assumptions): """ Even + Odd -> Odd Even + Even -> Even Odd + Odd -> Even TODO: remove float() when issue http://code.google.com/p/sympy/issues/detail?id=1473 is solved """ if expr.is_number: return AskEvenHandler._number(expr, assumptions) _result = True for arg in expr.args: if ask(arg, Q.even, assumptions): pass elif ask(arg, Q.odd, assumptions): _result = not _result else: break else: return _result
def Add(expr, assumptions): """ Positive + Positive -> Positive, Negative + Negative -> Negative """ if expr.is_number: return AskNegativeHandler._number(expr, assumptions) for arg in expr.args: if not ask(arg, Q.negative, assumptions): break else: # if all argument's are negative return True
def Add(expr, assumptions): """ Imaginary + Imaginary -> Imaginary Imaginary + Complex -> ? Imaginary + Real -> !Imaginary """ if expr.is_number: return AskImaginaryHandler._number(expr, assumptions) reals = 0 for arg in expr.args: if ask(arg, Q.imaginary, assumptions): pass elif ask(arg, Q.real, assumptions): 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
def refine_abs(expr, assumptions): """ Handler for the absolute value. Examples: >>> from sympy import Symbol, Assume, Q >>> from sympy.refine import refine_abs >>> x = Symbol("x") >>> refine_abs(abs(x), Assume(x, Q.real)) >>> refine_abs(abs(x), Assume(x, Q.positive)) x >>> refine_abs(abs(x), Assume(x, Q.negative)) -x """ arg = expr.args[0] if ask(arg, Q.real, assumptions) and \ fuzzy_not(ask(arg, Q.negative, assumptions)): # if it's nonnegative return arg if ask(arg, Q.negative, assumptions): return -arg
def test_infinitesimal(): x, y = symbols('x y') assert ask(x, Q.infinitesimal) == None assert ask(x, Q.infinitesimal, Assume(x, Q.infinitesimal)) == True assert ask(2*x, Q.infinitesimal, Assume(x, Q.infinitesimal)) == True assert ask(x*y, Q.infinitesimal, Assume(x, Q.infinitesimal)) == None assert ask(x*y, Q.infinitesimal, Assume(x, Q.infinitesimal) & \ Assume(y, Q.infinitesimal)) == True assert ask(x*y, Q.infinitesimal, Assume(x, Q.infinitesimal) & \ Assume(y, Q.bounded)) == True assert ask(x**2, Q.infinitesimal, Assume(x, Q.infinitesimal)) == True
def Add(expr, assumptions): """ Bounded + Bounded -> Bounded Unbounded + Bounded -> Unbounded Unbounded + Unbounded -> ? """ result = True for arg in expr.args: _bounded = ask(arg, Q.bounded, assumptions) if _bounded: continue elif _bounded is None: return elif _bounded is False: if result: result = False else: return return result
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: _out = ask(arg, key, assumptions) if _out is None: break elif _out is False: if result: result = False else: break else: return result
def test_type_extensibility(): """test that new types can be added to the ask system at runtime We create a custom type MyType, and override ask Q.prime=True with handler MyAskHandler for this type TODO: test incompatible resolutors """ from sympy.core import Basic class MyType(Basic): pass class MyAskHandler(AskHandler): @staticmethod def MyType(expr, assumptions): return True a = MyType() register_handler(Q.prime, MyAskHandler) assert ask(a, Q.prime) == True