Ejemplo n.º 1
0
def test_dice():
    # TODO: Make iid method!
    X, Y, Z = Die('X', 6), Die('Y', 6), Die('Z', 6)
    a, b, t, p = symbols('a b t p')

    assert E(X) == 3 + S.Half
    assert variance(X) == Rational(35, 12)
    assert E(X + Y) == 7
    assert E(X + X) == 7
    assert E(a * X + b) == a * E(X) + b
    assert variance(X + Y) == variance(X) + variance(Y) == cmoment(X + Y, 2)
    assert variance(X + X) == 4 * variance(X) == cmoment(X + X, 2)
    assert cmoment(X, 0) == 1
    assert cmoment(4 * X, 3) == 64 * cmoment(X, 3)
    assert covariance(X, Y) is S.Zero
    assert covariance(X, X + Y) == variance(X)
    assert density(Eq(cos(X * S.Pi), 1))[True] == S.Half
    assert correlation(X, Y) == 0
    assert correlation(X, Y) == correlation(Y, X)
    assert smoment(X + Y, 3) == skewness(X + Y)
    assert smoment(X + Y, 4) == kurtosis(X + Y)
    assert smoment(X, 0) == 1
    assert P(X > 3) == S.Half
    assert P(2 * X > 6) == S.Half
    assert P(X > Y) == Rational(5, 12)
    assert P(Eq(X, Y)) == P(Eq(X, 1))

    assert E(X, X > 3) == 5 == moment(X, 1, 0, X > 3)
    assert E(X, Y > 3) == E(X) == moment(X, 1, 0, Y > 3)
    assert E(X + Y, Eq(X, Y)) == E(2 * X)
    assert moment(X, 0) == 1
    assert moment(5 * X, 2) == 25 * moment(X, 2)
    assert quantile(X)(p) == Piecewise((nan, (p > 1) | (p < 0)),\
        (S.One, p <= Rational(1, 6)), (S(2), p <= Rational(1, 3)), (S(3), p <= S.Half),\
        (S(4), p <= Rational(2, 3)), (S(5), p <= Rational(5, 6)), (S(6), p <= 1))

    assert P(X > 3, X > 3) is S.One
    assert P(X > Y, Eq(Y, 6)) is S.Zero
    assert P(Eq(X + Y, 12)) == Rational(1, 36)
    assert P(Eq(X + Y, 12), Eq(X, 6)) == Rational(1, 6)

    assert density(X + Y) == density(Y + Z) != density(X + X)
    d = density(2 * X + Y**Z)
    assert d[S(22)] == Rational(1, 108) and d[S(4100)] == Rational(
        1, 216) and S(3130) not in d

    assert pspace(X).domain.as_boolean() == Or(
        *[Eq(X.symbol, i) for i in [1, 2, 3, 4, 5, 6]])

    assert where(X > 3).set == FiniteSet(4, 5, 6)

    assert characteristic_function(X)(t) == exp(6 * I * t) / 6 + exp(
        5 * I * t) / 6 + exp(4 * I * t) / 6 + exp(3 * I * t) / 6 + exp(
            2 * I * t) / 6 + exp(I * t) / 6
    assert moment_generating_function(X)(
        t) == exp(6 * t) / 6 + exp(5 * t) / 6 + exp(4 * t) / 6 + exp(
            3 * t) / 6 + exp(2 * t) / 6 + exp(t) / 6
    assert median(X) == FiniteSet(3, 4)
    D = Die('D', 7)
    assert median(D) == FiniteSet(4)
    # Bayes test for die
    BayesTest(X > 3, X + Y < 5)
    BayesTest(Eq(X - Y, Z), Z > Y)
    BayesTest(X > 3, X > 2)

    # arg test for die
    raises(ValueError, lambda: Die('X', -1))  # issue 8105: negative sides.
    raises(ValueError, lambda: Die('X', 0))
    raises(ValueError, lambda: Die('X', 1.5))  # issue 8103: non integer sides.

    # symbolic test for die
    n, k = symbols('n, k', positive=True)
    D = Die('D', n)
    dens = density(D).dict
    assert dens == Density(DieDistribution(n))
    assert set(dens.subs(n, 4).doit().keys()) == {1, 2, 3, 4}
    assert set(dens.subs(n, 4).doit().values()) == {Rational(1, 4)}
    k = Dummy('k', integer=True)
    assert E(D).dummy_eq(Sum(Piecewise((k / n, k <= n), (0, True)), (k, 1, n)))
    assert variance(D).subs(n, 6).doit() == Rational(35, 12)

    ki = Dummy('ki')
    cumuf = cdf(D)(k)
    assert cumuf.dummy_eq(
        Sum(Piecewise((1 / n, (ki >= 1) & (ki <= n)), (0, True)), (ki, 1, k)))
    assert cumuf.subs({n: 6, k: 2}).doit() == Rational(1, 3)

    t = Dummy('t')
    cf = characteristic_function(D)(t)
    assert cf.dummy_eq(
        Sum(Piecewise((exp(ki * I * t) / n, (ki >= 1) & (ki <= n)), (0, True)),
            (ki, 1, n)))
    assert cf.subs(
        n,
        3).doit() == exp(3 * I * t) / 3 + exp(2 * I * t) / 3 + exp(I * t) / 3
    mgf = moment_generating_function(D)(t)
    assert mgf.dummy_eq(
        Sum(Piecewise((exp(ki * t) / n, (ki >= 1) & (ki <= n)), (0, True)),
            (ki, 1, n)))
    assert mgf.subs(n,
                    3).doit() == exp(3 * t) / 3 + exp(2 * t) / 3 + exp(t) / 3
Ejemplo n.º 2
0
def test_fcode_Logical():
    # unary Not
    assert fcode(Not(x)) == ".not. x"
    # binary And
    assert fcode(And(x, y)) == "x .and. y"
    assert fcode(And(x, Not(y))) == "x .and. .not. y"
    assert fcode(And(Not(x), y)) == "y .and. .not. x"
    assert fcode(And(Not(x), Not(y))) == ".not. x .and. .not. y"
    assert fcode(Not(And(x, y), evaluate=False)) == ".not. (x .and. y)"
    # binary Or
    assert fcode(Or(x, y)) == "x .or. y"
    assert fcode(Or(x, Not(y))) == "x .or. .not. y"
    assert fcode(Or(Not(x), y)) == "y .or. .not. x"
    assert fcode(Or(Not(x), Not(y))) == ".not. x .or. .not. y"
    assert fcode(Not(Or(x, y), evaluate=False)) == ".not. (x .or. y)"
    # mixed And/Or
    assert fcode(And(Or(y, z), x)) == "x .and. (y .or. z)"
    assert fcode(And(Or(z, x), y)) == "y .and. (x .or. z)"
    assert fcode(And(Or(x, y), z)) == "z .and. (x .or. y)"
    assert fcode(Or(And(y, z), x)) == "x .or. y .and. z"
    assert fcode(Or(And(z, x), y)) == "y .or. x .and. z"
    assert fcode(Or(And(x, y), z)) == "z .or. x .and. y"
    # trinary And
    assert fcode(And(x, y, z)) == "x .and. y .and. z"
    assert fcode(And(x, y, Not(z))) == "x .and. y .and. .not. z"
    assert fcode(And(x, Not(y), z)) == "x .and. z .and. .not. y"
    assert fcode(And(Not(x), y, z)) == "y .and. z .and. .not. x"
    assert fcode(Not(And(x, y, z),
                     evaluate=False)) == ".not. (x .and. y .and. z)"
    # trinary Or
    assert fcode(Or(x, y, z)) == "x .or. y .or. z"
    assert fcode(Or(x, y, Not(z))) == "x .or. y .or. .not. z"
    assert fcode(Or(x, Not(y), z)) == "x .or. z .or. .not. y"
    assert fcode(Or(Not(x), y, z)) == "y .or. z .or. .not. x"
    assert fcode(Not(Or(x, y, z), evaluate=False)) == ".not. (x .or. y .or. z)"
Ejemplo n.º 3
0
def test_fcode_precedence():
    assert fcode(And(x < y, y < x + 1)) == "x < y .and. y < x + 1"
    assert fcode(Or(x < y, y < x + 1)) == "x < y .or. y < x + 1"
    assert fcode(Xor(x < y, y < x + 1,
                     evaluate=False)) == "x < y .neqv. y < x + 1"
    assert fcode(Equivalent(x < y, y < x + 1)) == "x < y .eqv. y < x + 1"
Ejemplo n.º 4
0
def test_fcode_Logical():
    x, y, z = symbols("x y z")
    # unary Not
    assert fcode(Not(x), source_format="free") == ".not. x"
    # binary And
    assert fcode(And(x, y), source_format="free") == "x .and. y"
    assert fcode(And(x, Not(y)), source_format="free") == "x .and. .not. y"
    assert fcode(And(Not(x), y), source_format="free") == "y .and. .not. x"
    assert fcode(And(Not(x), Not(y)), source_format="free") == \
        ".not. x .and. .not. y"
    assert fcode(Not(And(x, y), evaluate=False), source_format="free") == \
        ".not. (x .and. y)"
    # binary Or
    assert fcode(Or(x, y), source_format="free") == "x .or. y"
    assert fcode(Or(x, Not(y)), source_format="free") == "x .or. .not. y"
    assert fcode(Or(Not(x), y), source_format="free") == "y .or. .not. x"
    assert fcode(Or(Not(x), Not(y)), source_format="free") == \
        ".not. x .or. .not. y"
    assert fcode(Not(Or(x, y), evaluate=False), source_format="free") == \
        ".not. (x .or. y)"
    # mixed And/Or
    assert fcode(And(Or(y, z), x),
                 source_format="free") == "x .and. (y .or. z)"
    assert fcode(And(Or(z, x), y),
                 source_format="free") == "y .and. (x .or. z)"
    assert fcode(And(Or(x, y), z),
                 source_format="free") == "z .and. (x .or. y)"
    assert fcode(Or(And(y, z), x), source_format="free") == "x .or. y .and. z"
    assert fcode(Or(And(z, x), y), source_format="free") == "y .or. x .and. z"
    assert fcode(Or(And(x, y), z), source_format="free") == "z .or. x .and. y"
    # trinary And
    assert fcode(And(x, y, z), source_format="free") == "x .and. y .and. z"
    assert fcode(And(x, y, Not(z)), source_format="free") == \
        "x .and. y .and. .not. z"
    assert fcode(And(x, Not(y), z), source_format="free") == \
        "x .and. z .and. .not. y"
    assert fcode(And(Not(x), y, z), source_format="free") == \
        "y .and. z .and. .not. x"
    assert fcode(Not(And(x, y, z), evaluate=False), source_format="free") == \
        ".not. (x .and. y .and. z)"
    # trinary Or
    assert fcode(Or(x, y, z), source_format="free") == "x .or. y .or. z"
    assert fcode(Or(x, y, Not(z)), source_format="free") == \
        "x .or. y .or. .not. z"
    assert fcode(Or(x, Not(y), z), source_format="free") == \
        "x .or. z .or. .not. y"
    assert fcode(Or(Not(x), y, z), source_format="free") == \
        "y .or. z .or. .not. x"
    assert fcode(Not(Or(x, y, z), evaluate=False), source_format="free") == \
        ".not. (x .or. y .or. z)"
Ejemplo n.º 5
0
 def _handle_irel(self, x, handler):
     """Return either None (if the conditions of self depend only on x) else
     a Piecewise expression whose expressions (handled by the handler that
     was passed) are paired with the governing x-independent relationals,
     e.g. Piecewise((A, a(x) & b(y)), (B, c(x) | c(y)) ->
     Piecewise(
         (handler(Piecewise((A, a(x) & True), (B, c(x) | True)), b(y) & c(y)),
         (handler(Piecewise((A, a(x) & True), (B, c(x) | False)), b(y)),
         (handler(Piecewise((A, a(x) & False), (B, c(x) | True)), c(y)),
         (handler(Piecewise((A, a(x) & False), (B, c(x) | False)), True))
     """
     # identify governing relationals
     rel = self.atoms(Relational)
     irel = list(
         ordered([
             r for r in rel
             if x not in r.free_symbols and r not in (S.true, S.false)
         ]))
     if irel:
         args = {}
         exprinorder = []
         for truth in product((1, 0), repeat=len(irel)):
             reps = dict(zip(irel, truth))
             # only store the true conditions since the false are implied
             # when they appear lower in the Piecewise args
             if 1 not in truth:
                 cond = None  # flag this one so it doesn't get combined
             else:
                 andargs = Tuple(*[i for i in reps if reps[i]])
                 free = list(andargs.free_symbols)
                 if len(free) == 1:
                     from sympy.solvers.inequalities import (
                         reduce_inequalities, _solve_inequality)
                     try:
                         t = reduce_inequalities(andargs, free[0])
                         # ValueError when there are potentially
                         # nonvanishing imaginary parts
                     except (ValueError, NotImplementedError):
                         # at least isolate free symbol on left
                         t = And(*[
                             _solve_inequality(a, free[0], linear=True)
                             for a in andargs
                         ])
                 else:
                     t = And(*andargs)
                 if t is S.false:
                     continue  # an impossible combination
                 cond = t
             expr = handler(self.xreplace(reps))
             if isinstance(expr, self.func) and len(expr.args) == 1:
                 expr, econd = expr.args[0]
                 cond = And(econd, True if cond is None else cond)
             # the ec pairs are being collected since all possibilities
             # are being enumerated, but don't put the last one in since
             # its expr might match a previous expression and it
             # must appear last in the args
             if cond is not None:
                 args.setdefault(expr, []).append(cond)
                 # but since we only store the true conditions we must maintain
                 # the order so that the expression with the most true values
                 # comes first
                 exprinorder.append(expr)
         # convert collected conditions as args of Or
         for k in args:
             args[k] = Or(*args[k])
         # take them in the order obtained
         args = [(e, args[e]) for e in uniq(exprinorder)]
         # add in the last arg
         args.append((expr, True))
         # if any condition reduced to True, it needs to go last
         # and there should only be one of them or else the exprs
         # should agree
         trues = [i for i in range(len(args)) if args[i][1] is S.true]
         if not trues:
             # make the last one True since all cases were enumerated
             e, c = args[-1]
             args[-1] = (e, S.true)
         else:
             assert len(set([e for e, c in [args[i] for i in trues]])) == 1
             args.append(args.pop(trues.pop()))
             while trues:
                 args.pop(trues.pop())
         return Piecewise(*args)
Ejemplo n.º 6
0
def test_true_false():
    assert true is S.true
    assert false is S.false
    assert true is not True
    assert false is not False
    assert true
    assert not false
    assert true == True
    assert false == False
    assert not (true == False)
    assert not (false == True)
    assert not (true == false)

    assert hash(true) == hash(True)
    assert hash(false) == hash(False)
    assert len({true, True}) == len({false, False}) == 1

    assert isinstance(true, BooleanAtom)
    assert isinstance(false, BooleanAtom)
    # We don't want to subclass from bool, because bool subclasses from
    # int. But operators like &, |, ^, <<, >>, and ~ act differently on 0 and
    # 1 then we want them to on true and false.  See the docstrings of the
    # various And, Or, etc. functions for examples.
    assert not isinstance(true, bool)
    assert not isinstance(false, bool)

    # Note: using 'is' comparison is important here. We want these to return
    # true and false, not True and False

    assert Not(true) is false
    assert Not(True) is false
    assert Not(false) is true
    assert Not(False) is true
    assert ~true is false
    assert ~false is true

    for T, F in cartes([True, true], [False, false]):
        assert And(T, F) is false
        assert And(F, T) is false
        assert And(F, F) is false
        assert And(T, T) is true
        assert And(T, x) == x
        assert And(F, x) is false
        if not (T is True and F is False):
            assert T & F is false
            assert F & T is false
        if not F is False:
            assert F & F is false
        if not T is True:
            assert T & T is true

        assert Or(T, F) is true
        assert Or(F, T) is true
        assert Or(F, F) is false
        assert Or(T, T) is true
        assert Or(T, x) is true
        assert Or(F, x) == x
        if not (T is True and F is False):
            assert T | F is true
            assert F | T is true
        if not F is False:
            assert F | F is false
        if not T is True:
            assert T | T is true

        assert Xor(T, F) is true
        assert Xor(F, T) is true
        assert Xor(F, F) is false
        assert Xor(T, T) is false
        assert Xor(T, x) == ~x
        assert Xor(F, x) == x
        if not (T is True and F is False):
            assert T ^ F is true
            assert F ^ T is true
        if not F is False:
            assert F ^ F is false
        if not T is True:
            assert T ^ T is false

        assert Nand(T, F) is true
        assert Nand(F, T) is true
        assert Nand(F, F) is true
        assert Nand(T, T) is false
        assert Nand(T, x) == ~x
        assert Nand(F, x) is true

        assert Nor(T, F) is false
        assert Nor(F, T) is false
        assert Nor(F, F) is true
        assert Nor(T, T) is false
        assert Nor(T, x) is false
        assert Nor(F, x) == ~x

        assert Implies(T, F) is false
        assert Implies(F, T) is true
        assert Implies(F, F) is true
        assert Implies(T, T) is true
        assert Implies(T, x) == x
        assert Implies(F, x) is true
        assert Implies(x, T) is true
        assert Implies(x, F) == ~x
        if not (T is True and F is False):
            assert T >> F is false
            assert F << T is false
            assert F >> T is true
            assert T << F is true
        if not F is False:
            assert F >> F is true
            assert F << F is true
        if not T is True:
            assert T >> T is true
            assert T << T is true

        assert Equivalent(T, F) is false
        assert Equivalent(F, T) is false
        assert Equivalent(F, F) is true
        assert Equivalent(T, T) is true
        assert Equivalent(T, x) == x
        assert Equivalent(F, x) == ~x
        assert Equivalent(x, T) == x
        assert Equivalent(x, F) == ~x

        assert ITE(T, T, T) is true
        assert ITE(T, T, F) is true
        assert ITE(T, F, T) is false
        assert ITE(T, F, F) is false
        assert ITE(F, T, T) is true
        assert ITE(F, T, F) is false
        assert ITE(F, F, T) is true
        assert ITE(F, F, F) is false

    assert all(i.simplify(1, 2) is i for i in (S.true, S.false))
Ejemplo n.º 7
0
def test_multivariate_bool_as_set():
    x, y = symbols('x,y')

    assert And(x >= 0, y >= 0).as_set() == Interval(0, oo) * Interval(0, oo)
    assert Or(x >= 0, y >= 0).as_set() == S.Reals*S.Reals - \
        Interval(-oo, 0, True, True)*Interval(-oo, 0, True, True)
Ejemplo n.º 8
0
 def as_relational(self, symbol):
     """Rewrite a FiniteSet in terms of equalities and logic operators. """
     from sympy.core.relational import Eq
     return Or(*[Eq(symbol, elem) for elem in self])
Ejemplo n.º 9
0
def test_Or():

    assert Or() is false
    assert Or(A) == A
    assert Or(True) is true
    assert Or(False) is false
    assert Or(True, True) is true
    assert Or(True, False) is true
    assert Or(False, False) is false
    assert Or(True, A) is true
    assert Or(False, A) == A
    assert Or(True, False, False) is true
    assert Or(True, False, A) is true
    assert Or(False, False, A) == A
    assert Or(2, A) is true
    assert Or(A < 1, A >= 1) is true
    e = A > 1
    assert Or(e, e.canonical) == e
    g, l, ge, le = A > B, B < A, A >= B, B <= A
    assert Or(g, l, ge, le) == Or(g, ge)
Ejemplo n.º 10
0
 def _contains(self, other):
     or_args = [the_set.contains(other) for the_set in self.args]
     return Or(*or_args)
Ejemplo n.º 11
0
 def as_relational(self, symbol):
     """Rewrite a Union in terms of equalities and logic operators. """
     return Or(*[set.as_relational(symbol) for set in self.args])
Ejemplo n.º 12
0
 def pmf(self):
     k = Dummy('k')
     return Lambda(
         k, Piecewise((S.Half, Or(Eq(k, -1), Eq(k, 1))), (S.Zero, True)))
Ejemplo n.º 13
0
from sympy import *
x, y = symbols('x,y')

print("1.AND 2.OR")
ch = int(input())
while (ch < 3):
    if (ch == 1):
        from sympy.logic.boolalg import Not, And, Or
        from sympy.abc import x, A, B

        expr = input(("Enter a logic expression to perform AND operation"))
        print(And(expr))
    elif (ch == 2):
        from sympy.logic.boolalg import Not, And, Or
        from sympy.abc import x, A, B

        expr = input(("Enter a logic expression to perform OR operation"))
        print(Or(expr))
    else:
        print("1")
Ejemplo n.º 14
0
def heurisch_wrapper(f, x, rewrite=False, hints=None, mappings=None, retries=3,
                     degree_offset=0, unnecessary_permutations=None,
                     _try_heurisch=None):
    """
    A wrapper around the heurisch integration algorithm.

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

    This method takes the result from heurisch and checks for poles in the
    denominator. For each of these poles, the integral is reevaluated, and
    the final integration result is given in terms of a Piecewise.

    Examples
    ========

    >>> from sympy.core import symbols
    >>> from sympy.functions import cos
    >>> from sympy.integrals.heurisch import heurisch, heurisch_wrapper
    >>> n, x = symbols('n x')
    >>> heurisch(cos(n*x), x)
    sin(n*x)/n
    >>> heurisch_wrapper(cos(n*x), x)
    Piecewise((sin(n*x)/n, Ne(n, 0)), (x, True))

    See Also
    ========

    heurisch
    """
    from sympy.solvers.solvers import solve, denoms
    f = sympify(f)
    if x not in f.free_symbols:
        return f*x

    res = heurisch(f, x, rewrite, hints, mappings, retries, degree_offset,
                   unnecessary_permutations, _try_heurisch)
    if not isinstance(res, Basic):
        return res
    # We consider each denominator in the expression, and try to find
    # cases where one or more symbolic denominator might be zero. The
    # conditions for these cases are stored in the list slns.
    slns = []
    for d in denoms(res):
        try:
            slns += solve(d, dict=True, exclude=(x,))
        except NotImplementedError:
            pass
    if not slns:
        return res
    slns = list(uniq(slns))
    # Remove the solutions corresponding to poles in the original expression.
    slns0 = []
    for d in denoms(f):
        try:
            slns0 += solve(d, dict=True, exclude=(x,))
        except NotImplementedError:
            pass
    slns = [s for s in slns if s not in slns0]
    if not slns:
        return res
    if len(slns) > 1:
        eqs = []
        for sub_dict in slns:
            eqs.extend([Eq(key, value) for key, value in sub_dict.items()])
        slns = solve(eqs, dict=True, exclude=(x,)) + slns
    # For each case listed in the list slns, we reevaluate the integral.
    pairs = []
    for sub_dict in slns:
        expr = heurisch(f.subs(sub_dict), x, rewrite, hints, mappings, retries,
                        degree_offset, unnecessary_permutations,
                        _try_heurisch)
        cond = And(*[Eq(key, value) for key, value in sub_dict.items()])
        generic = Or(*[Ne(key, value) for key, value in sub_dict.items()])
        if expr is None:
            expr = integrate(f.subs(sub_dict),x)
        pairs.append((expr, cond))
    # If there is one condition, put the generic case first. Otherwise,
    # doing so may lead to longer Piecewise formulas
    if len(pairs) == 1:
        pairs = [(heurisch(f, x, rewrite, hints, mappings, retries,
                              degree_offset, unnecessary_permutations,
                              _try_heurisch),
                              generic),
                 (pairs[0][0], True)]
    else:
        pairs.append((heurisch(f, x, rewrite, hints, mappings, retries,
                              degree_offset, unnecessary_permutations,
                              _try_heurisch),
                              True))
    return Piecewise(*pairs)
Ejemplo n.º 15
0
def test_eliminate_implications():
    assert eliminate_implications(Implies(A, B, evaluate=False)) == (~A) | B
    assert eliminate_implications(A >> (C >> Not(B))) == Or(
        Or(Not(B), Not(C)), Not(A))
    assert eliminate_implications(Equivalent(A, B, C, D)) == \
        (~A | B) & (~B | C) & (~C | D) & (~D | A)
Ejemplo n.º 16
0
def test_simplification():
    """
    Test working of simplification methods.
    """
    set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]]
    set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]]
    from sympy.abc import w, x, y, z
    assert SOPform('xyz', set1) == Or(And(Not(x), z), And(Not(z), x))
    assert Not(SOPform('xyz', set2)) == And(Or(Not(x), Not(z)), Or(x, z))
    assert POSform('xyz', set1 + set2) is True
    assert SOPform('xyz', set1 + set2) is True
    assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is True

    minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
        [1, 1, 1, 1]]
    dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]]
    assert (
        SOPform('wxyz', minterms, dontcares) ==
        Or(And(Not(w), z), And(y, z)))
    assert POSform('wxyz', minterms, dontcares) == And(Or(Not(w), y), z)

    # test simplification
    ans = And(A, Or(B, C))
    assert simplify_logic('A & (B | C)') == ans
    assert simplify_logic('(A & B) | (A & C)') == ans
    assert simplify_logic(Implies(A, B)) == Or(Not(A), B)
    assert simplify_logic(Equivalent(A, B)) == \
           Or(And(A, B), And(Not(A), Not(B)))
    assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C)
    assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A)
    assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C)
    assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \
           == And(Equality(A, 3), Or(B, C))
    assert simplify_logic(And(A, x**2-x)) == And(A, x*(x-1))
    assert simplify_logic(And(A, x**2-x), simplify=False) == And(A, x**2-x)

    # check input
    ans = SOPform('xy', [[1, 0]])
    assert SOPform([x, y], [[1, 0]]) == ans
    assert POSform(['x', 'y'], [[1, 0]]) == ans

    raises(ValueError, lambda: SOPform('x', [[1]], [[1]]))
    assert SOPform('x', [[1]], [[0]]) is True
    assert SOPform('x', [[0]], [[1]]) is True
    assert SOPform('x', [], []) is False

    raises(ValueError, lambda: POSform('x', [[1]], [[1]]))
    assert POSform('x', [[1]], [[0]]) is True
    assert POSform('x', [[0]], [[1]]) is True
    assert POSform('x', [], []) is False

    #check working of simplify
    assert simplify('(A & B) | (A & C)') == sympify('And(A, Or(B, C))')
    assert simplify(And(x, Not(x))) == False
    assert simplify(Or(x, Not(x))) == True
Ejemplo n.º 17
0
def test_distribute():
    assert distribute_and_over_or(Or(And(A, B), C)) == And(Or(A, C), Or(B, C))
    assert distribute_or_over_and(And(A, Or(B, C))) == Or(And(A, B), And(A, C))
Ejemplo n.º 18
0
def test_eliminate_implications():

    assert eliminate_implications(Implies(A, B, evaluate=False)) == (~A) | B
    assert eliminate_implications(
        A >> (C >> Not(B))) == Or(Or(Not(B), Not(C)), Not(A))
Ejemplo n.º 19
0
def test_Or():
    assert Or() is false
    assert Or(A) == A
    assert Or(True) is true
    assert Or(False) is false
    assert Or(True, True) is true
    assert Or(True, False) is true
    assert Or(False, False) is false
    assert Or(True, A) is true
    assert Or(False, A) == A
    assert Or(True, False, False) is true
    assert Or(True, False, A) is true
    assert Or(False, False, A) == A
    assert Or(1, A) is true
    raises(TypeError, lambda: Or(2, A))
    raises(TypeError, lambda: Or(A < 2, A))
    assert Or(A < 1, A >= 1) is true
    e = A > 1
    assert Or(e, e.canonical) == e
    g, l, ge, le = A > B, B < A, A >= B, B <= A
    assert Or(g, l, ge, le) == Or(g, ge)
Ejemplo n.º 20
0
def test_Or():

    assert Or() is False
    assert Or(A) == A
    assert Or(True) is True
    assert Or(False) is False
    assert Or(True, True ) is True
    assert Or(True, False) is True
    assert Or(False, False) is False
    assert Or(True, A) is True
    assert Or(False, A) == A
    assert Or(True, False, False) is True
    assert Or(True, False, A) is True
    assert Or(False, False, A) == A
    assert Or(2, A) is True
Ejemplo n.º 21
0
def test_issue_8975():
    assert Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)).as_set() == \
        Interval(-oo, -2) + Interval(2, oo)
Ejemplo n.º 22
0
 def apply(self):
     return Or(*[self.pred.rcall(arg) for arg in self.expr.args])
Ejemplo n.º 23
0
    def _sort_expr_cond(self, sym, a, b, targetcond=None):
        """Determine what intervals the expr, cond pairs affect.

        1) If cond is True, then log it as default
        1.1) Currently if cond can't be evaluated, throw NotImplementedError.
        2) For each inequality, if previous cond defines part of the interval
           update the new conds interval.
           -  eg x < 1, x < 3 -> [oo,1],[1,3] instead of [oo,1],[oo,3]
        3) Sort the intervals to make it easier to find correct exprs

        Under normal use, we return the expr,cond pairs in increasing order
        along the real axis corresponding to the symbol sym.  If targetcond
        is given, we return a list of (lowerbound, upperbound) pairs for
        this condition."""
        from sympy.solvers.inequalities import _solve_inequality
        default = None
        int_expr = []
        expr_cond = []
        or_cond = False
        or_intervals = []
        independent_expr_cond = []
        for expr, cond in self.args:
            if isinstance(cond, Or):
                for cond2 in sorted(cond.args, key=default_sort_key):
                    expr_cond.append((expr, cond2))
            else:
                expr_cond.append((expr, cond))
            if cond == True:
                break
        for expr, cond in expr_cond:
            if cond == True:
                independent_expr_cond.append((expr, cond))
                default = self.func(*independent_expr_cond)
                break
            orig_cond = cond
            if sym not in cond.free_symbols:
                independent_expr_cond.append((expr, cond))
                continue
            elif isinstance(cond, Equality):
                continue
            elif isinstance(cond, And):
                lower = S.NegativeInfinity
                upper = S.Infinity
                for cond2 in cond.args:
                    if sym not in [cond2.lts, cond2.gts]:
                        cond2 = _solve_inequality(cond2, sym)
                    if cond2.lts == sym:
                        upper = Min(cond2.gts, upper)
                    elif cond2.gts == sym:
                        lower = Max(cond2.lts, lower)
                    else:
                        raise NotImplementedError(
                            "Unable to handle interval evaluation of expression."
                        )
            else:
                if sym not in [cond.lts, cond.gts]:
                    cond = _solve_inequality(cond, sym)
                lower, upper = cond.lts, cond.gts  # part 1: initialize with givens
                if cond.lts == sym:  # part 1a: expand the side ...
                    lower = S.NegativeInfinity  # e.g. x <= 0 ---> -oo <= 0
                elif cond.gts == sym:  # part 1a: ... that can be expanded
                    upper = S.Infinity  # e.g. x >= 0 --->  oo >= 0
                else:
                    raise NotImplementedError(
                        "Unable to handle interval evaluation of expression.")

            # part 1b: Reduce (-)infinity to what was passed in.
            lower, upper = Max(a, lower), Min(b, upper)

            for n in range(len(int_expr)):
                # Part 2: remove any interval overlap.  For any conflicts, the
                # iterval already there wins, and the incoming interval updates
                # its bounds accordingly.
                if self.__eval_cond(lower < int_expr[n][1]) and \
                        self.__eval_cond(lower >= int_expr[n][0]):
                    lower = int_expr[n][1]
                elif len(int_expr[n][1].free_symbols) and \
                        self.__eval_cond(lower >= int_expr[n][0]):
                    if self.__eval_cond(lower == int_expr[n][0]):
                        lower = int_expr[n][1]
                    else:
                        int_expr[n][1] = Min(lower, int_expr[n][1])
                elif len(int_expr[n][0].free_symbols) and \
                        self.__eval_cond(upper == int_expr[n][1]):
                    upper = Min(upper, int_expr[n][0])
                elif len(int_expr[n][1].free_symbols) and \
                        (lower >= int_expr[n][0]) != True and \
                        (int_expr[n][1] == Min(lower, upper)) != True:
                    upper = Min(upper, int_expr[n][0])
                elif self.__eval_cond(upper > int_expr[n][0]) and \
                        self.__eval_cond(upper <= int_expr[n][1]):
                    upper = int_expr[n][0]
                elif len(int_expr[n][0].free_symbols) and \
                        self.__eval_cond(upper < int_expr[n][1]):
                    int_expr[n][0] = Max(upper, int_expr[n][0])

            if self.__eval_cond(
                    lower >= upper) != True:  # Is it still an interval?
                int_expr.append([lower, upper, expr])
            if orig_cond == targetcond:
                return [(lower, upper, None)]
            elif isinstance(targetcond, Or) and cond in targetcond.args:
                or_cond = Or(or_cond, cond)
                or_intervals.append((lower, upper, None))
                if or_cond == targetcond:
                    or_intervals.sort(key=lambda x: x[0])
                    return or_intervals

        int_expr.sort(key=lambda x: x[1].sort_key()
                      if x[1].is_number else S.NegativeInfinity.sort_key())
        int_expr.sort(key=lambda x: x[0].sort_key()
                      if x[0].is_number else S.Infinity.sort_key())

        for n in range(len(int_expr)):
            if len(int_expr[n][0].free_symbols) or len(
                    int_expr[n][1].free_symbols):
                if isinstance(int_expr[n][1], Min) or int_expr[n][1] == b:
                    newval = Min(*int_expr[n][:-1])
                    if n > 0 and int_expr[n][0] == int_expr[n - 1][1]:
                        int_expr[n - 1][1] = newval
                    int_expr[n][0] = newval
                else:
                    newval = Max(*int_expr[n][:-1])
                    if n < len(int_expr) - 1 and int_expr[n][1] == int_expr[
                            n + 1][0]:
                        int_expr[n + 1][0] = newval
                    int_expr[n][1] = newval

        # Add holes to list of intervals if there is a default value,
        # otherwise raise a ValueError.
        holes = []
        curr_low = a
        for int_a, int_b, expr in int_expr:
            if (curr_low < int_a) == True:
                holes.append([curr_low, Min(b, int_a), default])
            elif (curr_low >= int_a) != True:
                holes.append([curr_low, Min(b, int_a), default])
            curr_low = Min(b, int_b)
        if (curr_low < b) == True:
            holes.append([Min(b, curr_low), b, default])
        elif (curr_low >= b) != True:
            holes.append([Min(b, curr_low), b, default])

        if holes and default is not None:
            int_expr.extend(holes)
            if targetcond == True:
                return [(h[0], h[1], None) for h in holes]
        elif holes and default is None:
            raise ValueError("Called interval evaluation over piecewise "
                             "function on undefined intervals %s" %
                             ", ".join([str((h[0], h[1])) for h in holes]))

        return int_expr
Ejemplo n.º 24
0
def test_Or():
    X = Geometric('X', S.Half)
    P(Or(X < 3, X > 4)) == Rational(13, 16)
    P(Or(X > 2, X > 1)) == P(X > 1)
    P(Or(X >= 3, X < 3)) == 1
Ejemplo n.º 25
0
def real_root(arg, n=None, evaluate=None):
    """Return the real *n*'th-root of *arg* if possible.

    Parameters
    ==========

    n : int or None, optional
        If *n* is ``None``, then all instances of
        ``(-n)**(1/odd)`` will be changed to ``-n**(1/odd)``.
        This will only create a real root of a principal root.
        The presence of other factors may cause the result to not be
        real.

    evaluate : bool, optional
        The parameter determines if the expression should be evaluated.
        If ``None``, its value is taken from
        ``global_parameters.evaluate``.

    Examples
    ========

    >>> from sympy import root, real_root, Rational
    >>> from sympy.abc import x, n

    >>> real_root(-8, 3)
    -2
    >>> root(-8, 3)
    2*(-1)**(1/3)
    >>> real_root(_)
    -2

    If one creates a non-principal root and applies real_root, the
    result will not be real (so use with caution):

    >>> root(-8, 3, 2)
    -2*(-1)**(2/3)
    >>> real_root(_)
    -2*(-1)**(2/3)

    See Also
    ========

    sympy.polys.rootoftools.rootof
    sympy.core.power.integer_nthroot
    root, sqrt
    """
    from sympy.functions.elementary.complexes import Abs, im, sign
    from sympy.functions.elementary.piecewise import Piecewise

    if n is not None:
        return Piecewise(
            (root(arg, n, evaluate=evaluate), Or(Eq(n, S.One), Eq(n, S.NegativeOne))),
            (
                Mul(sign(arg), root(Abs(arg), n, evaluate=evaluate), evaluate=evaluate),
                And(Eq(im(arg), S.Zero), Eq(Mod(n, 2), S.One)),
            ),
            (root(arg, n, evaluate=evaluate), True),
        )
    rv = sympify(arg)
    n1pow = Transform(
        lambda x: -((-x.base) ** x.exp),
        lambda x: x.is_Pow
        and x.base.is_negative
        and x.exp.is_Rational
        and x.exp.p == 1
        and x.exp.q % 2,
    )
    return rv.xreplace(n1pow)
Ejemplo n.º 26
0
def test_equals():
    assert Not(Or(A, B)).equals(And(Not(A), Not(B))) is True
    assert Equivalent(A, B).equals((A >> B) & (B >> A)) is True
    assert ((A | ~B) & (~A | B)).equals((~A & ~B) | (A & B)) is True
    assert (A >> B).equals(~A >> ~B) is False
    assert (A >> (B >> A)).equals(A >> (C >> A)) is False
Ejemplo n.º 27
0
def test_fcode_Xlogical():
    x, y, z = symbols("x y z")
    # binary Xor
    assert fcode(Xor(x, y, evaluate=False)) == "x .neqv. y"
    assert fcode(Xor(x, Not(y), evaluate=False)) == "x .neqv. .not. y"
    assert fcode(Xor(Not(x), y, evaluate=False)) == "y .neqv. .not. x"
    assert fcode(Xor(Not(x), Not(y),
                     evaluate=False)) == ".not. x .neqv. .not. y"
    assert fcode(Not(Xor(x, y, evaluate=False),
                     evaluate=False)) == ".not. (x .neqv. y)"
    # binary Equivalent
    assert fcode(Equivalent(x, y)) == "x .eqv. y"
    assert fcode(Equivalent(x, Not(y))) == "x .eqv. .not. y"
    assert fcode(Equivalent(Not(x), y)) == "y .eqv. .not. x"
    assert fcode(Equivalent(Not(x), Not(y))) == ".not. x .eqv. .not. y"
    assert fcode(Not(Equivalent(x, y), evaluate=False)) == ".not. (x .eqv. y)"
    # mixed And/Equivalent
    assert fcode(Equivalent(And(y, z), x)) == "x .eqv. y .and. z"
    assert fcode(Equivalent(And(z, x), y)) == "y .eqv. x .and. z"
    assert fcode(Equivalent(And(x, y), z)) == "z .eqv. x .and. y"
    assert fcode(And(Equivalent(y, z), x)) == "x .and. (y .eqv. z)"
    assert fcode(And(Equivalent(z, x), y)) == "y .and. (x .eqv. z)"
    assert fcode(And(Equivalent(x, y), z)) == "z .and. (x .eqv. y)"
    # mixed Or/Equivalent
    assert fcode(Equivalent(Or(y, z), x)) == "x .eqv. y .or. z"
    assert fcode(Equivalent(Or(z, x), y)) == "y .eqv. x .or. z"
    assert fcode(Equivalent(Or(x, y), z)) == "z .eqv. x .or. y"
    assert fcode(Or(Equivalent(y, z), x)) == "x .or. (y .eqv. z)"
    assert fcode(Or(Equivalent(z, x), y)) == "y .or. (x .eqv. z)"
    assert fcode(Or(Equivalent(x, y), z)) == "z .or. (x .eqv. y)"
    # mixed Xor/Equivalent
    assert fcode(Equivalent(Xor(y, z, evaluate=False),
                            x)) == "x .eqv. (y .neqv. z)"
    assert fcode(Equivalent(Xor(z, x, evaluate=False),
                            y)) == "y .eqv. (x .neqv. z)"
    assert fcode(Equivalent(Xor(x, y, evaluate=False),
                            z)) == "z .eqv. (x .neqv. y)"
    assert fcode(Xor(Equivalent(y, z), x,
                     evaluate=False)) == "x .neqv. (y .eqv. z)"
    assert fcode(Xor(Equivalent(z, x), y,
                     evaluate=False)) == "y .neqv. (x .eqv. z)"
    assert fcode(Xor(Equivalent(x, y), z,
                     evaluate=False)) == "z .neqv. (x .eqv. y)"
    # mixed And/Xor
    assert fcode(Xor(And(y, z), x, evaluate=False)) == "x .neqv. y .and. z"
    assert fcode(Xor(And(z, x), y, evaluate=False)) == "y .neqv. x .and. z"
    assert fcode(Xor(And(x, y), z, evaluate=False)) == "z .neqv. x .and. y"
    assert fcode(And(Xor(y, z, evaluate=False), x)) == "x .and. (y .neqv. z)"
    assert fcode(And(Xor(z, x, evaluate=False), y)) == "y .and. (x .neqv. z)"
    assert fcode(And(Xor(x, y, evaluate=False), z)) == "z .and. (x .neqv. y)"
    # mixed Or/Xor
    assert fcode(Xor(Or(y, z), x, evaluate=False)) == "x .neqv. y .or. z"
    assert fcode(Xor(Or(z, x), y, evaluate=False)) == "y .neqv. x .or. z"
    assert fcode(Xor(Or(x, y), z, evaluate=False)) == "z .neqv. x .or. y"
    assert fcode(Or(Xor(y, z, evaluate=False), x)) == "x .or. (y .neqv. z)"
    assert fcode(Or(Xor(z, x, evaluate=False), y)) == "y .or. (x .neqv. z)"
    assert fcode(Or(Xor(x, y, evaluate=False), z)) == "z .or. (x .neqv. y)"
    # ternary Xor
    assert fcode(Xor(x, y, z, evaluate=False)) == "x .neqv. y .neqv. z"
    assert fcode(Xor(x, y, Not(z),
                     evaluate=False)) == "x .neqv. y .neqv. .not. z"
    assert fcode(Xor(x, Not(y), z,
                     evaluate=False)) == "x .neqv. z .neqv. .not. y"
    assert fcode(Xor(Not(x), y, z,
                     evaluate=False)) == "y .neqv. z .neqv. .not. x"
Ejemplo n.º 28
0
def test_simplification():
    """
    Test working of simplification methods.
    """
    set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]]
    set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]]
    assert SOPform([x, y, z], set1) == Or(And(Not(x), z), And(Not(z), x))
    assert Not(SOPform([x, y, z],
                       set2)) == Not(Or(And(Not(x), Not(z)), And(x, z)))
    assert POSform([x, y, z], set1 + set2) is true
    assert SOPform([x, y, z], set1 + set2) is true
    assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is true

    minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
                [1, 1, 1, 1]]
    dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]]
    assert (SOPform([w, x, y, z], minterms,
                    dontcares) == Or(And(Not(w), z), And(y, z)))
    assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)

    # test simplification
    ans = And(A, Or(B, C))
    assert simplify_logic(A & (B | C)) == ans
    assert simplify_logic((A & B) | (A & C)) == ans
    assert simplify_logic(Implies(A, B)) == Or(Not(A), B)
    assert simplify_logic(Equivalent(A, B)) == \
           Or(And(A, B), And(Not(A), Not(B)))
    assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C)
    assert simplify_logic(And(Equality(A, 2), A)) is S.false
    assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A)
    assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C)
    assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \
           == And(Equality(A, 3), Or(B, C))
    b = (~x & ~y & ~z) | (~x & ~y & z)
    e = And(A, b)
    assert simplify_logic(e) == A & ~x & ~y

    # check input
    ans = SOPform([x, y], [[1, 0]])
    assert SOPform([x, y], [[1, 0]]) == ans
    assert POSform([x, y], [[1, 0]]) == ans

    raises(ValueError, lambda: SOPform([x], [[1]], [[1]]))
    assert SOPform([x], [[1]], [[0]]) is true
    assert SOPform([x], [[0]], [[1]]) is true
    assert SOPform([x], [], []) is false

    raises(ValueError, lambda: POSform([x], [[1]], [[1]]))
    assert POSform([x], [[1]], [[0]]) is true
    assert POSform([x], [[0]], [[1]]) is true
    assert POSform([x], [], []) is false

    # check working of simplify
    assert simplify((A & B) | (A & C)) == And(A, Or(B, C))
    assert simplify(And(x, Not(x))) == False
    assert simplify(Or(x, Not(x))) == True
Ejemplo n.º 29
0
    def eval(cls, *_args):
        """Either return a modified version of the args or, if no
        modifications were made, return None.

        Modifications that are made here:
        1) relationals are made canonical
        2) any False conditions are dropped
        3) any repeat of a previous condition is ignored
        3) any args past one with a true condition are dropped

        If there are no args left, nan will be returned.
        If there is a single arg with a True condition, its
        corresponding expression will be returned.
        """
        from sympy.functions.elementary.complexes import im, re

        if not _args:
            return Undefined

        if len(_args) == 1 and _args[0][-1] == True:
            return _args[0][0]

        newargs = []  # the unevaluated conditions
        current_cond = set()  # the conditions up to a given e, c pair
        # make conditions canonical
        args = []
        for e, c in _args:
            if (not c.is_Atom and not isinstance(c, Relational)
                    and not c.has(im, re)):
                free = c.free_symbols
                if len(free) == 1:
                    funcs = [
                        i for i in c.atoms(Function)
                        if not isinstance(i, Boolean)
                    ]
                    if len(funcs) == 1 and len(
                            c.xreplace({
                                list(funcs)[0]: Dummy()
                            }).free_symbols) == 1:
                        # we can treat function like a symbol
                        free = funcs
                    _c = c
                    x = free.pop()
                    try:
                        c = c.as_set().as_relational(x)
                    except NotImplementedError:
                        pass
                    else:
                        reps = {}
                        for i in c.atoms(Relational):
                            ic = i.canonical
                            if ic.rhs in (S.Infinity, S.NegativeInfinity):
                                if not _c.has(ic.rhs):
                                    # don't accept introduction of
                                    # new Relationals with +/-oo
                                    reps[i] = S.true
                                elif ('=' not in ic.rel_op and c.xreplace(
                                    {x: i.rhs}) != _c.xreplace({x: i.rhs})):
                                    reps[i] = Relational(
                                        i.lhs, i.rhs, i.rel_op + '=')
                        c = c.xreplace(reps)
            args.append((e, _canonical(c)))

        for expr, cond in args:
            # Check here if expr is a Piecewise and collapse if one of
            # the conds in expr matches cond. This allows the collapsing
            # of Piecewise((Piecewise((x,x<0)),x<0)) to Piecewise((x,x<0)).
            # This is important when using piecewise_fold to simplify
            # multiple Piecewise instances having the same conds.
            # Eventually, this code should be able to collapse Piecewise's
            # having different intervals, but this will probably require
            # using the new assumptions.
            if isinstance(expr, Piecewise):
                unmatching = []
                for i, (e, c) in enumerate(expr.args):
                    if c in current_cond:
                        # this would already have triggered
                        continue
                    if c == cond:
                        if c != True:
                            # nothing past this condition will ever
                            # trigger and only those args before this
                            # that didn't match a previous condition
                            # could possibly trigger
                            if unmatching:
                                expr = Piecewise(*(unmatching + [(e, c)]))
                            else:
                                expr = e
                        break
                    else:
                        unmatching.append((e, c))

            # check for condition repeats
            got = False
            # -- if an And contains a condition that was
            #    already encountered, then the And will be
            #    False: if the previous condition was False
            #    then the And will be False and if the previous
            #    condition is True then then we wouldn't get to
            #    this point. In either case, we can skip this condition.
            for i in ([cond] +
                      (list(cond.args) if isinstance(cond, And) else [])):
                if i in current_cond:
                    got = True
                    break
            if got:
                continue

            # -- if not(c) is already in current_cond then c is
            #    a redundant condition in an And. This does not
            #    apply to Or, however: (e1, c), (e2, Or(~c, d))
            #    is not (e1, c), (e2, d) because if c and d are
            #    both False this would give no results when the
            #    true answer should be (e2, True)
            if isinstance(cond, And):
                nonredundant = []
                for c in cond.args:
                    if (isinstance(c, Relational)
                            and c.negated.canonical in current_cond):
                        continue
                    nonredundant.append(c)
                cond = cond.func(*nonredundant)
            elif isinstance(cond, Relational):
                if cond.negated.canonical in current_cond:
                    cond = S.true

            current_cond.add(cond)

            # collect successive e,c pairs when exprs or cond match
            if newargs:
                if newargs[-1].expr == expr:
                    orcond = Or(cond, newargs[-1].cond)
                    if isinstance(orcond, (And, Or)):
                        orcond = distribute_and_over_or(orcond)
                    newargs[-1] = ExprCondPair(expr, orcond)
                    continue
                elif newargs[-1].cond == cond:
                    newargs[-1] = ExprCondPair(expr, cond)
                    continue

            newargs.append(ExprCondPair(expr, cond))

        # some conditions may have been redundant
        missing = len(newargs) != len(_args)
        # some conditions may have changed
        same = all(a == b for a, b in zip(newargs, _args))
        # if either change happened we return the expr with the
        # updated args
        if not newargs:
            raise ValueError(
                filldedent('''
                There are no conditions (or none that
                are not trivially false) to define an
                expression.'''))
        if missing or not same:
            return cls(*newargs)
Ejemplo n.º 30
0
def test_Or():
    X = Geometric('X', S(1) / 2)
    P(Or(X < 3, X > 4)) == S(13) / 16
    P(Or(X > 2, X > 1)) == P(X > 1)
    P(Or(X >= 3, X < 3)) == 1