Пример #1
0
 def MatPow(expr, assumptions):
     # only for integer powers
     base, exp = expr.args
     int_exp = ask(Q.integer(exp), assumptions)
     if int_exp:
         return ask(Q.unitary(base), assumptions)
     return None
Пример #2
0
 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
Пример #3
0
 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(Q.integer(arg), assumptions):
             if ask(Q.even(arg), assumptions):
                 even = True
             elif ask(Q.odd(arg), assumptions):
                 odd += 1
         elif ask(Q.irrational(arg), 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
Пример #4
0
    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
Пример #5
0
 def MatMul(expr, assumptions):
     factor, mmul = expr.as_coeff_mmul()
     if all(ask(Q.invertible(arg), assumptions) for arg in mmul.args):
         return True
     if any(ask(Q.invertible(arg), assumptions) is False
            for arg in mmul.args):
         return False
Пример #6
0
def refine_abs(expr, assumptions):
    """
    Handler for the absolute value.

    Examples
    ========

    >>> from sympy import Symbol, Q, refine, Abs
    >>> from sympy.assumptions.refine import refine_abs
    >>> from sympy.abc import x
    >>> refine_abs(Abs(x), Q.real(x))
    >>> refine_abs(Abs(x), Q.positive(x))
    x
    >>> refine_abs(Abs(x), Q.negative(x))
    -x

    """
    from sympy.core.logic import fuzzy_not

    arg = expr.args[0]
    if ask(Q.real(arg), assumptions) and fuzzy_not(ask(Q.negative(arg), assumptions)):
        # if it's nonnegative
        return arg
    if ask(Q.negative(arg), assumptions):
        return -arg
Пример #7
0
def refine_exp(expr, assumptions):
    """
    Handler for exponential function.

    >>> from sympy import Symbol, Q, exp, I, pi
    >>> from sympy.assumptions.refine import refine_exp
    >>> from sympy.abc import x
    >>> refine_exp(exp(pi*I*2*x), Q.real(x))
    >>> refine_exp(exp(pi*I*2*x), Q.integer(x))
    1

    """
    arg = expr.args[0]
    if arg.is_Mul:
        coeff = arg.as_coefficient(S.Pi*S.ImaginaryUnit)
        if coeff:
            if ask(Q.integer(2*coeff), assumptions):
                if ask(Q.even(coeff), assumptions):
                    return S.One
                elif ask(Q.odd(coeff), assumptions):
                    return S.NegativeOne
                elif ask(Q.even(coeff + S.Half), assumptions):
                    return -S.ImaginaryUnit
                elif ask(Q.odd(coeff + S.Half), assumptions):
                    return S.ImaginaryUnit
Пример #8
0
 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(Q.integer(arg), assumptions):
             if arg.is_Rational:
                 if arg.q == 2:
                     return ask(Q.even(2*expr), assumptions)
                 if ~(arg.q & 1):
                     return None
             elif ask(Q.irrational(arg), assumptions):
                 if _output:
                     _output = False
                 else:
                     return
             else:
                 return
     else:
         return _output
Пример #9
0
 def Basic(expr, assumptions):
     _real = ask(Q.real(expr), assumptions)
     if _real:
         _rational = ask(Q.rational(expr), assumptions)
         if _rational is None: return None
         return not _rational
     else: return _real
Пример #10
0
 def MatPow(expr, assumptions):
     # only for integer powers
     base, exp = expr.args
     int_exp = ask(Q.integer(exp), assumptions)
     if int_exp and ask(~Q.negative(exp), assumptions):
         return ask(Q.fullrank(base), assumptions)
     return None
Пример #11
0
def test_finally():
    try:
        with assuming(Q.integer(x)):
            1/0
    except ZeroDivisionError:
        pass
    assert not ask(Q.integer(x))
Пример #12
0
 def MatMul(expr, assumptions):
     factor, mmul = expr.as_coeff_mmul()
     if (all(ask(Q.orthogonal(arg), assumptions) for arg in mmul.args) and
         factor == 1):
         return True
     if any(ask(Q.invertible(arg), assumptions) == False
             for arg in mmul.args):
         return False
Пример #13
0
def test_remove_safe():
    global_assumptions.add(Q.integer(x))
    with assuming():
        assert ask(Q.integer(x))
        global_assumptions.remove(Q.integer(x))
        assert not ask(Q.integer(x))
    assert ask(Q.integer(x))
    global_assumptions.clear() # for the benefit of other tests
Пример #14
0
 def Pow(expr, assumptions):
     """
     Integer**Integer     -> !Prime
     """
     if expr.is_number:
         return AskPrimeHandler._number(expr, assumptions)
     if ask(Q.integer(expr.exp), assumptions) and ask(Q.integer(expr.base), assumptions):
         return False
Пример #15
0
 def Symbol(expr, assumptions):
     """Objects are expected to be commutative unless otherwise stated"""
     assumps = conjuncts(assumptions)
     if Q.commutative(expr) in assumps:
         return True
     elif ~Q.commutative(expr) in assumps:
         return False
     return True
Пример #16
0
 def log(expr, assumptions):
     r = ask(Q.real(expr.args[0]), assumptions)
     if r is not True:
         return r
     if ask(Q.positive(expr.args[0] - 1), assumptions):
         return True
     if ask(Q.negative(expr.args[0] - 1), assumptions):
         return False
Пример #17
0
 def MatMul(expr, assumptions):
     factor, mmul = expr.as_coeff_mmul()
     if (all(ask(Q.positive_definite(arg), assumptions)
             for arg in mmul.args) and factor > 0):
         return True
     if len(mmul.args) >= 2 and mmul.args[0] == mmul.args[-1].T:
         return ask(Q.positive_definite(
             MatMul(*mmul.args[1:-1])), assumptions)
Пример #18
0
def test_custom_context():
    """Test ask with custom assumptions context"""
    x = symbols('x')
    assert ask(Q.integer(x)) == None
    local_context = AssumptionsContext()
    local_context.add(Q.integer(x))
    assert ask(Q.integer(x), context = local_context) == True
    assert ask(Q.integer(x)) == None
Пример #19
0
 def MatMul(expr, assumptions):
     factor, mmul = expr.as_coeff_mmul()
     if all(ask(Q.symmetric(arg), assumptions) for arg in mmul.args):
         return True
     if len(mmul.args) >= 2 and mmul.args[0] == mmul.args[-1].T:
         if len(mmul.args) == 2:
             return True
         return ask(Q.symmetric(MatMul(*mmul.args[1:-1])), assumptions)
Пример #20
0
def test_global():
    """Test ask with global assumptions"""
    x = symbols('x')
    assert ask(Q.integer(x)) == None
    global_assumptions.add(Q.integer(x))
    assert ask(Q.integer(x)) == True
    global_assumptions.clear()
    assert ask(Q.integer(x)) == None
Пример #21
0
 def Pow(expr, assumptions):
     """
     Hermitian**Integer -> Hermitian
     """
     if expr.is_number:
         return AskRealHandler._number(expr, assumptions)
     if ask(Q.hermitian(expr.base), assumptions):
         if ask(Q.integer(expr.exp), assumptions):
             return True
Пример #22
0
 def Pow(expr, assumptions):
     if expr.is_number: return expr.evalf() > 0
     if ask(Q.positive(expr.base), assumptions):
         return True
     if ask(Q.negative(expr.base), assumptions):
         if ask(Q.even(expr.exp), assumptions):
             return True
         if ask(Q.even(expr.exp), assumptions):
             return False
Пример #23
0
 def MatrixSlice(expr, assumptions):
     # TODO: implement sathandlers system for the matrices.
     # Now it duplicates the general fact: Implies(Q.diagonal, Q.symmetric).
     if ask(Q.diagonal(expr), assumptions):
         return True
     if not expr.on_diag:
         return None
     else:
         return ask(Q.symmetric(expr.parent), assumptions)
Пример #24
0
 def MatrixSymbol(expr, assumptions):
     if not expr.is_square:
         return False
     # TODO: implement sathandlers system for the matrices.
     # Now it duplicates the general fact: Implies(Q.diagonal, Q.symmetric).
     if ask(Q.diagonal(expr), assumptions):
         return True
     if Q.symmetric(expr) in conjuncts(assumptions):
         return True
Пример #25
0
 def MatPow(expr, assumptions):
     # only for integer powers
     base, exp = expr.args
     int_exp = ask(Q.integer(exp), assumptions)
     if not int_exp:
         return None
     if exp.is_negative == False:
         return ask(Q.integer_elements(base), assumptions)
     return None
Пример #26
0
 def Mul(expr, assumptions):
     if expr.is_number:
         return AskPositiveHandler._number(expr, assumptions)
     result = True
     for arg in expr.args:
         if ask(Q.positive(arg), assumptions): continue
         elif ask(Q.negative(arg), assumptions):
             result = result ^ True
         else: return
     return result
Пример #27
0
 def Pow(expr, assumptions):
     if expr.is_number:
         return AskEvenHandler._number(expr, assumptions)
     if ask(Q.integer(expr.exp), assumptions):
         if ask(Q.positive(expr.exp), assumptions):
             return ask(Q.even(expr.base), assumptions)
         elif ask(~Q.negative(expr.exp) & Q.odd(expr.base), assumptions):
             return False
         elif expr.base is S.NegativeOne:
             return False
Пример #28
0
 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
Пример #29
0
    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
Пример #30
0
 def Pow(expr, assumptions):
     """
     Rational ** Integer      -> Rational
     Irrational ** Rational   -> Irrational
     Rational ** Irrational   -> ?
     """
     if ask(Q.integer(expr.exp), assumptions):
         return ask(Q.rational(expr.base), assumptions)
     elif ask(Q.rational(expr.exp), assumptions):
         if ask(Q.prime(expr.base), assumptions):
             return False
Пример #31
0
def is_extended_nonnegative(obj, assumptions=None):
    if assumptions is None:
        return obj.is_extended_nonnegative
    return ask(Q.extended_nonnegative(obj), assumptions)
Пример #32
0
 def MatrixSymbol(expr, assumptions):
     if not expr.is_square:
         return False
     if Q.invertible(expr) in conjuncts(assumptions):
         return True
Пример #33
0
 def log(expr, assumptions):
     return ask(Q.finite(expr.args[0]), assumptions)
Пример #34
0
 def Transpose(expr, assumptions):
     return ask(Q.orthogonal(expr.arg), assumptions)
Пример #35
0
 def MatrixSlice(expr, assumptions):
     if not expr.on_diag:
         return None
     else:
         return ask(Q.invertible(expr.parent), assumptions)
Пример #36
0
 def MatrixSlice(expr, assumptions):
     if not expr.on_diag:
         return None
     else:
         return ask(Q.positive_definite(expr.parent), assumptions)
Пример #37
0
 def MatrixSymbol(expr, assumptions):
     if (not expr.is_square
             or ask(Q.invertible(expr), assumptions) is False):
         return False
     if Q.unitary(expr) in conjuncts(assumptions):
         return True
Пример #38
0
 def Transpose(expr, assumptions):
     return ask(Q.lower_triangular(expr.arg), assumptions)
Пример #39
0
 def MatrixSymbol(expr, assumptions):
     if Q.upper_triangular(expr) in conjuncts(assumptions):
         return True
Пример #40
0
 def Inverse(expr, assumptions):
     return ask(Q.upper_triangular(expr.arg), assumptions)
Пример #41
0
 def MatrixSlice(expr, assumptions):
     if not expr.on_diag:
         return None
     else:
         return ask(Q.upper_triangular(expr.parent), assumptions)
Пример #42
0
 def MatMul(expr, assumptions):
     factor, matrices = expr.as_coeff_matrices()
     if all(ask(Q.lower_triangular(m), assumptions) for m in matrices):
         return True
Пример #43
0
def is_extended_real(obj, assumptions=None):
    if assumptions is None:
        return obj.is_extended_real
    return ask(Q.extended_real(obj), assumptions)
Пример #44
0
 def Transpose(expr, assumptions):
     return ask(Q.positive_definite(expr.arg), assumptions)
Пример #45
0
 def Transpose(expr, assumptions):
     return ask(Q.unitary(expr.arg), assumptions)
Пример #46
0
 def MatrixSymbol(expr, assumptions):
     if not expr.is_square:
         return False
     if Q.positive_definite(expr) in conjuncts(assumptions):
         return True
Пример #47
0
 def MatrixSlice(expr, assumptions):
     if not expr.on_diag:
         return None
     else:
         return ask(Q.orthogonal(expr.parent), assumptions)
Пример #48
0
 def MatAdd(expr, assumptions):
     if all(
             ask(Q.positive_definite(arg), assumptions)
             for arg in expr.args):
         return True
Пример #49
0
 def MatAdd(expr, assumptions):
     if (len(expr.args) == 1
             and ask(Q.orthogonal(expr.args[0]), assumptions)):
         return True
Пример #50
0
 def MatPow(expr, assumptions):
     # a power of a positive definite matrix is positive definite
     if ask(Q.positive_definite(expr.args[0]), assumptions):
         return True
Пример #51
0
 def Transpose(expr, assumptions):
     return ask(Q.invertible(expr.arg), assumptions)
Пример #52
0
 def MatrixSlice(expr, assumptions):
     if ask(Q.orthogonal(expr.parent), assumptions):
         return True
Пример #53
0
    def Add(expr, assumptions):
        """
        Return True if expr is bounded, False if not and None if unknown.

        Truth Table:

        +-------+-----+-----------+-----------+
        |       |     |           |           |
        |       |  B  |     U     |     ?     |
        |       |     |           |           |
        +-------+-----+---+---+---+---+---+---+
        |       |     |   |   |   |   |   |   |
        |       |     |'+'|'-'|'x'|'+'|'-'|'x'|
        |       |     |   |   |   |   |   |   |
        +-------+-----+---+---+---+---+---+---+
        |       |     |           |           |
        |   B   |  B  |     U     |     ?     |
        |       |     |           |           |
        +---+---+-----+---+---+---+---+---+---+
        |   |   |     |   |   |   |   |   |   |
        |   |'+'|     | U | ? | ? | U | ? | ? |
        |   |   |     |   |   |   |   |   |   |
        |   +---+-----+---+---+---+---+---+---+
        |   |   |     |   |   |   |   |   |   |
        | U |'-'|     | ? | U | ? | ? | U | ? |
        |   |   |     |   |   |   |   |   |   |
        |   +---+-----+---+---+---+---+---+---+
        |   |   |     |           |           |
        |   |'x'|     |     ?     |     ?     |
        |   |   |     |           |           |
        +---+---+-----+---+---+---+---+---+---+
        |       |     |           |           |
        |   ?   |     |           |     ?     |
        |       |     |           |           |
        +-------+-----+-----------+---+---+---+

            * 'B' = Bounded

            * 'U' = Unbounded

            * '?' = unknown boundedness

            * '+' = positive sign

            * '-' = negative sign

            * 'x' = sign unknown

|

            * All Bounded -> True

            * 1 Unbounded and the rest Bounded -> False

            * >1 Unbounded, all with same known sign -> False

            * Any Unknown and unknown sign -> None

            * Else -> None

        When the signs are not the same you can have an undefined
        result as in oo - oo, hence 'bounded' is also undefined.

        """

        sign = -1  # sign of unknown or infinite
        result = True
        for arg in expr.args:
            _bounded = ask(Q.finite(arg), assumptions)
            if _bounded:
                continue
            s = ask(Q.positive(arg), assumptions)
            # if there has been more than one sign or if the sign of this arg
            # is None and Bounded is None or there was already
            # an unknown sign, return None
            if sign != -1 and s != sign or \
                    s is None and (s == _bounded or s == sign):
                return None
            else:
                sign = s
            # once False, do not change
            if result is not False:
                result = _bounded
        return result
Пример #54
0
 def Transpose(expr, assumptions):
     return ask(Q.fullrank(expr.arg), assumptions)
Пример #55
0
def refine_Pow(expr, assumptions):
    """
    Handler for instances of Pow.

    >>> from sympy import Symbol, Q
    >>> from sympy.assumptions.refine import refine_Pow
    >>> from sympy.abc import x,y,z
    >>> refine_Pow((-1)**x, Q.real(x))
    >>> refine_Pow((-1)**x, Q.even(x))
    1
    >>> refine_Pow((-1)**x, Q.odd(x))
    -1

    For powers of -1, even parts of the exponent can be simplified:

    >>> refine_Pow((-1)**(x+y), Q.even(x))
    (-1)**y
    >>> refine_Pow((-1)**(x+y+z), Q.odd(x) & Q.odd(z))
    (-1)**y
    >>> refine_Pow((-1)**(x+y+2), Q.odd(x))
    (-1)**(y + 1)
    >>> refine_Pow((-1)**(x+3), True)
    (-1)**(x + 1)

    """
    from sympy.core import Pow, Rational
    from sympy.functions.elementary.complexes import Abs
    from sympy.functions import sign
    if isinstance(expr.base, Abs):
        if ask(Q.real(expr.base.args[0]), assumptions) and \
                ask(Q.even(expr.exp), assumptions):
            return expr.base.args[0] ** expr.exp
    if ask(Q.real(expr.base), assumptions):
        if expr.base.is_number:
            if ask(Q.even(expr.exp), assumptions):
                return abs(expr.base) ** expr.exp
            if ask(Q.odd(expr.exp), 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)

        if expr.base is S.NegativeOne:
            if expr.exp.is_Add:

                old = expr

                # For powers of (-1) we can remove
                #  - even terms
                #  - pairs of odd terms
                #  - a single odd term + 1
                #  - A numerical constant N can be replaced with mod(N,2)

                coeff, terms = expr.exp.as_coeff_add()
                terms = set(terms)
                even_terms = set([])
                odd_terms = set([])
                initial_number_of_terms = len(terms)

                for t in terms:
                    if ask(Q.even(t), assumptions):
                        even_terms.add(t)
                    elif ask(Q.odd(t), assumptions):
                        odd_terms.add(t)

                terms -= even_terms
                if len(odd_terms) % 2:
                    terms -= odd_terms
                    new_coeff = (coeff + S.One) % 2
                else:
                    terms -= odd_terms
                    new_coeff = coeff % 2

                if new_coeff != coeff or len(terms) < initial_number_of_terms:
                    terms.add(new_coeff)
                    expr = expr.base**(Add(*terms))

                # Handle (-1)**((-1)**n/2 + m/2)
                e2 = 2*expr.exp
                if ask(Q.even(e2), assumptions):
                    if e2.could_extract_minus_sign():
                        e2 *= expr.base
                if e2.is_Add:
                    i, p = e2.as_two_terms()
                    if p.is_Pow and p.base is S.NegativeOne:
                        if ask(Q.integer(p.exp), assumptions):
                            i = (i + 1)/2
                            if ask(Q.even(i), assumptions):
                                return expr.base**p.exp
                            elif ask(Q.odd(i), assumptions):
                                return expr.base**(p.exp + 1)
                            else:
                                return expr.base**(p.exp + i)

                if old != expr:
                    return expr
Пример #56
0
 def MatMul(expr, assumptions):
     if all(ask(Q.fullrank(arg), assumptions) for arg in expr.args):
         return True
Пример #57
0
def test_assumptions():
    rl = rewriterule(x + y, x**y, [x, y], assume=Q.integer(x))

    a, b = map(Symbol, 'ab')
    expr = a + b
    assert list(rl(expr, Q.integer(b))) == [b**a]
Пример #58
0
 def MatrixSlice(expr, assumptions):
     if not expr.on_diag:
         return None
     else:
         return ask(Q.unitary(expr.parent), assumptions)
Пример #59
0
def is_infinite(obj, assumptions=None):
    if assumptions is None:
        return obj.is_infinite
    return ask(Q.infinite(obj), assumptions)
Пример #60
0
 def MatAdd(expr, assumptions):
     if all(ask(Q.lower_triangular(arg), assumptions) for arg in expr.args):
         return True