12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340 |
- from sympy.assumptions.ask import Q
- from sympy.assumptions.refine import refine
- from sympy.core.numbers import oo
- from sympy.core.relational import Equality, Eq, Ne
- from sympy.core.singleton import S
- from sympy.core.symbol import (Dummy, symbols)
- from sympy.functions import Piecewise
- from sympy.functions.elementary.trigonometric import cos, sin
- from sympy.sets.sets import (Interval, Union)
- from sympy.simplify.simplify import simplify
- from sympy.logic.boolalg import (
- And, Boolean, Equivalent, ITE, Implies, Nand, Nor, Not, Or,
- POSform, SOPform, Xor, Xnor, conjuncts, disjuncts,
- distribute_or_over_and, distribute_and_over_or,
- eliminate_implications, is_nnf, is_cnf, is_dnf, simplify_logic,
- to_nnf, to_cnf, to_dnf, to_int_repr, bool_map, true, false,
- BooleanAtom, is_literal, term_to_integer,
- truth_table, as_Boolean, to_anf, is_anf, distribute_xor_over_and,
- anf_coeffs, ANFform, bool_minterm, bool_maxterm, bool_monomial,
- _check_pair, _convert_to_varsSOP, _convert_to_varsPOS, Exclusive,
- gateinputcount)
- from sympy.assumptions.cnf import CNF
- from sympy.testing.pytest import raises, XFAIL, slow
- from itertools import combinations, permutations, product
- A, B, C, D = symbols('A:D')
- a, b, c, d, e, w, x, y, z = symbols('a:e w:z')
- def test_overloading():
- """Test that |, & are overloaded as expected"""
- assert A & B == And(A, B)
- assert A | B == Or(A, B)
- assert (A & B) | C == Or(And(A, B), C)
- assert A >> B == Implies(A, B)
- assert A << B == Implies(B, A)
- assert ~A == Not(A)
- assert A ^ B == Xor(A, B)
- def test_And():
- assert And() is true
- assert And(A) == A
- assert And(True) is true
- assert And(False) is false
- assert And(True, True) is true
- assert And(True, False) is false
- assert And(False, False) is false
- assert And(True, A) == A
- assert And(False, A) is false
- assert And(True, True, True) is true
- assert And(True, True, A) == A
- assert And(True, False, A) is false
- assert And(1, A) == A
- raises(TypeError, lambda: And(2, A))
- raises(TypeError, lambda: And(A < 2, A))
- assert And(A < 1, A >= 1) is false
- e = A > 1
- assert And(e, e.canonical) == e.canonical
- g, l, ge, le = A > B, B < A, A >= B, B <= A
- assert And(g, l, ge, le) == And(ge, g)
- assert {And(*i) for i in permutations((l,g,le,ge))} == {And(ge, g)}
- assert And(And(Eq(a, 0), Eq(b, 0)), And(Ne(a, 0), Eq(c, 0))) is false
- 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)
- def test_Xor():
- assert Xor() is false
- assert Xor(A) == A
- assert Xor(A, A) is false
- assert Xor(True, A, A) is true
- assert Xor(A, A, A, A, A) == A
- assert Xor(True, False, False, A, B) == ~Xor(A, B)
- assert Xor(True) is true
- assert Xor(False) is false
- assert Xor(True, True) is false
- assert Xor(True, False) is true
- assert Xor(False, False) is false
- assert Xor(True, A) == ~A
- assert Xor(False, A) == A
- assert Xor(True, False, False) is true
- assert Xor(True, False, A) == ~A
- assert Xor(False, False, A) == A
- assert isinstance(Xor(A, B), Xor)
- assert Xor(A, B, Xor(C, D)) == Xor(A, B, C, D)
- assert Xor(A, B, Xor(B, C)) == Xor(A, C)
- assert Xor(A < 1, A >= 1, B) == Xor(0, 1, B) == Xor(1, 0, B)
- e = A > 1
- assert Xor(e, e.canonical) == Xor(0, 0) == Xor(1, 1)
- def test_rewrite_as_And():
- expr = x ^ y
- assert expr.rewrite(And) == (x | y) & (~x | ~y)
- def test_rewrite_as_Or():
- expr = x ^ y
- assert expr.rewrite(Or) == (x & ~y) | (y & ~x)
- def test_rewrite_as_Nand():
- expr = (y & z) | (z & ~w)
- assert expr.rewrite(Nand) == ~(~(y & z) & ~(z & ~w))
- def test_rewrite_as_Nor():
- expr = z & (y | ~w)
- assert expr.rewrite(Nor) == ~(~z | ~(y | ~w))
- def test_Not():
- raises(TypeError, lambda: Not(True, False))
- assert Not(True) is false
- assert Not(False) is true
- assert Not(0) is true
- assert Not(1) is false
- assert Not(2) is false
- def test_Nand():
- assert Nand() is false
- assert Nand(A) == ~A
- assert Nand(True) is false
- assert Nand(False) is true
- assert Nand(True, True) is false
- assert Nand(True, False) is true
- assert Nand(False, False) is true
- assert Nand(True, A) == ~A
- assert Nand(False, A) is true
- assert Nand(True, True, True) is false
- assert Nand(True, True, A) == ~A
- assert Nand(True, False, A) is true
- def test_Nor():
- assert Nor() is true
- assert Nor(A) == ~A
- assert Nor(True) is false
- assert Nor(False) is true
- assert Nor(True, True) is false
- assert Nor(True, False) is false
- assert Nor(False, False) is true
- assert Nor(True, A) is false
- assert Nor(False, A) == ~A
- assert Nor(True, True, True) is false
- assert Nor(True, True, A) is false
- assert Nor(True, False, A) is false
- def test_Xnor():
- assert Xnor() is true
- assert Xnor(A) == ~A
- assert Xnor(A, A) is true
- assert Xnor(True, A, A) is false
- assert Xnor(A, A, A, A, A) == ~A
- assert Xnor(True) is false
- assert Xnor(False) is true
- assert Xnor(True, True) is true
- assert Xnor(True, False) is false
- assert Xnor(False, False) is true
- assert Xnor(True, A) == A
- assert Xnor(False, A) == ~A
- assert Xnor(True, False, False) is false
- assert Xnor(True, False, A) == A
- assert Xnor(False, False, A) == ~A
- def test_Implies():
- raises(ValueError, lambda: Implies(A, B, C))
- assert Implies(True, True) is true
- assert Implies(True, False) is false
- assert Implies(False, True) is true
- assert Implies(False, False) is true
- assert Implies(0, A) is true
- assert Implies(1, 1) is true
- assert Implies(1, 0) is false
- assert A >> B == B << A
- assert (A < 1) >> (A >= 1) == (A >= 1)
- assert (A < 1) >> (S.One > A) is true
- assert A >> A is true
- def test_Equivalent():
- assert Equivalent(A, B) == Equivalent(B, A) == Equivalent(A, B, A)
- assert Equivalent() is true
- assert Equivalent(A, A) == Equivalent(A) is true
- assert Equivalent(True, True) == Equivalent(False, False) is true
- assert Equivalent(True, False) == Equivalent(False, True) is false
- assert Equivalent(A, True) == A
- assert Equivalent(A, False) == Not(A)
- assert Equivalent(A, B, True) == A & B
- assert Equivalent(A, B, False) == ~A & ~B
- assert Equivalent(1, A) == A
- assert Equivalent(0, A) == Not(A)
- assert Equivalent(A, Equivalent(B, C)) != Equivalent(Equivalent(A, B), C)
- assert Equivalent(A < 1, A >= 1) is false
- assert Equivalent(A < 1, A >= 1, 0) is false
- assert Equivalent(A < 1, A >= 1, 1) is false
- assert Equivalent(A < 1, S.One > A) == Equivalent(1, 1) == Equivalent(0, 0)
- assert Equivalent(Equality(A, B), Equality(B, A)) is true
- def test_Exclusive():
- assert Exclusive(False, False, False) is true
- assert Exclusive(True, False, False) is true
- assert Exclusive(True, True, False) is false
- assert Exclusive(True, True, True) is false
- 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
- raises(NotImplementedError, lambda: (A & B).equals(A > B))
- def test_simplification_boolalg():
- """
- 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(y, z), And(Not(w), Not(x))))
- assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
- minterms = [1, 3, 7, 11, 15]
- dontcares = [0, 2, 5]
- assert (
- SOPform([w, x, y, z], minterms, dontcares) ==
- Or(And(y, z), And(Not(w), Not(x))))
- assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
- minterms = [1, [0, 0, 1, 1], 7, [1, 0, 1, 1],
- [1, 1, 1, 1]]
- dontcares = [0, [0, 0, 1, 0], 5]
- assert (
- SOPform([w, x, y, z], minterms, dontcares) ==
- Or(And(y, z), And(Not(w), Not(x))))
- assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
- minterms = [1, {y: 1, z: 1}]
- dontcares = [0, [0, 0, 1, 0], 5]
- assert (
- SOPform([w, x, y, z], minterms, dontcares) ==
- Or(And(y, z), And(Not(w), Not(x))))
- assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z)
- minterms = [{y: 1, z: 1}, 1]
- dontcares = [[0, 0, 0, 0]]
- minterms = [[0, 0, 0]]
- raises(ValueError, lambda: SOPform([w, x, y, z], minterms))
- raises(ValueError, lambda: POSform([w, x, y, z], minterms))
- raises(TypeError, lambda: POSform([w, x, y, z], ["abcdefg"]))
- # 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
- raises(ValueError, lambda: simplify_logic(A & (B | C), form='blabla'))
- assert simplify(Or(x <= y, And(x < y, z))) == (x <= y)
- assert simplify(Or(x <= y, And(y > x, z))) == (x <= y)
- assert simplify(Or(x >= y, And(y < x, z))) == (x >= y)
- # Check that expressions with nine variables or more are not simplified
- # (without the force-flag)
- a, b, c, d, e, f, g, h, j = symbols('a b c d e f g h j')
- expr = a & b & c & d & e & f & g & h & j | \
- a & b & c & d & e & f & g & h & ~j
- # This expression can be simplified to get rid of the j variables
- assert simplify_logic(expr) == expr
- # Test dontcare
- assert simplify_logic((a & b) | c | d, dontcare=(a & b)) == c | d
- # 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
- assert simplify(And(Eq(x, 0), Eq(x, y))) == And(Eq(x, 0), Eq(y, 0))
- assert And(Eq(x - 1, 0), Eq(x, y)).simplify() == And(Eq(x, 1), Eq(y, 1))
- assert And(Ne(x - 1, 0), Ne(x, y)).simplify() == And(Ne(x, 1), Ne(x, y))
- assert And(Eq(x - 1, 0), Ne(x, y)).simplify() == And(Eq(x, 1), Ne(y, 1))
- assert And(Eq(x - 1, 0), Eq(x, z + y), Eq(y + x, 0)).simplify(
- ) == And(Eq(x, 1), Eq(y, -1), Eq(z, 2))
- assert And(Eq(x - 1, 0), Eq(x + 2, 3)).simplify() == Eq(x, 1)
- assert And(Ne(x - 1, 0), Ne(x + 2, 3)).simplify() == Ne(x, 1)
- assert And(Eq(x - 1, 0), Eq(x + 2, 2)).simplify() == False
- assert And(Ne(x - 1, 0), Ne(x + 2, 2)).simplify(
- ) == And(Ne(x, 1), Ne(x, 0))
- def test_bool_map():
- """
- Test working of bool_map function.
- """
- minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1],
- [1, 1, 1, 1]]
- assert bool_map(Not(Not(a)), a) == (a, {a: a})
- assert bool_map(SOPform([w, x, y, z], minterms),
- POSform([w, x, y, z], minterms)) == \
- (And(Or(Not(w), y), Or(Not(x), y), z), {x: x, w: w, z: z, y: y})
- assert bool_map(SOPform([x, z, y], [[1, 0, 1]]),
- SOPform([a, b, c], [[1, 0, 1]])) != False
- function1 = SOPform([x, z, y], [[1, 0, 1], [0, 0, 1]])
- function2 = SOPform([a, b, c], [[1, 0, 1], [1, 0, 0]])
- assert bool_map(function1, function2) == \
- (function1, {y: a, z: b})
- assert bool_map(Xor(x, y), ~Xor(x, y)) == False
- assert bool_map(And(x, y), Or(x, y)) is None
- assert bool_map(And(x, y), And(x, y, z)) is None
- # issue 16179
- assert bool_map(Xor(x, y, z), ~Xor(x, y, z)) == False
- assert bool_map(Xor(a, x, y, z), ~Xor(a, x, y, z)) == False
- def test_bool_symbol():
- """Test that mixing symbols with boolean values
- works as expected"""
- assert And(A, True) == A
- assert And(A, True, True) == A
- assert And(A, False) is false
- assert And(A, True, False) is false
- assert Or(A, True) is true
- assert Or(A, False) == A
- def test_is_boolean():
- assert isinstance(True, Boolean) is False
- assert isinstance(true, Boolean) is True
- assert 1 == True
- assert 1 != true
- assert (1 == true) is False
- assert 0 == False
- assert 0 != false
- assert (0 == false) is False
- assert true.is_Boolean is True
- assert (A & B).is_Boolean
- assert (A | B).is_Boolean
- assert (~A).is_Boolean
- assert (A ^ B).is_Boolean
- assert A.is_Boolean != isinstance(A, Boolean)
- assert isinstance(A, Boolean)
- def test_subs():
- assert (A & B).subs(A, True) == B
- assert (A & B).subs(A, False) is false
- assert (A & B).subs(B, True) == A
- assert (A & B).subs(B, False) is false
- assert (A & B).subs({A: True, B: True}) is true
- assert (A | B).subs(A, True) is true
- assert (A | B).subs(A, False) == B
- assert (A | B).subs(B, True) is true
- assert (A | B).subs(B, False) == A
- assert (A | B).subs({A: True, B: True}) is true
- """
- we test for axioms of boolean algebra
- see https://en.wikipedia.org/wiki/Boolean_algebra_(structure)
- """
- def test_commutative():
- """Test for commutativity of And and Or"""
- A, B = map(Boolean, symbols('A,B'))
- assert A & B == B & A
- assert A | B == B | A
- def test_and_associativity():
- """Test for associativity of And"""
- assert (A & B) & C == A & (B & C)
- def test_or_assicativity():
- assert ((A | B) | C) == (A | (B | C))
- def test_double_negation():
- a = Boolean()
- assert ~(~a) == a
- # test methods
- 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)
- def test_conjuncts():
- assert conjuncts(A & B & C) == {A, B, C}
- assert conjuncts((A | B) & C) == {A | B, C}
- assert conjuncts(A) == {A}
- assert conjuncts(True) == {True}
- assert conjuncts(False) == {False}
- def test_disjuncts():
- assert disjuncts(A | B | C) == {A, B, C}
- assert disjuncts((A | B) & C) == {(A | B) & C}
- assert disjuncts(A) == {A}
- assert disjuncts(True) == {True}
- assert disjuncts(False) == {False}
- 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))
- assert distribute_xor_over_and(And(A, Xor(B, C))) == Xor(And(A, B), And(A, C))
- def test_to_anf():
- x, y, z = symbols('x,y,z')
- assert to_anf(And(x, y)) == And(x, y)
- assert to_anf(Or(x, y)) == Xor(x, y, And(x, y))
- assert to_anf(Or(Implies(x, y), And(x, y), y)) == \
- Xor(x, True, x & y, remove_true=False)
- assert to_anf(Or(Nand(x, y), Nor(x, y), Xnor(x, y), Implies(x, y))) == True
- assert to_anf(Or(x, Not(y), Nor(x,z), And(x, y), Nand(y, z))) == \
- Xor(True, And(y, z), And(x, y, z), remove_true=False)
- assert to_anf(Xor(x, y)) == Xor(x, y)
- assert to_anf(Not(x)) == Xor(x, True, remove_true=False)
- assert to_anf(Nand(x, y)) == Xor(True, And(x, y), remove_true=False)
- assert to_anf(Nor(x, y)) == Xor(x, y, True, And(x, y), remove_true=False)
- assert to_anf(Implies(x, y)) == Xor(x, True, And(x, y), remove_true=False)
- assert to_anf(Equivalent(x, y)) == Xor(x, y, True, remove_true=False)
- assert to_anf(Nand(x | y, x >> y), deep=False) == \
- Xor(True, And(Or(x, y), Implies(x, y)), remove_true=False)
- assert to_anf(Nor(x ^ y, x & y), deep=False) == \
- Xor(True, Or(Xor(x, y), And(x, y)), remove_true=False)
- def test_to_nnf():
- assert to_nnf(true) is true
- assert to_nnf(false) is false
- assert to_nnf(A) == A
- assert to_nnf(A | ~A | B) is true
- assert to_nnf(A & ~A & B) is false
- assert to_nnf(A >> B) == ~A | B
- assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
- assert to_nnf(A ^ B ^ C) == \
- (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
- assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
- assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
- assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
- assert to_nnf(Not(A >> B)) == A & ~B
- assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
- assert to_nnf(Not(A ^ B ^ C)) == \
- (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
- assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
- assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
- assert to_nnf((A >> B) ^ (B >> A), False) == \
- (~A | ~B | A | B) & ((A & ~B) | (~A & B))
- assert ITE(A, 1, 0).to_nnf() == A
- assert ITE(A, 0, 1).to_nnf() == ~A
- # although ITE can hold non-Boolean, it will complain if
- # an attempt is made to convert the ITE to Boolean nnf
- raises(TypeError, lambda: ITE(A < 1, [1], B).to_nnf())
- def test_to_cnf():
- assert to_cnf(~(B | C)) == And(Not(B), Not(C))
- assert to_cnf((A & B) | C) == And(Or(A, C), Or(B, C))
- assert to_cnf(A >> B) == (~A) | B
- assert to_cnf(A >> (B & C)) == (~A | B) & (~A | C)
- assert to_cnf(A & (B | C) | ~A & (B | C), True) == B | C
- assert to_cnf(A & B) == And(A, B)
- assert to_cnf(Equivalent(A, B)) == And(Or(A, Not(B)), Or(B, Not(A)))
- assert to_cnf(Equivalent(A, B & C)) == \
- (~A | B) & (~A | C) & (~B | ~C | A)
- assert to_cnf(Equivalent(A, B | C), True) == \
- And(Or(Not(B), A), Or(Not(C), A), Or(B, C, Not(A)))
- assert to_cnf(A + 1) == A + 1
- def test_issue_18904():
- x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = symbols('x1:16')
- eq = (( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9 ) |
- ( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x10 & x9 ) |
- ( x1 & x11 & x3 & x12 & x5 & x13 & x14 & x15 & x9 ))
- assert is_cnf(to_cnf(eq))
- raises(ValueError, lambda: to_cnf(eq, simplify=True))
- for f, t in zip((And, Or), (to_cnf, to_dnf)):
- eq = f(x1, x2, x3, x4, x5, x6, x7, x8, x9)
- raises(ValueError, lambda: to_cnf(eq, simplify=True))
- assert t(eq, simplify=True, force=True) == eq
- def test_issue_9949():
- assert is_cnf(to_cnf((b > -5) | (a > 2) & (a < 4)))
- def test_to_CNF():
- assert CNF.CNF_to_cnf(CNF.to_CNF(~(B | C))) == to_cnf(~(B | C))
- assert CNF.CNF_to_cnf(CNF.to_CNF((A & B) | C)) == to_cnf((A & B) | C)
- assert CNF.CNF_to_cnf(CNF.to_CNF(A >> B)) == to_cnf(A >> B)
- assert CNF.CNF_to_cnf(CNF.to_CNF(A >> (B & C))) == to_cnf(A >> (B & C))
- assert CNF.CNF_to_cnf(CNF.to_CNF(A & (B | C) | ~A & (B | C))) == to_cnf(A & (B | C) | ~A & (B | C))
- assert CNF.CNF_to_cnf(CNF.to_CNF(A & B)) == to_cnf(A & B)
- def test_to_dnf():
- assert to_dnf(~(B | C)) == And(Not(B), Not(C))
- assert to_dnf(A & (B | C)) == Or(And(A, B), And(A, C))
- assert to_dnf(A >> B) == (~A) | B
- assert to_dnf(A >> (B & C)) == (~A) | (B & C)
- assert to_dnf(A | B) == A | B
- assert to_dnf(Equivalent(A, B), True) == \
- Or(And(A, B), And(Not(A), Not(B)))
- assert to_dnf(Equivalent(A, B & C), True) == \
- Or(And(A, B, C), And(Not(A), Not(B)), And(Not(A), Not(C)))
- assert to_dnf(A + 1) == A + 1
- def test_to_int_repr():
- x, y, z = map(Boolean, symbols('x,y,z'))
- def sorted_recursive(arg):
- try:
- return sorted(sorted_recursive(x) for x in arg)
- except TypeError: # arg is not a sequence
- return arg
- assert sorted_recursive(to_int_repr([x | y, z | x], [x, y, z])) == \
- sorted_recursive([[1, 2], [1, 3]])
- assert sorted_recursive(to_int_repr([x | y, z | ~x], [x, y, z])) == \
- sorted_recursive([[1, 2], [3, -1]])
- def test_is_anf():
- x, y = symbols('x,y')
- assert is_anf(true) is True
- assert is_anf(false) is True
- assert is_anf(x) is True
- assert is_anf(And(x, y)) is True
- assert is_anf(Xor(x, y, And(x, y))) is True
- assert is_anf(Xor(x, y, Or(x, y))) is False
- assert is_anf(Xor(Not(x), y)) is False
- def test_is_nnf():
- assert is_nnf(true) is True
- assert is_nnf(A) is True
- assert is_nnf(~A) is True
- assert is_nnf(A & B) is True
- assert is_nnf((A & B) | (~A & A) | (~B & B) | (~A & ~B), False) is True
- assert is_nnf((A | B) & (~A | ~B)) is True
- assert is_nnf(Not(Or(A, B))) is False
- assert is_nnf(A ^ B) is False
- assert is_nnf((A & B) | (~A & A) | (~B & B) | (~A & ~B), True) is False
- def test_is_cnf():
- assert is_cnf(x) is True
- assert is_cnf(x | y | z) is True
- assert is_cnf(x & y & z) is True
- assert is_cnf((x | y) & z) is True
- assert is_cnf((x & y) | z) is False
- assert is_cnf(~(x & y) | z) is False
- def test_is_dnf():
- assert is_dnf(x) is True
- assert is_dnf(x | y | z) is True
- assert is_dnf(x & y & z) is True
- assert is_dnf((x & y) | z) is True
- assert is_dnf((x | y) & z) is False
- assert is_dnf(~(x | y) & z) is False
- def test_ITE():
- A, B, C = symbols('A:C')
- assert ITE(True, False, True) is false
- assert ITE(True, True, False) is true
- assert ITE(False, True, False) is false
- assert ITE(False, False, True) is true
- assert isinstance(ITE(A, B, C), ITE)
- A = True
- assert ITE(A, B, C) == B
- A = False
- assert ITE(A, B, C) == C
- B = True
- assert ITE(And(A, B), B, C) == C
- assert ITE(Or(A, False), And(B, True), False) is false
- assert ITE(x, A, B) == Not(x)
- assert ITE(x, B, A) == x
- assert ITE(1, x, y) == x
- assert ITE(0, x, y) == y
- raises(TypeError, lambda: ITE(2, x, y))
- raises(TypeError, lambda: ITE(1, [], y))
- raises(TypeError, lambda: ITE(1, (), y))
- raises(TypeError, lambda: ITE(1, y, []))
- assert ITE(1, 1, 1) is S.true
- assert isinstance(ITE(1, 1, 1, evaluate=False), ITE)
- raises(TypeError, lambda: ITE(x > 1, y, x))
- assert ITE(Eq(x, True), y, x) == ITE(x, y, x)
- assert ITE(Eq(x, False), y, x) == ITE(~x, y, x)
- assert ITE(Ne(x, True), y, x) == ITE(~x, y, x)
- assert ITE(Ne(x, False), y, x) == ITE(x, y, x)
- assert ITE(Eq(S. true, x), y, x) == ITE(x, y, x)
- assert ITE(Eq(S.false, x), y, x) == ITE(~x, y, x)
- assert ITE(Ne(S.true, x), y, x) == ITE(~x, y, x)
- assert ITE(Ne(S.false, x), y, x) == ITE(x, y, x)
- # 0 and 1 in the context are not treated as True/False
- # so the equality must always be False since dissimilar
- # objects cannot be equal
- assert ITE(Eq(x, 0), y, x) == x
- assert ITE(Eq(x, 1), y, x) == x
- assert ITE(Ne(x, 0), y, x) == y
- assert ITE(Ne(x, 1), y, x) == y
- assert ITE(Eq(x, 0), y, z).subs(x, 0) == y
- assert ITE(Eq(x, 0), y, z).subs(x, 1) == z
- raises(ValueError, lambda: ITE(x > 1, y, x, z))
- def test_is_literal():
- assert is_literal(True) is True
- assert is_literal(False) is True
- assert is_literal(A) is True
- assert is_literal(~A) is True
- assert is_literal(Or(A, B)) is False
- assert is_literal(Q.zero(A)) is True
- assert is_literal(Not(Q.zero(A))) is True
- assert is_literal(Or(A, B)) is False
- assert is_literal(And(Q.zero(A), Q.zero(B))) is False
- assert is_literal(x < 3)
- assert not is_literal(x + y < 3)
- def test_operators():
- # Mostly test __and__, __rand__, and so on
- assert True & A == A & True == A
- assert False & A == A & False == False
- assert A & B == And(A, B)
- assert True | A == A | True == True
- assert False | A == A | False == A
- assert A | B == Or(A, B)
- assert ~A == Not(A)
- assert True >> A == A << True == A
- assert False >> A == A << False == True
- assert A >> True == True << A == True
- assert A >> False == False << A == ~A
- assert A >> B == B << A == Implies(A, B)
- assert True ^ A == A ^ True == ~A
- assert False ^ A == A ^ False == A
- assert A ^ B == Xor(A, B)
- 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 product((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 F is not False:
- assert F & F is false
- if T is not 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 F is not False:
- assert F | F is false
- if T is not 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 F is not False:
- assert F ^ F is false
- if T is not 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 F is not False:
- assert F >> F is true
- assert F << F is true
- if T is not 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))
- def test_bool_as_set():
- assert ITE(y <= 0, False, y >= 1).as_set() == Interval(1, oo)
- assert And(x <= 2, x >= -2).as_set() == Interval(-2, 2)
- assert Or(x >= 2, x <= -2).as_set() == Interval(-oo, -2) + Interval(2, oo)
- assert Not(x > 2).as_set() == Interval(-oo, 2)
- # issue 10240
- assert Not(And(x > 2, x < 3)).as_set() == \
- Union(Interval(-oo, 2), Interval(3, oo))
- assert true.as_set() == S.UniversalSet
- assert false.as_set() is S.EmptySet
- assert x.as_set() == S.UniversalSet
- assert And(Or(x < 1, x > 3), x < 2).as_set() == Interval.open(-oo, 1)
- assert And(x < 1, sin(x) < 3).as_set() == (x < 1).as_set()
- raises(NotImplementedError, lambda: (sin(x) < 1).as_set())
- # watch for object morph in as_set
- assert Eq(-1, cos(2*x)**2/sin(2*x)**2).as_set() is S.EmptySet
- @XFAIL
- 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)
- def test_all_or_nothing():
- x = symbols('x', extended_real=True)
- args = x >= -oo, x <= oo
- v = And(*args)
- if v.func is And:
- assert len(v.args) == len(args) - args.count(S.true)
- else:
- assert v == True
- v = Or(*args)
- if v.func is Or:
- assert len(v.args) == 2
- else:
- assert v == True
- def test_canonical_atoms():
- assert true.canonical == true
- assert false.canonical == false
- def test_negated_atoms():
- assert true.negated == false
- assert false.negated == true
- def test_issue_8777():
- assert And(x > 2, x < oo).as_set() == Interval(2, oo, left_open=True)
- assert And(x >= 1, x < oo).as_set() == Interval(1, oo)
- assert (x < oo).as_set() == Interval(-oo, oo)
- assert (x > -oo).as_set() == Interval(-oo, oo)
- def test_issue_8975():
- assert Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)).as_set() == \
- Interval(-oo, -2) + Interval(2, oo)
- def test_term_to_integer():
- assert term_to_integer([1, 0, 1, 0, 0, 1, 0]) == 82
- assert term_to_integer('0010101000111001') == 10809
- def test_issue_21971():
- a, b, c, d = symbols('a b c d')
- f = a & b & c | a & c
- assert f.subs(a & c, d) == b & d | d
- assert f.subs(a & b & c, d) == a & c | d
- f = (a | b | c) & (a | c)
- assert f.subs(a | c, d) == (b | d) & d
- assert f.subs(a | b | c, d) == (a | c) & d
- f = (a ^ b ^ c) & (a ^ c)
- assert f.subs(a ^ c, d) == (b ^ d) & d
- assert f.subs(a ^ b ^ c, d) == (a ^ c) & d
- def test_truth_table():
- assert list(truth_table(And(x, y), [x, y], input=False)) == \
- [False, False, False, True]
- assert list(truth_table(x | y, [x, y], input=False)) == \
- [False, True, True, True]
- assert list(truth_table(x >> y, [x, y], input=False)) == \
- [True, True, False, True]
- assert list(truth_table(And(x, y), [x, y])) == \
- [([0, 0], False), ([0, 1], False), ([1, 0], False), ([1, 1], True)]
- def test_issue_8571():
- for t in (S.true, S.false):
- raises(TypeError, lambda: +t)
- raises(TypeError, lambda: -t)
- raises(TypeError, lambda: abs(t))
- # use int(bool(t)) to get 0 or 1
- raises(TypeError, lambda: int(t))
- for o in [S.Zero, S.One, x]:
- for _ in range(2):
- raises(TypeError, lambda: o + t)
- raises(TypeError, lambda: o - t)
- raises(TypeError, lambda: o % t)
- raises(TypeError, lambda: o*t)
- raises(TypeError, lambda: o/t)
- raises(TypeError, lambda: o**t)
- o, t = t, o # do again in reversed order
- def test_expand_relational():
- n = symbols('n', negative=True)
- p, q = symbols('p q', positive=True)
- r = ((n + q*(-n/q + 1))/(q*(-n/q + 1)) < 0)
- assert r is not S.false
- assert r.expand() is S.false
- assert (q > 0).expand() is S.true
- def test_issue_12717():
- assert S.true.is_Atom == True
- assert S.false.is_Atom == True
- def test_as_Boolean():
- nz = symbols('nz', nonzero=True)
- assert all(as_Boolean(i) is S.true for i in (True, S.true, 1, nz))
- z = symbols('z', zero=True)
- assert all(as_Boolean(i) is S.false for i in (False, S.false, 0, z))
- assert all(as_Boolean(i) == i for i in (x, x < 0))
- for i in (2, S(2), x + 1, []):
- raises(TypeError, lambda: as_Boolean(i))
- def test_binary_symbols():
- assert ITE(x < 1, y, z).binary_symbols == {y, z}
- for f in (Eq, Ne):
- assert f(x, 1).binary_symbols == set()
- assert f(x, True).binary_symbols == {x}
- assert f(x, False).binary_symbols == {x}
- assert S.true.binary_symbols == set()
- assert S.false.binary_symbols == set()
- assert x.binary_symbols == {x}
- assert And(x, Eq(y, False), Eq(z, 1)).binary_symbols == {x, y}
- assert Q.prime(x).binary_symbols == set()
- assert Q.lt(x, 1).binary_symbols == set()
- assert Q.is_true(x).binary_symbols == {x}
- assert Q.eq(x, True).binary_symbols == {x}
- assert Q.prime(x).binary_symbols == set()
- def test_BooleanFunction_diff():
- assert And(x, y).diff(x) == Piecewise((0, Eq(y, False)), (1, True))
- def test_issue_14700():
- A, B, C, D, E, F, G, H = symbols('A B C D E F G H')
- q = ((B & D & H & ~F) | (B & H & ~C & ~D) | (B & H & ~C & ~F) |
- (B & H & ~D & ~G) | (B & H & ~F & ~G) | (C & G & ~B & ~D) |
- (C & G & ~D & ~H) | (C & G & ~F & ~H) | (D & F & H & ~B) |
- (D & F & ~G & ~H) | (B & D & F & ~C & ~H) | (D & E & F & ~B & ~C) |
- (D & F & ~A & ~B & ~C) | (D & F & ~A & ~C & ~H) |
- (A & B & D & F & ~E & ~H))
- soldnf = ((B & D & H & ~F) | (D & F & H & ~B) | (B & H & ~C & ~D) |
- (B & H & ~D & ~G) | (C & G & ~B & ~D) | (C & G & ~D & ~H) |
- (C & G & ~F & ~H) | (D & F & ~G & ~H) | (D & E & F & ~C & ~H) |
- (D & F & ~A & ~C & ~H) | (A & B & D & F & ~E & ~H))
- solcnf = ((B | C | D) & (B | D | G) & (C | D | H) & (C | F | H) &
- (D | G | H) & (F | G | H) & (B | F | ~D | ~H) &
- (~B | ~D | ~F | ~H) & (D | ~B | ~C | ~G | ~H) &
- (A | H | ~C | ~D | ~F | ~G) & (H | ~C | ~D | ~E | ~F | ~G) &
- (B | E | H | ~A | ~D | ~F | ~G))
- assert simplify_logic(q, "dnf") == soldnf
- assert simplify_logic(q, "cnf") == solcnf
- minterms = [[0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1],
- [0, 0, 1, 1], [1, 0, 1, 1]]
- dontcares = [[1, 0, 0, 0], [1, 0, 0, 1], [1, 1, 0, 0], [1, 1, 0, 1]]
- assert SOPform([w, x, y, z], minterms) == (x & ~w) | (y & z & ~x)
- # Should not be more complicated with don't cares
- assert SOPform([w, x, y, z], minterms, dontcares) == \
- (x & ~w) | (y & z & ~x)
- def test_relational_simplification():
- w, x, y, z = symbols('w x y z', real=True)
- d, e = symbols('d e', real=False)
- # Test all combinations or sign and order
- assert Or(x >= y, x < y).simplify() == S.true
- assert Or(x >= y, y > x).simplify() == S.true
- assert Or(x >= y, -x > -y).simplify() == S.true
- assert Or(x >= y, -y < -x).simplify() == S.true
- assert Or(-x <= -y, x < y).simplify() == S.true
- assert Or(-x <= -y, -x > -y).simplify() == S.true
- assert Or(-x <= -y, y > x).simplify() == S.true
- assert Or(-x <= -y, -y < -x).simplify() == S.true
- assert Or(y <= x, x < y).simplify() == S.true
- assert Or(y <= x, y > x).simplify() == S.true
- assert Or(y <= x, -x > -y).simplify() == S.true
- assert Or(y <= x, -y < -x).simplify() == S.true
- assert Or(-y >= -x, x < y).simplify() == S.true
- assert Or(-y >= -x, y > x).simplify() == S.true
- assert Or(-y >= -x, -x > -y).simplify() == S.true
- assert Or(-y >= -x, -y < -x).simplify() == S.true
- assert Or(x < y, x >= y).simplify() == S.true
- assert Or(y > x, x >= y).simplify() == S.true
- assert Or(-x > -y, x >= y).simplify() == S.true
- assert Or(-y < -x, x >= y).simplify() == S.true
- assert Or(x < y, -x <= -y).simplify() == S.true
- assert Or(-x > -y, -x <= -y).simplify() == S.true
- assert Or(y > x, -x <= -y).simplify() == S.true
- assert Or(-y < -x, -x <= -y).simplify() == S.true
- assert Or(x < y, y <= x).simplify() == S.true
- assert Or(y > x, y <= x).simplify() == S.true
- assert Or(-x > -y, y <= x).simplify() == S.true
- assert Or(-y < -x, y <= x).simplify() == S.true
- assert Or(x < y, -y >= -x).simplify() == S.true
- assert Or(y > x, -y >= -x).simplify() == S.true
- assert Or(-x > -y, -y >= -x).simplify() == S.true
- assert Or(-y < -x, -y >= -x).simplify() == S.true
- # Some other tests
- assert Or(x >= y, w < z, x <= y).simplify() == S.true
- assert And(x >= y, x < y).simplify() == S.false
- assert Or(x >= y, Eq(y, x)).simplify() == (x >= y)
- assert And(x >= y, Eq(y, x)).simplify() == Eq(x, y)
- assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \
- (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z))
- assert Or(Eq(x, y), x >= y, w < y, z < y).simplify() == \
- (x >= y) | (y > z) | (w < y)
- assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify() == \
- Eq(x, y) & (y > z) & (w < y)
- # assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify(relational_minmax=True) == \
- # And(Eq(x, y), y > Max(w, z))
- # assert Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify(relational_minmax=True) == \
- # (Eq(x, y) | (x >= 1) | (y > Min(2, z)))
- assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \
- (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z))
- assert (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)).simplify() == \
- (Eq(x, y) & Eq(d, e) & (d >= e))
- assert And(Eq(x, y), Eq(x, -y)).simplify() == And(Eq(x, 0), Eq(y, 0))
- assert Xor(x >= y, x <= y).simplify() == Ne(x, y)
- assert And(x > 1, x < -1, Eq(x, y)).simplify() == S.false
- # From #16690
- assert And(x >= y, Eq(y, 0)).simplify() == And(x >= 0, Eq(y, 0))
- assert Or(Ne(x, 1), Ne(x, 2)).simplify() == S.true
- assert And(Eq(x, 1), Ne(2, x)).simplify() == Eq(x, 1)
- assert Or(Eq(x, 1), Ne(2, x)).simplify() == Ne(x, 2)
- def test_issue_8373():
- x = symbols('x', real=True)
- assert Or(x < 1, x > -1).simplify() == S.true
- assert Or(x < 1, x >= 1).simplify() == S.true
- assert And(x < 1, x >= 1).simplify() == S.false
- assert Or(x <= 1, x >= 1).simplify() == S.true
- def test_issue_7950():
- x = symbols('x', real=True)
- assert And(Eq(x, 1), Eq(x, 2)).simplify() == S.false
- @slow
- def test_relational_simplification_numerically():
- def test_simplification_numerically_function(original, simplified):
- symb = original.free_symbols
- n = len(symb)
- valuelist = list(set(combinations(list(range(-(n-1), n))*n, n)))
- for values in valuelist:
- sublist = dict(zip(symb, values))
- originalvalue = original.subs(sublist)
- simplifiedvalue = simplified.subs(sublist)
- assert originalvalue == simplifiedvalue, "Original: {}\nand"\
- " simplified: {}\ndo not evaluate to the same value for {}"\
- "".format(original, simplified, sublist)
- w, x, y, z = symbols('w x y z', real=True)
- d, e = symbols('d e', real=False)
- expressions = (And(Eq(x, y), x >= y, w < y, y >= z, z < y),
- And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y),
- Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y),
- And(x >= y, Eq(y, x)),
- Or(And(Eq(x, y), x >= y, w < y, Or(y >= z, z < y)),
- And(Eq(x, y), x >= 1, 2 < y, y >= -1, z < y)),
- (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)),
- )
- for expression in expressions:
- test_simplification_numerically_function(expression,
- expression.simplify())
- def test_relational_simplification_patterns_numerically():
- from sympy.core import Wild
- from sympy.logic.boolalg import _simplify_patterns_and, \
- _simplify_patterns_or, _simplify_patterns_xor
- a = Wild('a')
- b = Wild('b')
- c = Wild('c')
- symb = [a, b, c]
- patternlists = [[And, _simplify_patterns_and()],
- [Or, _simplify_patterns_or()],
- [Xor, _simplify_patterns_xor()]]
- valuelist = list(set(combinations(list(range(-2, 3))*3, 3)))
- # Skip combinations of +/-2 and 0, except for all 0
- valuelist = [v for v in valuelist if any([w % 2 for w in v]) or not any(v)]
- for func, patternlist in patternlists:
- for pattern in patternlist:
- original = func(*pattern[0].args)
- simplified = pattern[1]
- for values in valuelist:
- sublist = dict(zip(symb, values))
- originalvalue = original.xreplace(sublist)
- simplifiedvalue = simplified.xreplace(sublist)
- assert originalvalue == simplifiedvalue, "Original: {}\nand"\
- " simplified: {}\ndo not evaluate to the same value for"\
- "{}".format(pattern[0], simplified, sublist)
- def test_issue_16803():
- n = symbols('n')
- # No simplification done, but should not raise an exception
- assert ((n > 3) | (n < 0) | ((n > 0) & (n < 3))).simplify() == \
- (n > 3) | (n < 0) | ((n > 0) & (n < 3))
- def test_issue_17530():
- r = {x: oo, y: oo}
- assert Or(x + y > 0, x - y < 0).subs(r)
- assert not And(x + y < 0, x - y < 0).subs(r)
- raises(TypeError, lambda: Or(x + y < 0, x - y < 0).subs(r))
- raises(TypeError, lambda: And(x + y > 0, x - y < 0).subs(r))
- raises(TypeError, lambda: And(x + y > 0, x - y < 0).subs(r))
- def test_anf_coeffs():
- assert anf_coeffs([1, 0]) == [1, 1]
- assert anf_coeffs([0, 0, 0, 1]) == [0, 0, 0, 1]
- assert anf_coeffs([0, 1, 1, 1]) == [0, 1, 1, 1]
- assert anf_coeffs([1, 1, 1, 0]) == [1, 0, 0, 1]
- assert anf_coeffs([1, 0, 0, 0]) == [1, 1, 1, 1]
- assert anf_coeffs([1, 0, 0, 1]) == [1, 1, 1, 0]
- assert anf_coeffs([1, 1, 0, 1]) == [1, 0, 1, 1]
- def test_ANFform():
- x, y = symbols('x,y')
- assert ANFform([x], [1, 1]) == True
- assert ANFform([x], [0, 0]) == False
- assert ANFform([x], [1, 0]) == Xor(x, True, remove_true=False)
- assert ANFform([x, y], [1, 1, 1, 0]) == \
- Xor(True, And(x, y), remove_true=False)
- def test_bool_minterm():
- x, y = symbols('x,y')
- assert bool_minterm(3, [x, y]) == And(x, y)
- assert bool_minterm([1, 0], [x, y]) == And(Not(y), x)
- def test_bool_maxterm():
- x, y = symbols('x,y')
- assert bool_maxterm(2, [x, y]) == Or(Not(x), y)
- assert bool_maxterm([0, 1], [x, y]) == Or(Not(y), x)
- def test_bool_monomial():
- x, y = symbols('x,y')
- assert bool_monomial(1, [x, y]) == y
- assert bool_monomial([1, 1], [x, y]) == And(x, y)
- def test_check_pair():
- assert _check_pair([0, 1, 0], [0, 1, 1]) == 2
- assert _check_pair([0, 1, 0], [1, 1, 1]) == -1
- def test_issue_19114():
- expr = (B & C) | (A & ~C) | (~A & ~B)
- # Expression is minimal, but there are multiple minimal forms possible
- res1 = (A & B) | (C & ~A) | (~B & ~C)
- result = to_dnf(expr, simplify=True)
- assert result in (expr, res1)
- def test_issue_20870():
- result = SOPform([a, b, c, d], [1, 2, 3, 4, 5, 6, 8, 9, 11, 12, 14, 15])
- expected = ((d & ~b) | (a & b & c) | (a & ~c & ~d) |
- (b & ~a & ~c) | (c & ~a & ~d))
- assert result == expected
- def test_convert_to_varsSOP():
- assert _convert_to_varsSOP([0, 1, 0], [x, y, z]) == And(Not(x), y, Not(z))
- assert _convert_to_varsSOP([3, 1, 0], [x, y, z]) == And(y, Not(z))
- def test_convert_to_varsPOS():
- assert _convert_to_varsPOS([0, 1, 0], [x, y, z]) == Or(x, Not(y), z)
- assert _convert_to_varsPOS([3, 1, 0], [x, y, z]) == Or(Not(y), z)
- def test_gateinputcount():
- a, b, c, d, e = symbols('a:e')
- assert gateinputcount(And(a, b)) == 2
- assert gateinputcount(a | b & c & d ^ (e | a)) == 9
- assert gateinputcount(And(a, True)) == 0
- raises(TypeError, lambda: gateinputcount(a*b))
- def test_refine():
- # relational
- assert not refine(x < 0, ~(x < 0))
- assert refine(x < 0, (x < 0))
- assert refine(x < 0, (0 > x)) is S.true
- assert refine(x < 0, (y < 0)) == (x < 0)
- assert not refine(x <= 0, ~(x <= 0))
- assert refine(x <= 0, (x <= 0))
- assert refine(x <= 0, (0 >= x)) is S.true
- assert refine(x <= 0, (y <= 0)) == (x <= 0)
- assert not refine(x > 0, ~(x > 0))
- assert refine(x > 0, (x > 0))
- assert refine(x > 0, (0 < x)) is S.true
- assert refine(x > 0, (y > 0)) == (x > 0)
- assert not refine(x >= 0, ~(x >= 0))
- assert refine(x >= 0, (x >= 0))
- assert refine(x >= 0, (0 <= x)) is S.true
- assert refine(x >= 0, (y >= 0)) == (x >= 0)
- assert not refine(Eq(x, 0), ~(Eq(x, 0)))
- assert refine(Eq(x, 0), (Eq(x, 0)))
- assert refine(Eq(x, 0), (Eq(0, x))) is S.true
- assert refine(Eq(x, 0), (Eq(y, 0))) == Eq(x, 0)
- assert not refine(Ne(x, 0), ~(Ne(x, 0)))
- assert refine(Ne(x, 0), (Ne(0, x))) is S.true
- assert refine(Ne(x, 0), (Ne(x, 0)))
- assert refine(Ne(x, 0), (Ne(y, 0))) == (Ne(x, 0))
- # boolean functions
- assert refine(And(x > 0, y > 0), (x > 0)) == (y > 0)
- assert refine(And(x > 0, y > 0), (x > 0) & (y > 0)) is S.true
- # predicates
- assert refine(Q.positive(x), Q.positive(x)) is S.true
- assert refine(Q.positive(x), Q.negative(x)) is S.false
- assert refine(Q.positive(x), Q.real(x)) == Q.positive(x)
- def test_relational_threeterm_simplification_patterns_numerically():
- from sympy.core import Wild
- from sympy.logic.boolalg import _simplify_patterns_and3
- a = Wild('a')
- b = Wild('b')
- c = Wild('c')
- symb = [a, b, c]
- patternlists = [[And, _simplify_patterns_and3()]]
- valuelist = list(set(combinations(list(range(-2, 3))*3, 3)))
- # Skip combinations of +/-2 and 0, except for all 0
- valuelist = [v for v in valuelist if any([w % 2 for w in v]) or not any(v)]
- for func, patternlist in patternlists:
- for pattern in patternlist:
- original = func(*pattern[0].args)
- simplified = pattern[1]
- for values in valuelist:
- sublist = dict(zip(symb, values))
- originalvalue = original.xreplace(sublist)
- simplifiedvalue = simplified.xreplace(sublist)
- assert originalvalue == simplifiedvalue, "Original: {}\nand"\
- " simplified: {}\ndo not evaluate to the same value for"\
- "{}".format(pattern[0], simplified, sublist)
|