def Mul(expr, assumptions): """ Return True if expr is bounded, False if not and None if unknown. TRUTH TABLE B U ? s /s +---+---+---+---+ B | B | U | ? | legend: +---+---+---+---+ B = Bounded U | U | U | ? | U = Unbounded +---+---+---+ ? = unknown boundedness ? | ? | s = signed (hence nonzero) +---+---+ /s = not signed """ result = True for arg in expr.args: _bounded = ask(Q.bounded(arg), assumptions) if _bounded: continue elif _bounded is None: if result is None: return None if ask(Q.nonzero(arg), assumptions) is None: return None if result is not False: result = None else: result = False return result
def test_positive(): x, y, z, w = symbols('x,y,z,w') assert ask(Q.positive(x), Q.positive(x)) == True assert ask(Q.positive(x), Q.negative(x)) == False assert ask(Q.positive(x), Q.nonzero(x)) == None assert ask(Q.positive(-x), Q.positive(x)) == False assert ask(Q.positive(-x), Q.negative(x)) == True assert ask(Q.positive(x+y), Q.positive(x) & Q.positive(y)) == True assert ask(Q.positive(x+y), Q.positive(x) & Q.negative(y)) == None assert ask(Q.positive(2*x), Q.positive(x)) == True assumptions = Q.positive(x) & Q.negative(y) & Q.negative(z) & Q.positive(w) assert ask(Q.positive(x*y*z)) == None assert ask(Q.positive(x*y*z), assumptions) == True assert ask(Q.positive(-x*y*z), assumptions) == False assert ask(Q.positive(x**2), Q.positive(x)) == True assert ask(Q.positive(x**2), Q.negative(x)) == True #exponential assert ask(Q.positive(exp(x)), Q.real(x)) == True assert ask(Q.positive(x + exp(x)), Q.real(x)) == None #absolute value assert ask(Q.positive(Abs(x))) == None # Abs(0) = 0 assert ask(Q.positive(Abs(x)), Q.positive(x)) == True
def Mul(expr, assumptions): for arg in expr.args: result = ask(Q.nonzero(arg), assumptions) if result: continue return result return True
def Mul(expr, assumptions): """ Return True if expr is bounded, False if not and None if unknown. Truth Table: +---+---+---+--------+ | | | | | | | B | U | ? | | | | | | +---+---+---+---+----+ | | | | | | | | | | s | /s | | | | | | | +---+---+---+---+----+ | | | | | | B | B | U | ? | | | | | | +---+---+---+---+----+ | | | | | | | U | | U | U | ? | | | | | | | +---+---+---+---+----+ | | | | | | ? | | | ? | | | | | | +---+---+---+---+----+ * B = Bounded * U = Unbounded * ? = unknown boundedness * s = signed (hence nonzero) * /s = not signed """ result = True for arg in expr.args: _bounded = ask(Q.bounded(arg), assumptions) if _bounded: continue elif _bounded is None: if result is None: return None if ask(Q.nonzero(arg), assumptions) is None: return None if result is not False: result = None else: result = False return result
def test_zero_0(): z = Integer(0) assert ask(Q.nonzero(z)) == False assert ask(Q.commutative(z)) == True assert ask(Q.integer(z)) == True assert ask(Q.rational(z)) == True assert ask(Q.real(z)) == True assert ask(Q.complex(z)) == True assert ask(Q.imaginary(z)) == False assert ask(Q.positive(z)) == False assert ask(Q.negative(z)) == False assert ask(Q.even(z)) == True assert ask(Q.odd(z)) == False assert ask(Q.bounded(z)) == True assert ask(Q.infinitesimal(z)) == True assert ask(Q.prime(z)) == False assert ask(Q.composite(z)) == False
def test_nan(): nan = S.NaN assert ask(Q.commutative(nan)) == True assert ask(Q.integer(nan)) == False assert ask(Q.rational(nan)) == False assert ask(Q.real(nan)) == False assert ask(Q.extended_real(nan)) == False assert ask(Q.complex(nan)) == False assert ask(Q.irrational(nan)) == False assert ask(Q.imaginary(nan)) == False assert ask(Q.positive(nan)) == False assert ask(Q.nonzero(nan)) == True assert ask(Q.even(nan)) == False assert ask(Q.odd(nan)) == False assert ask(Q.bounded(nan)) == False assert ask(Q.infinitesimal(nan)) == False assert ask(Q.prime(nan)) == False assert ask(Q.composite(nan)) == False
def test_real(): x, y = symbols('x,y') assert ask(Q.real(x)) == None assert ask(Q.real(x), Q.real(x)) == True assert ask(Q.real(x), Q.nonzero(x)) == True assert ask(Q.real(x), Q.positive(x)) == True assert ask(Q.real(x), Q.negative(x)) == True assert ask(Q.real(x), Q.integer(x)) == True assert ask(Q.real(x), Q.even(x)) == True assert ask(Q.real(x), Q.prime(x)) == True assert ask(Q.real(x/sqrt(2)), Q.real(x)) == True assert ask(Q.real(x/sqrt(-2)), Q.real(x)) == False I = S.ImaginaryUnit assert ask(Q.real(x+1), Q.real(x)) == True assert ask(Q.real(x+I), Q.real(x)) == False assert ask(Q.real(x+I), Q.complex(x)) == None assert ask(Q.real(2*x), Q.real(x)) == True assert ask(Q.real(I*x), Q.real(x)) == False assert ask(Q.real(I*x), Q.imaginary(x)) == True assert ask(Q.real(I*x), Q.complex(x)) == None assert ask(Q.real(x**2), Q.real(x)) == True assert ask(Q.real(sqrt(x)), Q.negative(x)) == False assert ask(Q.real(x**y), Q.real(x) & Q.integer(y)) == True assert ask(Q.real(x**y), Q.real(x) & Q.real(y)) == None assert ask(Q.real(x**y), Q.positive(x) & Q.real(y)) == True # trigonometric functions assert ask(Q.real(sin(x))) == None assert ask(Q.real(cos(x))) == None assert ask(Q.real(sin(x)), Q.real(x)) == True assert ask(Q.real(cos(x)), Q.real(x)) == True # exponential function assert ask(Q.real(exp(x))) == None assert ask(Q.real(exp(x)), Q.real(x)) == True assert ask(Q.real(x + exp(x)), Q.real(x)) == True # Q.complexes assert ask(Q.real(re(x))) == True assert ask(Q.real(im(x))) == True
def test_rational(): x, y = symbols('x,y') assert ask(Q.rational(x), Q.integer(x)) == True assert ask(Q.rational(x), Q.irrational(x)) == False assert ask(Q.rational(x), Q.real(x)) == None assert ask(Q.rational(x), Q.positive(x)) == None assert ask(Q.rational(x), Q.negative(x)) == None assert ask(Q.rational(x), Q.nonzero(x)) == None assert ask(Q.rational(2*x), Q.rational(x)) == True assert ask(Q.rational(2*x), Q.integer(x)) == True assert ask(Q.rational(2*x), Q.even(x)) == True assert ask(Q.rational(2*x), Q.odd(x)) == True assert ask(Q.rational(2*x), Q.irrational(x)) == False assert ask(Q.rational(x/2), Q.rational(x)) == True assert ask(Q.rational(x/2), Q.integer(x)) == True assert ask(Q.rational(x/2), Q.even(x)) == True assert ask(Q.rational(x/2), Q.odd(x)) == True assert ask(Q.rational(x/2), Q.irrational(x)) == False assert ask(Q.rational(1/x), Q.rational(x)) == True assert ask(Q.rational(1/x), Q.integer(x)) == True assert ask(Q.rational(1/x), Q.even(x)) == True assert ask(Q.rational(1/x), Q.odd(x)) == True assert ask(Q.rational(1/x), Q.irrational(x)) == False assert ask(Q.rational(2/x), Q.rational(x)) == True assert ask(Q.rational(2/x), Q.integer(x)) == True assert ask(Q.rational(2/x), Q.even(x)) == True assert ask(Q.rational(2/x), Q.odd(x)) == True assert ask(Q.rational(2/x), Q.irrational(x)) == False # with multiple symbols assert ask(Q.rational(x*y), Q.irrational(x) & Q.irrational(y)) == None assert ask(Q.rational(y/x), Q.rational(x) & Q.rational(y)) == True assert ask(Q.rational(y/x), Q.integer(x) & Q.rational(y)) == True assert ask(Q.rational(y/x), Q.even(x) & Q.rational(y)) == True assert ask(Q.rational(y/x), Q.odd(x) & Q.rational(y)) == True assert ask(Q.rational(y/x), Q.irrational(x) & Q.rational(y)) == False
def Pow(expr, assumptions): """ Unbounded ** NonZero -> Unbounded Bounded ** Bounded -> Bounded Abs()<=1 ** Positive -> Bounded Abs()>=1 ** Negative -> Bounded Otherwise unknown """ base_bounded = ask(Q.bounded(expr.base), assumptions) exp_bounded = ask(Q.bounded(expr.exp), assumptions) if base_bounded is None and exp_bounded is None: # Common Case return None if base_bounded is False and ask(Q.nonzero(expr.exp), assumptions): return False if base_bounded and exp_bounded: return True if (abs(expr.base) <= 1) == True and ask(Q.positive(expr.exp), assumptions): return True if (abs(expr.base) >= 1) == True and ask(Q.negative(expr.exp), assumptions): return True if (abs(expr.base) >= 1) == True and exp_bounded is False: return False return None
def Pow(expr, assumptions): return ask(Q.nonzero(expr.base), assumptions)
def Abs(expr, assumptions): return ask(Q.nonzero(expr.args[0]), assumptions)
def log(expr, assumptions): x = expr.args[0] if ask(Q.algebraic(x), assumptions): return ask(~Q.nonzero(x - 1), assumptions)
def _(expr, assumptions): if expr.base == E: if ask(Q.algebraic(expr.exp), assumptions): return ask(~Q.nonzero(expr.exp), assumptions) return return expr.exp.is_Rational and ask(Q.algebraic(expr.base), assumptions)
def _(expr, assumptions): return ask(Q.nonzero(expr), assumptions)
def log(expr, assumptions): x = expr.args[0] if ask(Q.rational(x), assumptions): return ask(~Q.nonzero(x - 1), assumptions)
def _(expr, assumptions): x = expr.exp if ask(Q.rational(x), assumptions): return ask(~Q.nonzero(x), assumptions)
def test_nonzero(): x, y = symbols('x,y') assert ask(Q.nonzero(x)) == None assert ask(Q.nonzero(x), Q.real(x)) == None assert ask(Q.nonzero(x), Q.positive(x)) == True assert ask(Q.nonzero(x), Q.negative(x)) == True assert ask(Q.nonzero(x), Q.negative(x) | Q.positive(x)) == True assert ask(Q.nonzero(x+y)) == None assert ask(Q.nonzero(x+y), Q.positive(x) & Q.positive(y)) == True assert ask(Q.nonzero(x+y), Q.positive(x) & Q.negative(y)) == None assert ask(Q.nonzero(x+y), Q.negative(x) & Q.negative(y)) == True assert ask(Q.nonzero(2*x)) == None assert ask(Q.nonzero(2*x), Q.positive(x)) == True assert ask(Q.nonzero(2*x), Q.negative(x)) == True assert ask(Q.nonzero(x*y), Q.nonzero(x)) == None assert ask(Q.nonzero(x*y), Q.nonzero(x) & Q.nonzero(y)) == True assert ask(Q.nonzero(Abs(x))) == None assert ask(Q.nonzero(Abs(x)), Q.nonzero(x)) == True
def _(expr, assumptions): return ask(Q.nonzero(expr.args[0]), assumptions)
def _(expr, assumptions): # After complex -> finite fact is registered to new assumption system, # querying Q.infinite may be removed. if ask(Q.infinite(expr.args[0]), assumptions): return False return ask(Q.nonzero(expr.args[0]), assumptions)
def Basic(expr, assumptions): return fuzzy_and([fuzzy_not(ask(Q.nonzero(expr), assumptions)), ask(Q.real(expr), assumptions)])
def Abs(expr, assumptions): return ask(Q.nonzero(expr), assumptions)
def _(expr, assumptions): x = expr.exp if ask(Q.algebraic(x), assumptions): return ask(~Q.nonzero(x), assumptions)
def _(expr, assumptions): return fuzzy_and([fuzzy_not(ask(Q.nonzero(expr), assumptions)), ask(Q.real(expr), assumptions)])