def ask(proposition, assumptions=True, context=global_assumptions): """ Method for inferring properties about objects. **Syntax** * ask(proposition) * ask(proposition, assumptions) where ``proposition`` is any boolean expression Examples ======== >>> from sympy import ask, Q, pi >>> from sympy.abc import x, y >>> ask(Q.rational(pi)) False >>> ask(Q.even(x*y), Q.even(x) & Q.integer(y)) True >>> ask(Q.prime(4*x), Q.integer(x)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >>> ask(Q.positive(x), Q.is_true(x > 0)) It is however a work in progress. """ from sympy.assumptions.satask import satask if not isinstance(proposition, (BooleanFunction, AppliedPredicate, bool, BooleanAtom)): raise TypeError("proposition must be a valid logical expression") if not isinstance(assumptions, (BooleanFunction, AppliedPredicate, bool, BooleanAtom)): raise TypeError("assumptions must be a valid logical expression") if isinstance(proposition, AppliedPredicate): key, expr = proposition.func, sympify(proposition.arg) else: key, expr = Q.is_true, sympify(proposition) assump = CNF.from_prop(assumptions) assump.extend(context) local_facts = _extract_all_facts(assump, expr) known_facts_cnf = get_all_known_facts() known_facts_dict = get_known_facts_dict() enc_cnf = EncodedCNF() enc_cnf.from_cnf(CNF(known_facts_cnf)) enc_cnf.add_from_cnf(local_facts) if local_facts.clauses and satisfiable(enc_cnf) is False: raise ValueError("inconsistent assumptions %s" % assumptions) if local_facts.clauses: if len(local_facts.clauses) == 1: cl, = local_facts.clauses f, = cl if len(cl) == 1 else [None] if f and f.is_Not and f.arg in known_facts_dict.get(key, []): return False for clause in local_facts.clauses: if len(clause) == 1: f, = clause fdict = known_facts_dict.get(f.arg, None) if not f.is_Not else None if fdict and key in fdict: return True if fdict and Not(key) in known_facts_dict[f.arg]: return False # direct resolution method, no logic res = key(expr)._eval_ask(assumptions) if res is not None: return bool(res) # using satask (still costly) res = satask(proposition, assumptions=assumptions, context=context) return res
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)"
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) minterms = [1, 3, 7, 11, 15] dontcares = [0, 2, 5] 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) 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(Not(w), z), And(y, z)) 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(Not(w), z), And(y, z)) 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")) # 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 # 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 ask(proposition, assumptions=True, context=global_assumptions): """ Method for inferring properties about objects. **Syntax** * ask(proposition) * ask(proposition, assumptions) where ``proposition`` is any boolean expression Examples ======== >>> from sympy import ask, Q, pi >>> from sympy.abc import x, y >>> ask(Q.rational(pi)) False >>> ask(Q.even(x*y), Q.even(x) & Q.integer(y)) True >>> ask(Q.prime(x*y), Q.integer(x) & Q.integer(y)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >>> ask(Q.positive(x), Q.is_true(x > 0)) # doctest: +SKIP It is however a work in progress and should be available before the official release """ assumptions = And(assumptions, And(*context)) if isinstance(proposition, AppliedPredicate): key, expr = proposition.func, sympify(proposition.arg) else: key, expr = Q.is_true, sympify(proposition) # direct resolution method, no logic res = key(expr)._eval_ask(assumptions) if res is not None: return res if assumptions is True: return if not expr.is_Atom: return local_facts = _extract_facts(assumptions, expr) if local_facts is None or local_facts is True: return # See if there's a straight-forward conclusion we can make for the inference if local_facts.is_Atom: if key in known_facts_dict[local_facts]: return True if Not(key) in known_facts_dict[local_facts]: return False elif local_facts.func is And and all(k in known_facts_dict for k in local_facts.args): for assum in local_facts.args: if assum.is_Atom: if key in known_facts_dict[assum]: return True if Not(key) in known_facts_dict[assum]: return False elif assum.func is Not and assum.args[0].is_Atom: if key in known_facts_dict[assum]: return False if Not(key) in known_facts_dict[assum]: return True elif (isinstance(key, Predicate) and local_facts.func is Not and local_facts.args[0].is_Atom): if local_facts.args[0] in known_facts_dict[key]: return False # Failing all else, we do a full logical inference return ask_full_inference(key, local_facts)
def test_rubi_printer(): #14819 a = Symbol('a') assert rubi_printer(Not(a)) == 'Not(a)'
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 ask(proposition, assumptions=True, context=global_assumptions): """ Function to evaluate the proposition with assumptions. **Syntax** * ask(proposition) Evaluate the *proposition* in global assumption context. * ask(proposition, assumptions) Evaluate the *proposition* with respect to *assumptions* in global assumption context. This function evaluates the proposition to ``True`` or ``False`` if the truth value can be determined. If not, it returns ``None``. It should be discerned from :func:`~.refine()` which does not reduce the expression to ``None``. Parameters ========== proposition : any boolean expression Proposition which will be evaluated to boolean value. If this is not ``AppliedPredicate``, it will be wrapped by ``Q.is_true``. assumptions : any boolean expression, optional Local assumptions to evaluate the *proposition*. context : AssumptionsContext, optional Default assumptions to evaluate the *proposition*. By default, this is ``sympy.assumptions.global_assumptions`` variable. Examples ======== >>> from sympy import ask, Q, pi >>> from sympy.abc import x, y >>> ask(Q.rational(pi)) False >>> ask(Q.even(x*y), Q.even(x) & Q.integer(y)) True >>> ask(Q.prime(4*x), Q.integer(x)) False If the truth value cannot be determined, ``None`` will be returned. >>> print(ask(Q.odd(3*x))) # cannot determine unless we know x None **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >>> ask(Q.positive(x), Q.is_true(x > 0)) It is however a work in progress. See Also ======== sympy.assumptions.refine.refine : Simplification using assumptions. Proposition is not reduced to ``None`` if the truth value cannot be determined. """ from sympy.assumptions.satask import satask proposition = sympify(proposition) assumptions = sympify(assumptions) if isinstance(proposition, Predicate) or proposition.kind is not BooleanKind: raise TypeError("proposition must be a valid logical expression") if isinstance(assumptions, Predicate) or assumptions.kind is not BooleanKind: raise TypeError("assumptions must be a valid logical expression") if isinstance(proposition, AppliedPredicate): key, args = proposition.function, proposition.arguments else: key, args = Q.is_true, (proposition, ) assump = CNF.from_prop(assumptions) assump.extend(context) local_facts = _extract_all_facts(assump, args) known_facts_cnf = get_all_known_facts() known_facts_dict = get_known_facts_dict() enc_cnf = EncodedCNF() enc_cnf.from_cnf(CNF(known_facts_cnf)) enc_cnf.add_from_cnf(local_facts) if local_facts.clauses and satisfiable(enc_cnf) is False: raise ValueError("inconsistent assumptions %s" % assumptions) if local_facts.clauses: if len(local_facts.clauses) == 1: cl, = local_facts.clauses f, = cl if len(cl) == 1 else [None] if f and f.is_Not and f.arg in known_facts_dict.get(key, []): return False for clause in local_facts.clauses: if len(clause) == 1: f, = clause fdict = known_facts_dict.get(f.arg, None) if not f.is_Not else None if fdict and key in fdict: return True if fdict and Not(key) in known_facts_dict[f.arg]: return False # direct resolution method, no logic res = key(*args)._eval_ask(assumptions) if res is not None: return bool(res) # using satask (still costly) res = satask(proposition, assumptions=assumptions, context=context) return res
def test_sympy__logic__boolalg__Not(): from sympy.logic.boolalg import Not assert _test_args(Not(2))
""" The contents of this file are the return value of ``sympy.assumptions.ask.compute_known_facts``. Do NOT manually edit this file. """ from sympy.logic.boolalg import And, Not, Or from sympy.assumptions.ask import Q # -{ Known facts in CNF }- known_facts_cnf = And( Or(Not(Q.imaginary), Q.antihermitian), Or(Not(Q.imaginary), Q.complex), Or(Not(Q.real), Q.complex), Or(Not(Q.infinity), Q.extended_real), Or(Not(Q.real), Q.extended_real), Or(Not(Q.real), Q.hermitian), Or(Not(Q.even), Q.integer), Or(Not(Q.odd), Q.integer), Or(Not(Q.prime), Q.integer), Or(Not(Q.positive_definite), Q.invertible), Or(Not(Q.diagonal), Q.lower_triangular), Or(Not(Q.negative), Q.nonzero), Or(Not(Q.positive), Q.nonzero), Or(Not(Q.prime), Q.positive), Or(Not(Q.orthogonal), Q.positive_definite), Or(Not(Q.integer), Q.rational), Or(Not(Q.irrational), Q.real), Or(Not(Q.nonzero), Q.real), Or(Not(Q.rational), Q.real), Or(Not(Q.diagonal), Q.upper_triangular), Or(Not(Q.antihermitian), Not(Q.hermitian)), Or(Not(Q.composite), Not(Q.prime)), Or(Not(Q.even), Not(Q.odd)), Or(Not(Q.imaginary), Not(Q.real)), Or(Not(Q.irrational), Not(Q.rational)), Or(Not(Q.negative), Not(Q.positive)), Or(Not(Q.integer), Q.even, Q.odd), Or(Not(Q.extended_real), Q.infinity, Q.real), Or(Not(Q.real), Q.irrational, Q.rational), Or(Not(Q.nonzero), Q.negative, Q.positive), Or(Not(Q.integer), Not(Q.positive), Q.composite, Q.prime)) # -{ Known facts in compressed sets }-
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 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 NOTTING(b): return move_not_inwards(Not(b))
def pl_true(expr, model={}): """ Return True if the propositional logic expression is true in the model, and False if it is false. If the model does not specify the value for every proposition, this may return None to indicate 'not obvious'; this may happen even when the expression is tautological. The model is implemented as a dict containing the pair symbol, boolean value. Examples ======== >>> from sympy.abc import A, B >>> from sympy.logic.inference import pl_true >>> pl_true( A & B, {A: True, B : True}) True """ if isinstance(expr, bool): return expr expr = sympify(expr) if expr.is_Symbol: return model.get(expr) args = expr.args func = expr.func if func is Not: p = pl_true(args[0], model) if p is None: return None else: return not p elif func is Or: result = False for arg in args: p = pl_true(arg, model) if p is True: return True if p is None: result = None return result elif func is And: result = True for arg in args: p = pl_true(arg, model) if p is False: return False if p is None: result = None return result elif func is Implies: p, q = args return pl_true(Or(Not(p), q), model) elif func is Equivalent: p, q = args pt = pl_true(p, model) if pt is None: return None qt = pl_true(q, model) if qt is None: return None return pt == qt else: raise ValueError("Illegal operator in logic expression" + str(expr))
def get_known_facts_cnf(): return And( Or(Q.invertible, Q.singular), Or(Not(Q.rational), Q.algebraic), Or(Not(Q.imaginary), Q.antihermitian), Or(Not(Q.algebraic), Q.complex), Or(Not(Q.imaginary), Q.complex), Or(Not(Q.real), Q.complex), Or(Not(Q.transcendental), Q.complex), Or(Not(Q.real_elements), Q.complex_elements), Or(Not(Q.zero), Q.even), Or(Not(Q.infinite), Q.extended_real), Or(Not(Q.real), Q.extended_real), Or(Not(Q.invertible), Q.fullrank), Or(Not(Q.real), Q.hermitian), Or(Not(Q.even), Q.integer), Or(Not(Q.odd), Q.integer), Or(Not(Q.prime), Q.integer), Or(Not(Q.positive_definite), Q.invertible), Or(Not(Q.unitary), Q.invertible), Or(Not(Q.diagonal), Q.lower_triangular), Or(Not(Q.negative), Q.nonzero), Or(Not(Q.positive), Q.nonzero), Or(Not(Q.diagonal), Q.normal), Or(Not(Q.unitary), Q.normal), Or(Not(Q.prime), Q.positive), Or(Not(Q.orthogonal), Q.positive_definite), Or(Not(Q.integer), Q.rational), Or(Not(Q.irrational), Q.real), Or(Not(Q.nonnegative), Q.real), Or(Not(Q.nonpositive), Q.real), Or(Not(Q.nonzero), Q.real), Or(Not(Q.rational), Q.real), Or(Not(Q.zero), Q.real), Or(Not(Q.integer_elements), Q.real_elements), Or(Not(Q.invertible), Q.square), Or(Not(Q.normal), Q.square), Or(Not(Q.symmetric), Q.square), Or(Not(Q.diagonal), Q.symmetric), Or(Not(Q.lower_triangular), Q.triangular), Or(Not(Q.unit_triangular), Q.triangular), Or(Not(Q.upper_triangular), Q.triangular), Or(Not(Q.orthogonal), Q.unitary), Or(Not(Q.diagonal), Q.upper_triangular), Or(Not(Q.algebraic), Not(Q.transcendental)), Or(Not(Q.antihermitian), Not(Q.hermitian)), Or(Not(Q.composite), Not(Q.prime)), Or(Not(Q.even), Not(Q.odd)), Or(Not(Q.finite), Not(Q.infinite)), Or(Not(Q.imaginary), Not(Q.real)), Or(Not(Q.invertible), Not(Q.singular)), Or(Not(Q.irrational), Not(Q.rational)), Or(Not(Q.negative), Not(Q.nonnegative)), Or(Not(Q.negative), Not(Q.positive)), Or(Not(Q.nonpositive), Not(Q.positive)), Or(Not(Q.nonzero), Not(Q.zero)), Or(Not(Q.complex), Q.algebraic, Q.transcendental), Or(Not(Q.integer), Q.even, Q.odd), Or(Not(Q.extended_real), Q.infinite, Q.real), Or(Not(Q.real), Q.irrational, Q.rational), Or(Not(Q.triangular), Q.lower_triangular, Q.upper_triangular), Or(Not(Q.real), Q.negative, Q.nonnegative), Or(Not(Q.nonzero), Q.negative, Q.positive), Or(Not(Q.real), Q.nonpositive, Q.positive), Or(Not(Q.real), Q.nonzero, Q.zero), Or(Not(Q.lower_triangular), Not(Q.upper_triangular), Q.diagonal), Or(Not(Q.fullrank), Not(Q.square), Q.invertible), Or(Not(Q.real), Not(Q.unitary), Q.orthogonal), Or(Not(Q.integer), Not(Q.positive), Q.composite, Q.prime))
def syntestbench(s, numlit, numclause): numlit = int(numlit) numclause = int(numclause) print("--ANSWER TO THIS TEST BENCH") print("--", end="") print(satisfiable(s)) s = to_cnf(sympify(s)) symbols = sorted(_find_predicates(s), key=default_sort_key) symbols_int_repr = set(range(0, len(symbols))) to_print = [] if s.func != And: s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) if s.func != Or: if s.is_Symbol: s1[symbols.index(s)] = 1 to_print.append(s1) to_print.append(s2) else: s2[symbols.index(Not(s))] = 1 to_print.append(s1) to_print.append(s2) else: for arg in s.args: if arg.is_Symbol: s1[symbols.index(arg)] = 1 else: s2[symbols.index(Not(arg))] = 1 to_print.append(s1) to_print.append(s2) else: clauses = s.args for clause in clauses: s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) if clause.func != Or: if clause.is_Symbol: s1[symbols.index(clause)] = 1 to_print.append(s1) to_print.append(s2) else: s2[symbols.index(Not(clause))] = 1 to_print.append(s1) to_print.append(s2) else: for arg in clause.args: if arg.is_Symbol: s1[symbols.index(arg)] = 1 else: s2[symbols.index(Not(arg))] = 1 to_print.append(s1) to_print.append(s2) if (numclause > len(to_print) / 2): s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) for i in range(numclause - int(len(to_print) / 2)): to_print.append(s1) to_print.append(s2) return to_print
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_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
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 generate_initial_beliefs(): """Example premises is from exercises from lecture 9""" p, q, s, r = symbols("p q s r") return [Implies(Not(p), q), Implies(q, p), Implies(p, And(r, s))]
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 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 do_agm(self, line): 'Test the KB on AGM postulates with a phi and a psi. Split with "-". Example: "agm p>>q - q | p"' if not line: self.do_help('agm') return #Save KB line = line.split("-") try: if len(line) == 1: phi = to_cnf(sympify(line[0])) psi = False elif len(line) == 2: phi = to_cnf(sympify(line[0])) psi = to_cnf(sympify(line[1])) else: print("More than two inputs") except ValueError as exc: print(exc) return pickle.dump(self.kb, open("temp.pickle", "wb")) notphi = to_cnf(Not(phi)) baseline = self.kb.fetch_premises() appended = baseline + [phi] self.kb.revise(phi) revised = self.kb.fetch_premises() #print(baseline) #print(appended) #print(revised) #Closure print("Closure: False") #Success print(f'Success: {phi in revised}') #Inclusion print(f'Inclusion: {set(revised).issubset(set(appended))}') #Vacuity if notphi in baseline: print('Vacuity: Can not be determined since phi negated in B') else: print(f'Vacuity: {set(revised)==set(appended)}') #Consistency if PL_resolution([], phi): print(f"Consistency: {PL_resolution([],revised)}") else: print( "Consistency: Can not be determined since phi isn't consistent" ) if psi: self.kb = pickle.load(open("temp.pickle", "rb")) self.kb.revise(psi) revised_psi = self.kb.fetch_premises() appended_psi = revised + [psi] self.kb = pickle.load(open("temp.pickle", "rb")) self.kb.revise(And(phi, psi)) revised_phi_psi = self.kb.fetch_premises() notpsi = to_cnf(Not(psi)) #Extensionality if (not PL_resolution([], Not(Biconditional( phi, psi)))) or Biconditional(phi, psi) == True: print(f'Extensionality: {set(revised)==set(revised_psi)}') else: print( "Extensionality: Can not be determined since (phi <-> psi) is not a tautologi" ) #Superexpansion print( f"Superexpansion: {set(revised_phi_psi).issubset(set(appended_psi))}" ) #Subexpansion if notpsi in revised: print( f"Subexpansion: {set(appended_psi).issubset(set(revised_phi_psi))}" ) else: print( 'Subexpansion: Can not be determined since psi negated in B*phi' ) else: print("No psi given for last 3 postulates") #Load the prior KB self.kb = pickle.load(open("temp.pickle", "rb")) #Cleanup temp file os.remove("temp.pickle")
Implies(Q.imaginary, Q.complex & ~Q.real), Implies(Q.imaginary, Q.antihermitian), Implies(Q.antihermitian, ~Q.hermitian), Equivalent(Q.negative, Q.nonzero & ~Q.positive), Equivalent(Q.positive, Q.nonzero & ~Q.negative), Equivalent(Q.rational, Q.real & ~Q.irrational), Equivalent(Q.real, Q.rational | Q.irrational), Implies(Q.nonzero, Q.real), Equivalent(Q.nonzero, Q.positive | Q.negative)) ################################################################################ # Note: The following facts are generated by the compute_known_facts function. # ################################################################################ # -{ Known facts in CNF }- known_facts_cnf = And( Or(Not(Q.integer), Q.even, Q.odd), Or(Not(Q.extended_real), Q.real, Q.infinity), Or(Not(Q.real), Q.irrational, Q.rational), Or(Not(Q.real), Q.complex), Or(Not(Q.integer), Not(Q.positive), Q.prime, Q.composite), Or(Not(Q.imaginary), Q.antihermitian), Or(Not(Q.integer), Q.rational), Or(Not(Q.real), Q.hermitian), Or(Not(Q.imaginary), Q.complex), Or(Not(Q.even), Q.integer), Or(Not(Q.positive), Q.nonzero), Or(Not(Q.nonzero), Q.negative, Q.positive), Or(Not(Q.prime), Q.positive), Or(Not(Q.rational), Q.real), Or(Not(Q.real), Not(Q.imaginary)), Or(Not(Q.odd), Q.integer), Or(Not(Q.real), Q.extended_real), Or(Not(Q.composite), Not(Q.prime)), Or(Not(Q.negative), Q.nonzero), Or(Not(Q.positive), Not(Q.negative)), Or(Not(Q.prime), Q.integer), Or(Not(Q.even), Not(Q.odd)), Or(Not(Q.nonzero), Q.real), Or(Not(Q.irrational), Q.real), Or(Not(Q.rational), Not(Q.irrational)), Or(Not(Q.infinity), Q.extended_real), Or(Not(Q.antihermitian), Not(Q.hermitian)))
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))
def negated(self): neg_rel = self.function.negated if neg_rel is None: return Not(self, evaluate=False) return neg_rel(*self.arguments)
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([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 # 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
def remove_literal(arg): return Not(arg.lit) if arg.is_Not else arg.lit
def ask(proposition, assumptions=True, context=global_assumptions): """ Method for inferring properties about objects. **Syntax** * ask(proposition) * ask(proposition, assumptions) where ``proposition`` is any boolean expression Examples ======== >>> from sympy import ask, Q, pi >>> from sympy.abc import x, y >>> ask(Q.rational(pi)) False >>> ask(Q.even(x*y), Q.even(x) & Q.integer(y)) True >>> ask(Q.prime(4*x), Q.integer(x)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >>> ask(Q.positive(x), Q.is_true(x > 0)) # doctest: +SKIP It is however a work in progress. """ from sympy.assumptions.satask import satask if not isinstance(proposition, (BooleanFunction, AppliedPredicate, bool, BooleanAtom)): raise TypeError("proposition must be a valid logical expression") if not isinstance(assumptions, (BooleanFunction, AppliedPredicate, bool, BooleanAtom)): raise TypeError("assumptions must be a valid logical expression") if isinstance(proposition, AppliedPredicate): key, expr = proposition.func, sympify(proposition.arg) else: key, expr = Q.is_true, sympify(proposition) assumptions = And(assumptions, And(*context)) assumptions = to_cnf(assumptions) local_facts = _extract_facts(assumptions, expr) known_facts_cnf = get_known_facts_cnf() known_facts_dict = get_known_facts_dict() if local_facts and satisfiable(And(local_facts, known_facts_cnf)) is False: raise ValueError("inconsistent assumptions %s" % assumptions) # direct resolution method, no logic res = key(expr)._eval_ask(assumptions) if res is not None: return bool(res) if local_facts is None: return satask(proposition, assumptions=assumptions, context=context) # See if there's a straight-forward conclusion we can make for the inference if local_facts.is_Atom: if key in known_facts_dict[local_facts]: return True if Not(key) in known_facts_dict[local_facts]: return False elif (isinstance(local_facts, And) and all(k in known_facts_dict for k in local_facts.args)): for assum in local_facts.args: if assum.is_Atom: if key in known_facts_dict[assum]: return True if Not(key) in known_facts_dict[assum]: return False elif isinstance(assum, Not) and assum.args[0].is_Atom: if key in known_facts_dict[assum]: return False if Not(key) in known_facts_dict[assum]: return True elif (isinstance(key, Predicate) and isinstance(local_facts, Not) and local_facts.args[0].is_Atom): if local_facts.args[0] in known_facts_dict[key]: return False # Failing all else, we do a full logical inference res = ask_full_inference(key, local_facts, known_facts_cnf) if res is None: return satask(proposition, assumptions=assumptions, context=context) return res
def test_fcode_Xlogical(): x, y, z = symbols("x y z") # 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_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_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_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))) # 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