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 pytest.raises(NotImplementedError, lambda: And(A, A < B).equals(And(A, B > A)))
def test_eliminate_implications(): from diofant.abc import A, B, C, D 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_bool_as_set(): assert And(x <= 2, x >= -2).as_set() == Interval(-2, 2) assert Or(x >= 2, x <= -2).as_set() == (Interval(-oo, -2, True) + Interval(2, oo, False, True)) assert Not(x > 2, evaluate=False).as_set() == Interval(-oo, 2, True) # issue sympy/sympy#10240 assert Not(And(x > 2, x < 3)).as_set() == \ Union(Interval(-oo, 2, True), Interval(3, oo, False, True)) assert true.as_set() == S.UniversalSet assert false.as_set() == EmptySet()
def entails(expr, formula_set={}): """ Check whether the given expr_set entail an expr. If formula_set is empty then it returns the validity of expr. Examples ======== >>> from diofant.abc import A, B, C >>> from diofant.logic.inference import entails >>> entails(A, [A >> B, B >> C]) False >>> entails(C, [A >> B, B >> C, A]) True >>> entails(A >> B) False >>> entails(A >> (B >> A)) True References ========== .. [1] http://en.wikipedia.org/wiki/Logical_consequence """ formula_set = list(formula_set) formula_set.append(Not(expr)) return not satisfiable(And(*formula_set))
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(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 | B) | C) == And(Or(Not(A), C), Or(Not(B), C))
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, Integer(1) > A) == Equivalent(1, 1) == Equivalent(0, 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]] from diofant.abc import a, b, c, w, x, y, z 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]])) is not S.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})
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_to_dnf(): assert to_dnf(true) == true assert to_dnf((~B) & (~C)) == (~B) & (~C) 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(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)))
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_Not(): pytest.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 assert Not(Unequality(A, B)) == Equality(A, B)
def test_is_nnf(): from diofant.abc import A, B 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_to_nnf(): assert to_nnf(true) is true assert to_nnf(false) is false assert to_nnf(A) == A assert (~A).to_nnf() == ~A class Boo(BooleanFunction): pass pytest.raises(ValueError, lambda: to_nnf(~Boo(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))
def piecewise_fold(expr): """ Takes an expression containing a piecewise function and returns the expression in piecewise form. Examples ======== >>> from diofant import Piecewise, piecewise_fold, Integer >>> from diofant.abc import x >>> p = Piecewise((x, x < 1), (1, Integer(1) <= x)) >>> piecewise_fold(x*p) Piecewise((x**2, x < 1), (x, 1 <= x)) See Also ======== diofant.functions.elementary.piecewise.Piecewise """ if not isinstance(expr, Basic) or not expr.has(Piecewise): return expr new_args = list(map(piecewise_fold, expr.args)) if expr.func is ExprCondPair: return ExprCondPair(*new_args) piecewise_args = [] for n, arg in enumerate(new_args): if isinstance(arg, Piecewise): piecewise_args.append(n) if len(piecewise_args) > 0: n = piecewise_args[0] new_args = [(expr.func(*(new_args[:n] + [e] + new_args[n + 1:])), c) for e, c in new_args[n].args] if isinstance(expr, Boolean): # If expr is Boolean, we must return some kind of PiecewiseBoolean. # This is constructed by means of Or, And and Not. # piecewise_fold(0 < Piecewise( (sin(x), x<0), (cos(x), True))) # can't return Piecewise((0 < sin(x), x < 0), (0 < cos(x), True)) # but instead Or(And(x < 0, 0 < sin(x)), And(0 < cos(x), Not(x<0))) other = True rtn = False for e, c in new_args: rtn = Or(rtn, And(other, c, e)) other = And(other, Not(c)) if len(piecewise_args) > 1: return piecewise_fold(rtn) return rtn if len(piecewise_args) > 1: return piecewise_fold(Piecewise(*new_args)) return Piecewise(*new_args) else: return expr.func(*new_args)
def dpll(clauses, symbols, model): """ Compute satisfiability in a partial model. Clauses is an array of conjuncts. >>> from diofant.abc import A, B, D >>> from diofant.logic.algorithms.dpll import dpll >>> dpll([A, B, D], [A, B], {D: False}) False """ # compute DP kernel P, value = find_unit_clause(clauses, model) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_unit_clause(clauses, model) P, value = find_pure_symbol(symbols, clauses) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_pure_symbol(symbols, clauses) # end DP kernel unknown_clauses = [] for c in clauses: val = pl_true(c, model) if val is False: return False if val is not True: unknown_clauses.append(c) if not unknown_clauses: return model if not clauses: return model P = symbols.pop() model_copy = model.copy() model.update({P: True}) model_copy.update({P: False}) symbols_copy = symbols[:] return (dpll(unit_propagate(unknown_clauses, P), symbols, model) or dpll(unit_propagate(unknown_clauses, Not(P)), symbols_copy, model_copy))
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_ITE(): A, B, C = map(Boolean, symbols('A,B,C')) pytest.raises(ValueError, lambda: ITE(A, B)) 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) assert ITE(True, B, C) == B assert ITE(False, B, C) == C assert ITE(A, B, B) == B assert ITE(C, False, True) == Not(C) assert ITE(C, True, False) == C
def valid(expr): """ Check validity of a propositional sentence. A valid propositional sentence is True under every assignment. Examples ======== >>> from diofant.abc import A, B >>> from diofant.logic.inference import valid >>> valid(A | ~A) True >>> valid(A | B) False References ========== .. [1] http://en.wikipedia.org/wiki/Validity """ return not satisfiable(Not(expr))
def find_pure_symbol(symbols, unknown_clauses): """ Find a symbol and its value if it appears only as a positive literal (or only as a negative) in clauses. >>> from diofant import symbols >>> from diofant.abc import A, B, D >>> from diofant.logic.algorithms.dpll import find_pure_symbol >>> find_pure_symbol([A, B, D], [A|~B,~B|~D,D|A]) (A, True) """ for sym in symbols: found_pos, found_neg = False, False for c in unknown_clauses: if not found_pos and sym in disjuncts(c): found_pos = True if not found_neg and Not(sym) in disjuncts(c): found_neg = True if found_pos != found_neg: return sym, found_pos return None, None
def test_fcode_Logical(): # 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)"
def test_true_false(): assert true is true assert false is false assert true is not True assert false is not False assert true assert not false assert true == True # noqa: E712 assert false == False # noqa: E712 assert not (true == False) # noqa: E712 assert not (false == True) # noqa: E712 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 itertools.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
def test_fcode_Xlogical(): # binary Xor assert fcode(Xor(x, y, evaluate=False), source_format="free") == \ "x .neqv. y" assert fcode(Xor(x, Not(y), evaluate=False), source_format="free") == \ "x .neqv. .not. y" assert fcode(Xor(Not(x), y, evaluate=False), source_format="free") == \ "y .neqv. .not. x" assert fcode(Xor(Not(x), Not(y), evaluate=False), source_format="free") == ".not. x .neqv. .not. y" assert fcode(Not(Xor(x, y, evaluate=False), evaluate=False), source_format="free") == ".not. (x .neqv. y)" # binary Equivalent assert fcode(Equivalent(x, y), source_format="free") == "x .eqv. y" assert fcode(Equivalent(x, Not(y)), source_format="free") == \ "x .eqv. .not. y" assert fcode(Equivalent(Not(x), y), source_format="free") == \ "y .eqv. .not. x" assert fcode(Equivalent(Not(x), Not(y)), source_format="free") == \ ".not. x .eqv. .not. y" assert fcode(Not(Equivalent(x, y), evaluate=False), source_format="free") == ".not. (x .eqv. y)" # mixed And/Equivalent assert fcode(Equivalent(And(y, z), x), source_format="free") == \ "x .eqv. y .and. z" assert fcode(Equivalent(And(z, x), y), source_format="free") == \ "y .eqv. x .and. z" assert fcode(Equivalent(And(x, y), z), source_format="free") == \ "z .eqv. x .and. y" assert fcode(And(Equivalent(y, z), x), source_format="free") == \ "x .and. (y .eqv. z)" assert fcode(And(Equivalent(z, x), y), source_format="free") == \ "y .and. (x .eqv. z)" assert fcode(And(Equivalent(x, y), z), source_format="free") == \ "z .and. (x .eqv. y)" # mixed Or/Equivalent assert fcode(Equivalent(Or(y, z), x), source_format="free") == \ "x .eqv. y .or. z" assert fcode(Equivalent(Or(z, x), y), source_format="free") == \ "y .eqv. x .or. z" assert fcode(Equivalent(Or(x, y), z), source_format="free") == \ "z .eqv. x .or. y" assert fcode(Or(Equivalent(y, z), x), source_format="free") == \ "x .or. (y .eqv. z)" assert fcode(Or(Equivalent(z, x), y), source_format="free") == \ "y .or. (x .eqv. z)" assert fcode(Or(Equivalent(x, y), z), source_format="free") == \ "z .or. (x .eqv. y)" # mixed Xor/Equivalent assert fcode(Equivalent(Xor(y, z, evaluate=False), x), source_format="free") == "x .eqv. (y .neqv. z)" assert fcode(Equivalent(Xor(z, x, evaluate=False), y), source_format="free") == "y .eqv. (x .neqv. z)" assert fcode(Equivalent(Xor(x, y, evaluate=False), z), source_format="free") == "z .eqv. (x .neqv. y)" assert fcode(Xor(Equivalent(y, z), x, evaluate=False), source_format="free") == "x .neqv. (y .eqv. z)" assert fcode(Xor(Equivalent(z, x), y, evaluate=False), source_format="free") == "y .neqv. (x .eqv. z)" assert fcode(Xor(Equivalent(x, y), z, evaluate=False), source_format="free") == "z .neqv. (x .eqv. y)" # mixed And/Xor assert fcode(Xor(And(y, z), x, evaluate=False), source_format="free") == \ "x .neqv. y .and. z" assert fcode(Xor(And(z, x), y, evaluate=False), source_format="free") == \ "y .neqv. x .and. z" assert fcode(Xor(And(x, y), z, evaluate=False), source_format="free") == \ "z .neqv. x .and. y" assert fcode(And(Xor(y, z, evaluate=False), x), source_format="free") == \ "x .and. (y .neqv. z)" assert fcode(And(Xor(z, x, evaluate=False), y), source_format="free") == \ "y .and. (x .neqv. z)" assert fcode(And(Xor(x, y, evaluate=False), z), source_format="free") == \ "z .and. (x .neqv. y)" # mixed Or/Xor assert fcode(Xor(Or(y, z), x, evaluate=False), source_format="free") == \ "x .neqv. y .or. z" assert fcode(Xor(Or(z, x), y, evaluate=False), source_format="free") == \ "y .neqv. x .or. z" assert fcode(Xor(Or(x, y), z, evaluate=False), source_format="free") == \ "z .neqv. x .or. y" assert fcode(Or(Xor(y, z, evaluate=False), x), source_format="free") == \ "x .or. (y .neqv. z)" assert fcode(Or(Xor(z, x, evaluate=False), y), source_format="free") == \ "y .or. (x .neqv. z)" assert fcode(Or(Xor(x, y, evaluate=False), z), source_format="free") == \ "z .or. (x .neqv. y)" # trinary Xor assert fcode(Xor(x, y, z, evaluate=False), source_format="free") == \ "x .neqv. y .neqv. z" assert fcode(Xor(x, y, Not(z), evaluate=False), source_format="free") == \ "x .neqv. y .neqv. .not. z" assert fcode(Xor(x, Not(y), z, evaluate=False), source_format="free") == \ "x .neqv. z .neqv. .not. y" assert fcode(Xor(Not(x), y, z, evaluate=False), source_format="free") == \ "y .neqv. z .neqv. .not. x"
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]])) is not 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(And(x, Not(y)), Or(y, Not(x))) is False assert bool_map(And(x, Not(y)), And(y, Not(x), z)) is False assert bool_map(And(x, Not(y)), And(Or(y, z), Not(x))) is False assert bool_map(Or(And(Not(y), a), And(Not(y), b), And(x, y)), Or( x, y, a)) is False
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)) == 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)) e = And(A, x**2 - x) assert simplify_logic(e) == And(A, x * (x - 1)) assert simplify_logic(e, deep=False) == e pytest.raises(ValueError, lambda: simplify_logic(A & (B | C), form='spam')) e = x & y ^ z | (z ^ x) res = [(x & ~z) | (z & ~x) | (z & ~y), (x & ~y) | (x & ~z) | (z & ~x)] assert simplify_logic(e) in res assert SOPform( [z, y, x], [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0]]) == res[1] # check input ans = SOPform([x, y], [[1, 0]]) assert SOPform([x, y], [[1, 0]]) == ans assert POSform([x, y], [[1, 0]]) == ans pytest.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 pytest.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))) is false assert simplify(Or(x, Not(x))) is true