Beispiel #1
0
 def cond():
     d = self._smat
     yield self.is_square
     if len(d) <= self.rows:
         yield fuzzy_and(d[i, i].is_real for i, j in d if i == j)
     else:
         yield fuzzy_and(d[i, i].is_real for i in range(self.rows) if (i, i) in d)
     yield fuzzy_and(((self[i, j] - self[j, i].conjugate()).is_zero if (j, i) in d else False) for (i, j) in d)
Beispiel #2
0
def test_fuzzy_and():
    assert fuzzy_and([T, T]) == T
    assert fuzzy_and([T, F]) == F
    assert fuzzy_and([T, U]) == U
    assert fuzzy_and([F, F]) == F
    assert fuzzy_and([F, U]) == F
    assert fuzzy_and([U, U]) == U
    assert [fuzzy_and([w]) for w in [U, T, F]] == [U, T, F]
    assert fuzzy_and([T, F, U]) == F
    assert fuzzy_and([]) == T
    raises(TypeError, lambda: fuzzy_and())
Beispiel #3
0
    def __new__(cls, *args):
        n = args[BinomialDistribution._argnames.index('n')]
        p = args[BinomialDistribution._argnames.index('p')]
        n_sym = sympify(n)
        p_sym = sympify(p)

        if fuzzy_not(fuzzy_and((n_sym.is_integer, n_sym.is_nonnegative))):
            raise ValueError("'n' must be positive integer. n = %s." % str(n))
        elif fuzzy_not(fuzzy_and((p_sym.is_nonnegative, (p_sym - 1).is_nonpositive))):
            raise ValueError("'p' must be: 0 <= p <= 1 . p = %s" % str(p))
        else:
            return super(BinomialDistribution, cls).__new__(cls, *args)
Beispiel #4
0
    def __new__(cls, *args):
        p = args[BernoulliDistribution._argnames.index('p')]
        p_sym = sympify(p)

        if fuzzy_not(fuzzy_and((p_sym.is_nonnegative, (p_sym - 1).is_nonpositive))):
            raise ValueError("p = %s is not in range [0, 1]." % str(p))
        else:
            return super(BernoulliDistribution, cls).__new__(cls, *args)
Beispiel #5
0
def _old_assump_replacer(obj):
    # Things to be careful of:
    # - real means real or infinite in the old assumptions.
    # - nonzero does not imply real in the old assumptions.
    # - finite means finite and not zero in the old assumptions.
    if not isinstance(obj, AppliedPredicate):
        return obj

    e = obj.args[0]
    ret = None

    if obj.func == Q.positive:
        ret = fuzzy_and([e.is_finite, e.is_positive])
    if obj.func == Q.zero:
        ret = e.is_zero
    if obj.func == Q.negative:
        ret = fuzzy_and([e.is_finite, e.is_negative])
    if obj.func == Q.nonpositive:
        ret = fuzzy_and([e.is_finite, e.is_nonpositive])
    if obj.func == Q.nonzero:
        ret = fuzzy_and([e.is_nonzero, e.is_finite])
    if obj.func == Q.nonnegative:
        ret = fuzzy_and([fuzzy_or([e.is_zero, e.is_finite]),
        e.is_nonnegative])

    if obj.func == Q.rational:
        ret = e.is_rational
    if obj.func == Q.irrational:
        ret = e.is_irrational

    if obj.func == Q.even:
        ret = e.is_even
    if obj.func == Q.odd:
        ret = e.is_odd
    if obj.func == Q.integer:
        ret = e.is_integer
    if obj.func == Q.imaginary:
        ret = e.is_imaginary
    if obj.func == Q.commutative:
        ret = e.is_commutative

    if ret is None:
        return obj
    return ret
Beispiel #6
0
 def __new__(cls, density):
     density = Dict(density)
     for k in density.values():
         k_sym = sympify(k)
         if fuzzy_not(fuzzy_and((k_sym.is_nonnegative, (k_sym - 1).is_nonpositive))):
             raise ValueError("Probability at a point must be between 0 and 1.")
     sum_sym = sum(density.values())
     if sum_sym != 1:
         raise ValueError("Total Probability must be equal to 1.")
     return Basic.__new__(cls, density)
Beispiel #7
0
    def _from_args(cls, args, is_commutative=None):
        """Create new instance with already-processed args"""
        if len(args) == 0:
            return cls.identity
        elif len(args) == 1:
            return args[0]

        obj = super(AssocOp, cls).__new__(cls, *args)
        if is_commutative is None:
            is_commutative = fuzzy_and(a.is_commutative for a in args)
        obj.is_commutative = is_commutative
        return obj
Beispiel #8
0
 def _eval_is_real(self):
     x = self.args[0]
     if len(self.args) == 1:
         k = S.Zero
     else:
         k = self.args[1]
     if k.is_zero:
         return (x + 1/S.Exp1).is_positive
     elif (k + 1).is_zero:
         from sympy.core.logic import fuzzy_and
         return fuzzy_and([x.is_negative, (x + 1/S.Exp1).is_positive])
     elif k.is_nonzero and (k + 1).is_nonzero:
         return False
Beispiel #9
0
    def is_hermitian(self):
        """Checks if the matrix is Hermitian.

        In a Hermitian matrix element i,j is the complex conjugate of
        element j,i.

        Examples
        ========

        >>> from sympy.matrices import SparseMatrix
        >>> from sympy import I
        >>> from sympy.abc import x
        >>> a = SparseMatrix([[1, I], [-I, 1]])
        >>> a
        Matrix([
        [ 1, I],
        [-I, 1]])
        >>> a.is_hermitian
        True
        >>> a[0, 0] = 2*I
        >>> a.is_hermitian
        False
        >>> a[0, 0] = x
        >>> a.is_hermitian
        >>> a[0, 1] = a[1, 0]*I
        >>> a.is_hermitian
        False
        """
        def cond():
            d = self._smat
            yield self.is_square
            if len(d) <= self.rows:
                yield fuzzy_and(
                    d[i, i].is_real for i, j in d if i == j)
            else:
                yield fuzzy_and(
                    d[i, i].is_real for i in range(self.rows) if (i, i) in d)
            yield fuzzy_and(
                    ((self[i, j] - self[j, i].conjugate()).is_zero
                    if (j, i) in d else False) for (i, j) in d)
        return fuzzy_and(i for i in cond())
 def _eval_is_integer(self):
     return fuzzy_and([self.args[0].is_integer, self.args[0].is_positive])
Beispiel #11
0
def _(a, b):
    if a.step == b.step == 1:
        return fuzzy_and(
            [fuzzy_bool(a.start >= b.start),
             fuzzy_bool(a.stop <= b.stop)])
Beispiel #12
0
def MatMul_elements(matrix_predicate, scalar_predicate, expr, assumptions):
    d = sift(expr.args, lambda x: isinstance(x, MatrixExpr))
    factors, matrices = d[False], d[True]
    return fuzzy_and([
        test_closed_group(Basic(*factors), assumptions, scalar_predicate),
        test_closed_group(Basic(*matrices), assumptions, matrix_predicate)])
Beispiel #13
0
 def _eval_is_positive(self):
     return fuzzy_and(a.is_positive for a in self.args)
Beispiel #14
0
def _eval_is_eq(lhs, rhs):  # noqa: F811
    if len(lhs.sets) != len(rhs.sets):
        return False

    eqs = (is_eq(x, y) for x, y in zip(lhs.sets, rhs.sets))
    return tfn[fuzzy_and(map(fuzzy_bool, eqs))]
Beispiel #15
0
 def __new__(cls, sides):
     sides_sym = sympify(sides)
     if fuzzy_not(fuzzy_and((sides_sym.is_integer, sides_sym.is_positive))):
         raise ValueError("'sides' must be a positive integer.")
     else:
         return super(DieDistribution, cls).__new__(cls, sides)
Beispiel #16
0
 def _eval_is_extended_negative(self):
     return fuzzy_and(arg.is_extended_negative for arg in self.args)
Beispiel #17
0
 def _eval_is_extended_real(self):
     return fuzzy_and(arg.is_extended_real for arg in self.args)
 def _eval_is_integer(self):
     from sympy.core.logic import fuzzy_and, fuzzy_not
     p, q = self.args
     if fuzzy_and([p.is_integer, q.is_integer, fuzzy_not(q.is_zero)]):
         return True
Beispiel #19
0
def MatMul_elements(matrix_predicate, scalar_predicate, expr, assumptions):
    d = sift(expr.args, lambda x: isinstance(x, MatrixExpr))
    factors, matrices = d[False], d[True]
    return fuzzy_and([
        test_closed_group(Basic(*factors), assumptions, scalar_predicate),
        test_closed_group(Basic(*matrices), assumptions, matrix_predicate)])
Beispiel #20
0
def is_eq(lhs, rhs):
    """
    Fuzzy bool representing mathematical equality between lhs and rhs.

    :param lhs: the left-hand side of the expression, must be sympified
    :param rhs: the right-hand side of the expression, must be sympified
    :return: True if lhs is equal to rhs, false is lhs is not equal to rhs, and
            None if the comparison between lhs and rhs is indeterminate

    Notes:

    This function is intended to give a relatively fast determination and deliberately does not attempt slow
    calculations that might help in obtaining a determination of True or False in more difficult cases.

    InEquality classes, such as Lt, Gt, etc. Use one of is_ge, is_le, etc.
    To implement comparisons with ``Gt(a, b)`` or ``a > b`` etc for an ``Expr`` subclass
    it is only necessary to define a dispatcher method for ``_eval_is_ge`` like

    >>> from sympy.core.relational import is_eq
    >>> from sympy.core.relational import is_neq
    >>> from sympy import S, Basic, Eq, sympify
    >>> from sympy.abc import x
    >>> from sympy.multipledispatch import dispatch
    >>> class MyBasic(Basic):
    ...     def __new__(cls, arg):
    ...         return Basic.__new__(cls, sympify(arg))
    ...     @property
    ...     def value(self):
    ...         return self.args[0]
    ...
    >>> @dispatch(MyBasic, MyBasic)
    ... def _eval_is_eq(a, b):
    ...     return is_eq(a.value, b.value)
    ...
    >>> a = MyBasic(1)
    >>> b = MyBasic(1)
    >>> a == b
    True
    >>> Eq(a, b)
    True
    >>> a != b
    False
    >>> is_eq(a, b)
    True


    Examples
    ========



    >>> is_eq(S(0), S(0))
    True
    >>> Eq(0, 0)
    True
    >>> is_neq(S(0), S(0))
    False
    >>> is_eq(S(0), S(2))
    False
    >>> Eq(0, 2)
    False
    >>> is_neq(S(0), S(2))
    True
    >>> is_eq(S(0), x)

    >>> Eq(S(0), x)
    Eq(0, x)



    """
    from sympy.core.add import Add
    from sympy.functions.elementary.complexes import arg
    from sympy.simplify.simplify import clear_coefficients
    from sympy.utilities.iterables import sift

    # here, _eval_Eq is only called for backwards compatibility
    # new code should use is_eq with multiple dispatch as
    # outlined in the docstring
    for side1, side2 in (lhs, rhs), (rhs, lhs):
        eval_func = getattr(side1, '_eval_Eq', None)
        if eval_func is not None:
            retval = eval_func(side2)
            if retval is not None:
                return retval

    retval = _eval_is_eq(lhs, rhs)
    if retval is not None:
        return retval

    if dispatch(type(lhs), type(rhs)) != dispatch(type(rhs), type(lhs)):
        retval = _eval_is_eq(rhs, lhs)
        if retval is not None:
            return retval

    # retval is still None, so go through the equality logic
    # If expressions have the same structure, they must be equal.
    if lhs == rhs:
        return True  # e.g. True == True
    elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)):
        return False  # True != False
    elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance(lhs, Boolean) !=
                                                   isinstance(rhs, Boolean)):
        return False  # only Booleans can equal Booleans

    if lhs.is_infinite or rhs.is_infinite:
        if fuzzy_xor([lhs.is_infinite, rhs.is_infinite]):
            return False
        if fuzzy_xor([lhs.is_extended_real, rhs.is_extended_real]):
            return False
        if fuzzy_and([lhs.is_extended_real, rhs.is_extended_real]):
            return fuzzy_xor([
                lhs.is_extended_positive,
                fuzzy_not(rhs.is_extended_positive)
            ])

        # Try to split real/imaginary parts and equate them
        I = S.ImaginaryUnit

        def split_real_imag(expr):
            real_imag = lambda t: ('real' if t.is_extended_real else 'imag'
                                   if (I * t).is_extended_real else None)
            return sift(Add.make_args(expr), real_imag)

        lhs_ri = split_real_imag(lhs)
        if not lhs_ri[None]:
            rhs_ri = split_real_imag(rhs)
            if not rhs_ri[None]:
                eq_real = Eq(Add(*lhs_ri['real']), Add(*rhs_ri['real']))
                eq_imag = Eq(I * Add(*lhs_ri['imag']),
                             I * Add(*rhs_ri['imag']))
                return fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag]))

        # Compare e.g. zoo with 1+I*oo by comparing args
        arglhs = arg(lhs)
        argrhs = arg(rhs)
        # Guard against Eq(nan, nan) -> Falsesymp
        if not (arglhs == S.NaN and argrhs == S.NaN):
            return fuzzy_bool(Eq(arglhs, argrhs))

    if all(isinstance(i, Expr) for i in (lhs, rhs)):
        # see if the difference evaluates
        dif = lhs - rhs
        z = dif.is_zero
        if z is not None:
            if z is False and dif.is_commutative:  # issue 10728
                return False
            if z:
                return True

        n2 = _n2(lhs, rhs)
        if n2 is not None:
            return _sympify(n2 == 0)

        # see if the ratio evaluates
        n, d = dif.as_numer_denom()
        rv = None
        if n.is_zero:
            rv = d.is_nonzero
        elif n.is_finite:
            if d.is_infinite:
                rv = True
            elif n.is_zero is False:
                rv = d.is_infinite
                if rv is None:
                    # if the condition that makes the denominator
                    # infinite does not make the original expression
                    # True then False can be returned
                    l, r = clear_coefficients(d, S.Infinity)
                    args = [_.subs(l, r) for _ in (lhs, rhs)]
                    if args != [lhs, rhs]:
                        rv = fuzzy_bool(Eq(*args))
                        if rv is True:
                            rv = None
        elif any(a.is_infinite for a in Add.make_args(n)):
            # (inf or nan)/x != 0
            rv = False
        if rv is not None:
            return rv
Beispiel #21
0
def _eval_is_eq(lhs, rhs):  # noqa: F811
    return tfn[fuzzy_and(a.is_subset(b) for a, b in [(lhs, rhs), (rhs, lhs)])]
Beispiel #22
0
 def __getitem__(self, i):
     from sympy.functions.elementary.integers import ceiling
     ooslice = "cannot slice from the end with an infinite value"
     zerostep = "slice step cannot be zero"
     infinite = "slicing not possible on range with infinite start"
     # if we had to take every other element in the following
     # oo, ..., 6, 4, 2, 0
     # we might get oo, ..., 4, 0 or oo, ..., 6, 2
     ambiguous = "cannot unambiguously re-stride from the end " + \
         "with an infinite value"
     if isinstance(i, slice):
         if self.size.is_finite:  # validates, too
             if self.start == self.stop:
                 return Range(0)
             start, stop, step = i.indices(self.size)
             n = ceiling((stop - start)/step)
             if n <= 0:
                 return Range(0)
             canonical_stop = start + n*step
             end = canonical_stop - step
             ss = step*self.step
             return Range(self[start], self[end] + ss, ss)
         else:  # infinite Range
             start = i.start
             stop = i.stop
             if i.step == 0:
                 raise ValueError(zerostep)
             step = i.step or 1
             ss = step*self.step
             #---------------------
             # handle infinite Range
             #   i.e. Range(-oo, oo) or Range(oo, -oo, -1)
             # --------------------
             if self.start.is_infinite and self.stop.is_infinite:
                 raise ValueError(infinite)
             #---------------------
             # handle infinite on right
             #   e.g. Range(0, oo) or Range(0, -oo, -1)
             # --------------------
             if self.stop.is_infinite:
                 # start and stop are not interdependent --
                 # they only depend on step --so we use the
                 # equivalent reversed values
                 return self.reversed[
                     stop if stop is None else -stop + 1:
                     start if start is None else -start:
                     step].reversed
             #---------------------
             # handle infinite on the left
             #   e.g. Range(oo, 0, -1) or Range(-oo, 0)
             # --------------------
             # consider combinations of
             # start/stop {== None, < 0, == 0, > 0} and
             # step {< 0, > 0}
             if start is None:
                 if stop is None:
                     if step < 0:
                         return Range(self[-1], self.start, ss)
                     elif step > 1:
                         raise ValueError(ambiguous)
                     else:  # == 1
                         return self
                 elif stop < 0:
                     if step < 0:
                         return Range(self[-1], self[stop], ss)
                     else:  # > 0
                         return Range(self.start, self[stop], ss)
                 elif stop == 0:
                     if step > 0:
                         return Range(0)
                     else:  # < 0
                         raise ValueError(ooslice)
                 elif stop == 1:
                     if step > 0:
                         raise ValueError(ooslice)  # infinite singleton
                     else:  # < 0
                         raise ValueError(ooslice)
                 else:  # > 1
                     raise ValueError(ooslice)
             elif start < 0:
                 if stop is None:
                     if step < 0:
                         return Range(self[start], self.start, ss)
                     else:  # > 0
                         return Range(self[start], self.stop, ss)
                 elif stop < 0:
                     return Range(self[start], self[stop], ss)
                 elif stop == 0:
                     if step < 0:
                         raise ValueError(ooslice)
                     else:  # > 0
                         return Range(0)
                 elif stop > 0:
                     raise ValueError(ooslice)
             elif start == 0:
                 if stop is None:
                     if step < 0:
                         raise ValueError(ooslice)  # infinite singleton
                     elif step > 1:
                         raise ValueError(ambiguous)
                     else:  # == 1
                         return self
                 elif stop < 0:
                     if step > 1:
                         raise ValueError(ambiguous)
                     elif step == 1:
                         return Range(self.start, self[stop], ss)
                     else:  # < 0
                         return Range(0)
                 else:  # >= 0
                     raise ValueError(ooslice)
             elif start > 0:
                 raise ValueError(ooslice)
     else:
         if self.start == self.stop:
             raise IndexError('Range index out of range')
         if not (all(i.is_integer or i.is_infinite
                 for i in self.args) and ((self.stop - self.start)/
                 self.step).is_extended_positive):
             raise ValueError('Invalid method for symbolic Range')
         if i == 0:
             if self.start.is_infinite:
                 raise ValueError(ooslice)
             return self.start
         if i == -1:
             if self.stop.is_infinite:
                 raise ValueError(ooslice)
             return self.stop - self.step
         n = self.size  # must be known for any other index
         rv = (self.stop if i < 0 else self.start) + i*self.step
         if rv.is_infinite:
             raise ValueError(ooslice)
         val = (rv - self.start)/self.step
         rel = fuzzy_or([val.is_infinite,
                         fuzzy_and([val.is_nonnegative, (n-val).is_nonnegative])])
         if rel:
             return rv
         if rel is None:
             raise ValueError('Invalid method for symbolic Range')
         raise IndexError("Range index out of range")
Beispiel #23
0
def _(expr, assumptions):
    if expr.rowblocksizes != expr.colblocksizes:
        return None
    return fuzzy_and([ask(Q.invertible(a), assumptions) for a in expr.diag])
Beispiel #24
0
def _eval_is_eq(lhs, rhs):  # noqa:F811
    if len(lhs) != len(rhs):
        return False

    return fuzzy_and(fuzzy_bool(is_eq(s, o)) for s, o in zip(lhs, rhs))
Beispiel #25
0
 def _eval_is_finite(self):
     return fuzzy_and(arg.is_finite for arg in self.args)
Beispiel #26
0
 def all_in_both():
     s_set = set(lhs.args)
     o_set = set(rhs.args)
     yield fuzzy_and(lhs._contains(e) for e in o_set - s_set)
     yield fuzzy_and(rhs._contains(e) for e in s_set - o_set)
Beispiel #27
0
 def _eval_is_complex(self):
     z = self.args[0]
     return fuzzy_and([z.is_complex, fuzzy_not(z.is_zero)])
Beispiel #28
0
 def _eval_is_integer(self):
     from sympy.core.logic import fuzzy_and
     p, q = self.args
     return fuzzy_and([p.is_integer, q.is_integer, q.is_nonzero])
Beispiel #29
0
def is_eq(lhs, rhs, assumptions=None):
    """
    Fuzzy bool representing mathematical equality between *lhs* and *rhs*.

    Parameters
    ==========

    lhs : Expr
        The left-hand side of the expression, must be sympified.

    rhs : Expr
        The right-hand side of the expression, must be sympified.

    assumptions: Boolean, optional
        Assumptions taken to evaluate the equality.

    Returns
    =======

    ``True`` if *lhs* is equal to *rhs*, ``False`` is *lhs* is not equal to *rhs*,
    and ``None`` if the comparison between *lhs* and *rhs* is indeterminate.

    Explanation
    ===========

    This function is intended to give a relatively fast determination and
    deliberately does not attempt slow calculations that might help in
    obtaining a determination of True or False in more difficult cases.

    :func:`~.is_neq` calls this function to return its value, so supporting
    new type with this function will ensure correct behavior for ``is_neq``
    as well.

    Examples
    ========

    >>> from sympy import Q, S
    >>> from sympy.core.relational import is_eq, is_neq
    >>> from sympy.abc import x
    >>> is_eq(S(0), S(0))
    True
    >>> is_neq(S(0), S(0))
    False
    >>> is_eq(S(0), S(2))
    False
    >>> is_neq(S(0), S(2))
    True

    Assumptions can be passed to evaluate the equality which is otherwise
    indeterminate.

    >>> print(is_eq(x, S(0)))
    None
    >>> is_eq(x, S(0), assumptions=Q.zero(x))
    True

    New types can be supported by dispatching to ``_eval_is_eq``.

    >>> from sympy import Basic, sympify
    >>> from sympy.multipledispatch import dispatch
    >>> class MyBasic(Basic):
    ...     def __new__(cls, arg):
    ...         return Basic.__new__(cls, sympify(arg))
    ...     @property
    ...     def value(self):
    ...         return self.args[0]
    ...
    >>> @dispatch(MyBasic, MyBasic)
    ... def _eval_is_eq(a, b):
    ...     return is_eq(a.value, b.value)
    ...
    >>> a = MyBasic(1)
    >>> b = MyBasic(1)
    >>> is_eq(a, b)
    True
    >>> is_neq(a, b)
    False

    """
    from sympy.assumptions.wrapper import (AssumptionsWrapper,
        is_infinite, is_extended_real)
    from sympy.core.add import Add
    from sympy.functions.elementary.complexes import arg
    from sympy.simplify.simplify import clear_coefficients
    from sympy.utilities.iterables import sift

    # here, _eval_Eq is only called for backwards compatibility
    # new code should use is_eq with multiple dispatch as
    # outlined in the docstring
    for side1, side2 in (lhs, rhs), (rhs, lhs):
        eval_func = getattr(side1, '_eval_Eq', None)
        if eval_func is not None:
            retval = eval_func(side2)
            if retval is not None:
                return retval

    retval = _eval_is_eq(lhs, rhs)
    if retval is not None:
        return retval

    if dispatch(type(lhs), type(rhs)) != dispatch(type(rhs), type(lhs)):
        retval = _eval_is_eq(rhs, lhs)
        if retval is not None:
            return retval

    # retval is still None, so go through the equality logic
    # If expressions have the same structure, they must be equal.
    if lhs == rhs:
        return True  # e.g. True == True
    elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)):
        return False  # True != False
    elif not (lhs.is_Symbol or rhs.is_Symbol) and (
        isinstance(lhs, Boolean) !=
        isinstance(rhs, Boolean)):
        return False  # only Booleans can equal Booleans

    _lhs = AssumptionsWrapper(lhs, assumptions)
    _rhs = AssumptionsWrapper(rhs, assumptions)

    if _lhs.is_infinite or _rhs.is_infinite:
        if fuzzy_xor([_lhs.is_infinite, _rhs.is_infinite]):
            return False
        if fuzzy_xor([_lhs.is_extended_real, _rhs.is_extended_real]):
            return False
        if fuzzy_and([_lhs.is_extended_real, _rhs.is_extended_real]):
            return fuzzy_xor([_lhs.is_extended_positive, fuzzy_not(_rhs.is_extended_positive)])

        # Try to split real/imaginary parts and equate them
        I = S.ImaginaryUnit

        def split_real_imag(expr):
            real_imag = lambda t: (
                'real' if is_extended_real(t, assumptions) else
                'imag' if is_extended_real(I*t, assumptions) else None)
            return sift(Add.make_args(expr), real_imag)

        lhs_ri = split_real_imag(lhs)
        if not lhs_ri[None]:
            rhs_ri = split_real_imag(rhs)
            if not rhs_ri[None]:
                eq_real = is_eq(Add(*lhs_ri['real']), Add(*rhs_ri['real']), assumptions)
                eq_imag = is_eq(I * Add(*lhs_ri['imag']), I * Add(*rhs_ri['imag']), assumptions)
                return fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag]))

        # Compare e.g. zoo with 1+I*oo by comparing args
        arglhs = arg(lhs)
        argrhs = arg(rhs)
        # Guard against Eq(nan, nan) -> Falsesymp
        if not (arglhs == S.NaN and argrhs == S.NaN):
            return fuzzy_bool(is_eq(arglhs, argrhs, assumptions))

    if all(isinstance(i, Expr) for i in (lhs, rhs)):
        # see if the difference evaluates
        dif = lhs - rhs
        _dif = AssumptionsWrapper(dif, assumptions)
        z = _dif.is_zero
        if z is not None:
            if z is False and _dif.is_commutative:  # issue 10728
                return False
            if z:
                return True

        n2 = _n2(lhs, rhs)
        if n2 is not None:
            return _sympify(n2 == 0)

        # see if the ratio evaluates
        n, d = dif.as_numer_denom()
        rv = None
        _n = AssumptionsWrapper(n, assumptions)
        _d = AssumptionsWrapper(d, assumptions)
        if _n.is_zero:
            rv = _d.is_nonzero
        elif _n.is_finite:
            if _d.is_infinite:
                rv = True
            elif _n.is_zero is False:
                rv = _d.is_infinite
                if rv is None:
                    # if the condition that makes the denominator
                    # infinite does not make the original expression
                    # True then False can be returned
                    l, r = clear_coefficients(d, S.Infinity)
                    args = [_.subs(l, r) for _ in (lhs, rhs)]
                    if args != [lhs, rhs]:
                        rv = fuzzy_bool(is_eq(*args, assumptions))
                        if rv is True:
                            rv = None
        elif any(is_infinite(a, assumptions) for a in Add.make_args(n)):
            # (inf or nan)/x != 0
            rv = False
        if rv is not None:
            return rv
Beispiel #30
0
    def __new__(cls, lhs, rhs=None, **options):
        from sympy.core.add import Add
        from sympy.core.logic import fuzzy_bool, fuzzy_xor, fuzzy_and, fuzzy_not
        from sympy.core.expr import _n2
        from sympy.functions.elementary.complexes import arg
        from sympy.simplify.simplify import clear_coefficients
        from sympy.utilities.iterables import sift

        if rhs is None:
            SymPyDeprecationWarning(
                feature="Eq(expr) with rhs default to 0",
                useinstead="Eq(expr, 0)",
                issue=16587,
                deprecated_since_version="1.5",
            ).warn()
            rhs = 0

        lhs = _sympify(lhs)
        rhs = _sympify(rhs)

        evaluate = options.pop("evaluate", global_parameters.evaluate)

        if evaluate:
            # If one expression has an _eval_Eq, return its results.
            if hasattr(lhs, "_eval_Eq"):
                r = lhs._eval_Eq(rhs)
                if r is not None:
                    return r
            if hasattr(rhs, "_eval_Eq"):
                r = rhs._eval_Eq(lhs)
                if r is not None:
                    return r
            # If expressions have the same structure, they must be equal.
            if lhs == rhs:
                return S.true  # e.g. True == True
            elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)):
                return S.false  # True != False
            elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance(
                    lhs, Boolean) != isinstance(rhs, Boolean)):
                return S.false  # only Booleans can equal Booleans

            if lhs.is_infinite or rhs.is_infinite:
                if fuzzy_xor([lhs.is_infinite, rhs.is_infinite]):
                    return S.false
                if fuzzy_xor([lhs.is_extended_real, rhs.is_extended_real]):
                    return S.false
                if fuzzy_and([lhs.is_extended_real, rhs.is_extended_real]):
                    r = fuzzy_xor([
                        lhs.is_extended_positive,
                        fuzzy_not(rhs.is_extended_positive)
                    ])
                    return S(r)

                # Try to split real/imaginary parts and equate them
                I = S.ImaginaryUnit

                def split_real_imag(expr):
                    real_imag = lambda t: ("real"
                                           if t.is_extended_real else "imag" if
                                           (I * t).is_extended_real else None)
                    return sift(Add.make_args(expr), real_imag)

                lhs_ri = split_real_imag(lhs)
                if not lhs_ri[None]:
                    rhs_ri = split_real_imag(rhs)
                    if not rhs_ri[None]:
                        eq_real = Eq(Add(*lhs_ri["real"]),
                                     Add(*rhs_ri["real"]))
                        eq_imag = Eq(I * Add(*lhs_ri["imag"]),
                                     I * Add(*rhs_ri["imag"]))
                        res = fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag]))
                        if res is not None:
                            return S(res)

                # Compare e.g. zoo with 1+I*oo by comparing args
                arglhs = arg(lhs)
                argrhs = arg(rhs)
                # Guard against Eq(nan, nan) -> False
                if not (arglhs == S.NaN and argrhs == S.NaN):
                    res = fuzzy_bool(Eq(arglhs, argrhs))
                    if res is not None:
                        return S(res)

                return Relational.__new__(cls, lhs, rhs, **options)

            if all(isinstance(i, Expr) for i in (lhs, rhs)):
                # see if the difference evaluates
                dif = lhs - rhs
                z = dif.is_zero
                if z is not None:
                    if z is False and dif.is_commutative:  # issue 10728
                        return S.false
                    if z:
                        return S.true
                # evaluate numerically if possible
                n2 = _n2(lhs, rhs)
                if n2 is not None:
                    return _sympify(n2 == 0)
                # see if the ratio evaluates
                n, d = dif.as_numer_denom()
                rv = None
                if n.is_zero:
                    rv = d.is_nonzero
                elif n.is_finite:
                    if d.is_infinite:
                        rv = S.true
                    elif n.is_zero is False:
                        rv = d.is_infinite
                        if rv is None:
                            # if the condition that makes the denominator
                            # infinite does not make the original expression
                            # True then False can be returned
                            l, r = clear_coefficients(d, S.Infinity)
                            args = [_.subs(l, r) for _ in (lhs, rhs)]
                            if args != [lhs, rhs]:
                                rv = fuzzy_bool(Eq(*args))
                                if rv is True:
                                    rv = None
                elif any(a.is_infinite for a in Add.make_args(n)):
                    # (inf or nan)/x != 0
                    rv = S.false
                if rv is not None:
                    return _sympify(rv)

        return Relational.__new__(cls, lhs, rhs, **options)
Beispiel #31
0
 def _eval_is_nonnegative(self):
     return fuzzy_and(a.is_nonnegative for a in self.args)
Beispiel #32
0
 def _eval_is_complex(self):
     z = self.args[1]
     is_negative_integer = fuzzy_and([z.is_negative, z.is_integer])
     return fuzzy_and([z.is_complex, fuzzy_not(is_negative_integer)])
Beispiel #33
0
def is_subset_sets(a, b):  # noqa:F811
    if a.step == b.step == 1:
        return fuzzy_and(
            [fuzzy_bool(a.start >= b.start),
             fuzzy_bool(a.stop <= b.stop)])
Beispiel #34
0
 def _eval_is_integer(self):
     from sympy.core.logic import fuzzy_and, fuzzy_not
     p, q = self.args
     if fuzzy_and([p.is_integer, q.is_integer, fuzzy_not(q.is_zero)]):
         return True
Beispiel #35
0
 def _eval_is_positive(self):
     return fuzzy_and(a.is_positive for a in self.args)
Beispiel #36
0
def _(a_ps, b_fs):
    return fuzzy_and(b_fs.contains(x) for x in a_ps)
Beispiel #37
0
 def _eval_is_integer(self):
     from sympy.core.logic import fuzzy_and
     p, q = self.args
     return fuzzy_and([p.is_integer, q.is_integer, q.is_nonzero])
Beispiel #38
0
 def _eval_is_nonnegative(self):
     return fuzzy_and(a.is_nonnegative for a in self.args)
Beispiel #39
0
def test_fuzzy_and():
    assert fuzzy_and(*[T, T]) == T
    assert fuzzy_and(*[T, F]) == F
    assert fuzzy_and(*[T, U]) == U
    assert fuzzy_and(*[F, F]) == F
    assert fuzzy_and(*[F, U]) == F
    assert fuzzy_and(*[U, U]) == U
    assert fuzzy_and([T, T]) == T
    assert fuzzy_and([T, F]) == F
    assert fuzzy_and([T, U]) == U
    assert fuzzy_and([F, F]) == F
    assert fuzzy_and([F, U]) == F
    assert fuzzy_and([U, U]) == U
Beispiel #40
0
 def __new__(cls, sides):
     sides_sym = sympify(sides)
     if fuzzy_not(fuzzy_and((sides_sym.is_integer, sides_sym.is_positive))):
         raise ValueError("'sides' must be a positive integer.")
     else:
         return super(DieDistribution, cls).__new__(cls, sides)
Beispiel #41
0
 def _eval_is_positive(self):
     return fuzzy_and((self.args[0].is_integer,
                       (self.args[0] + 1).is_nonnegative))
Beispiel #42
0
 def is_real(self):
     return fuzzy_and(arg.is_real for arg in self.args)
Beispiel #43
0
 def _eval_is_zero(self):
     x = self.args[0]
     if len(self.args) == 1:
         return x.is_zero
     else:
         return fuzzy_and([x.is_zero, self.args[1].is_zero])
Beispiel #44
0
 def _eval_is_ge(lhs, rhs):
     if type(lhs) == PowTest and type(rhs) == PowTest:
         return fuzzy_and([
             is_ge(lhs.args[0], rhs.args[0]),
             is_ge(lhs.args[1], rhs.args[1])
         ])
Beispiel #45
0
def test_fuzzy_and():
    assert fuzzy_and(*[T, T]) == T
    assert fuzzy_and(*[T, F]) == F
    assert fuzzy_and(*[T, U]) == U
    assert fuzzy_and(*[F, F]) == F
    assert fuzzy_and(*[F, U]) == F
    assert fuzzy_and(*[U, U]) == U
    assert fuzzy_and([T, T]) == T
    assert fuzzy_and([T, F]) == F
    assert fuzzy_and([T, U]) == U
    assert fuzzy_and([F, F]) == F
    assert fuzzy_and([F, U]) == F
    assert fuzzy_and([U, U]) == U
    assert [fuzzy_and(w) for w in [U, T, F]] == [U, T, F]
    raises(ValueError, lambda: fuzzy_and([]))
    raises(ValueError, lambda: fuzzy_and())
Beispiel #46
0
 def is_real(self):
     return fuzzy_and(arg.is_real for arg in self.args)
Beispiel #47
0
 def Basic(expr, assumptions):
     return fuzzy_and([fuzzy_not(ask(Q.nonzero(expr), assumptions)),
         ask(Q.real(expr), assumptions)])
Beispiel #48
0
 def _eval_is_integer(self):
     return fuzzy_and((self.args[0].is_integer, self.args[1].is_integer,
                       self.args[1].is_nonnegative))
Beispiel #49
0
def test_fuzzy_and():
    assert fuzzy_and(*[T, T]) == T
    assert fuzzy_and(*[T, F]) == F
    assert fuzzy_and(*[T, U]) == U
    assert fuzzy_and(*[F, F]) == F
    assert fuzzy_and(*[F, U]) == F
    assert fuzzy_and(*[U, U]) == U
    assert fuzzy_and([T, T]) == T
    assert fuzzy_and([T, F]) == F
    assert fuzzy_and([T, U]) == U
    assert fuzzy_and([F, F]) == F
    assert fuzzy_and([F, U]) == F
    assert fuzzy_and([U, U]) == U
    assert [fuzzy_and(w) for w in [U, T, F]] == [U, T, F]
    raises(ValueError, lambda: fuzzy_and([]))
    raises(ValueError, lambda: fuzzy_and())
Beispiel #50
0
def _(expr, assumptions):
    return fuzzy_and([fuzzy_not(ask(Q.nonzero(expr), assumptions)),
        ask(Q.real(expr), assumptions)])
Beispiel #51
0
 def _eval_is_integer(self):
     return fuzzy_and((self.args[0].is_integer, self.args[1].is_integer,
                       self.args[1].is_nonnegative))
Beispiel #52
0
 def _eval_is_integer(self):
     return fuzzy_and([self.args[0].is_integer, self.args[0].is_positive])