def get_all_relevant_facts(proposition, assumptions=True, context=global_assumptions, use_known_facts=True, iterations=oo): # The relevant facts might introduce new keys, e.g., Q.zero(x*y) will # introduce the keys Q.zero(x) and Q.zero(y), so we need to run it until # we stop getting new things. Hopefully this strategy won't lead to an # infinite loop in the future. i = 0 relevant_facts = set() exprs = None while exprs != set(): (relevant_facts, exprs) = get_relevant_facts(proposition, And.make_args(assumptions), context, use_known_facts=use_known_facts, exprs=exprs, relevant_facts=relevant_facts) i += 1 if i >= iterations: return And(*relevant_facts) return And(*relevant_facts)
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_sympy__logic__boolalg__And(): from sympy.logic.boolalg import And assert _test_args(And(x, y, 2))
def as_relational(self, other): return And( Lambda(self.sym, self.condition)(other), self.base_set.contains(other))
def __new__(cls, sym, condition, base_set=S.UniversalSet): # nonlinsolve uses ConditionSet to return an unsolved system # of equations (see _return_conditionset in solveset) so until # that is changed we do minimal checking of the args sym = _sympify(sym) base_set = _sympify(base_set) condition = _sympify(condition) if isinstance(condition, FiniteSet): condition_orig = condition temp = (Eq(lhs, 0) for lhs in condition) condition = And(*temp) SymPyDeprecationWarning( feature="Using {} for condition".format(condition_orig), issue=17651, deprecated_since_version='1.5', useinstead="{} for condition".format(condition)).warn() condition = as_Boolean(condition) if isinstance(sym, Tuple): # unsolved eqns syntax return Basic.__new__(cls, sym, condition, base_set) if not isinstance(base_set, Set): raise TypeError('expecting set for base_set') if condition is S.false: return S.EmptySet elif condition is S.true: return base_set if isinstance(base_set, EmptySet): return base_set know = None if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: know = FiniteSet(*sifted[True]) base_set = FiniteSet(*sifted[None]) else: return FiniteSet(*sifted[True]) if isinstance(base_set, cls): s, c, base_set = base_set.args if sym == s: condition = And(condition, c) elif sym not in c.free_symbols: condition = And(condition, c.xreplace({s: sym})) elif s not in condition.free_symbols: condition = And(condition.xreplace({sym: s}), c) sym = s else: # user will have to use cls.sym to get symbol dum = Symbol('lambda') if dum in condition.free_symbols or \ dum in c.free_symbols: dum = Dummy(str(dum)) condition = And(condition.xreplace({sym: dum}), c.xreplace({s: dum})) sym = dum if not isinstance(sym, Symbol): s = Dummy('lambda') if s not in condition.xreplace({sym: s}).free_symbols: raise ValueError( 'non-symbol dummy not recognized in condition') rv = Basic.__new__(cls, sym, condition, base_set) return rv if know is None else Union(know, rv)
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_BooleanFunction_diff(): assert And(x, y).diff(x) == Piecewise((0, Eq(y, False)), (1, True))
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 to_NNF(expr): """ Generates the Negation Normal Form of any boolean expression in terms of AND, OR, and Literal objects. """ if isinstance(expr, Not): arg = expr.args[0] tmp = to_NNF(arg) # Strategy: negate the NNF of expr return ~tmp if isinstance(expr, Or): return OR(*[to_NNF(x) for x in Or.make_args(expr)]) if isinstance(expr, And): return AND(*[to_NNF(x) for x in And.make_args(expr)]) if isinstance(expr, Nand): tmp = AND(*[to_NNF(x) for x in expr.args]) return ~tmp if isinstance(expr, Nor): tmp = OR(*[to_NNF(x) for x in expr.args]) return ~tmp if isinstance(expr, Xor): cnfs = [] for i in range(0, len(expr.args) + 1, 2): for neg in combinations(expr.args, i): clause = [ ~to_NNF(s) if s in neg else to_NNF(s) for s in expr.args ] cnfs.append(OR(*clause)) return AND(*cnfs) if isinstance(expr, Xnor): cnfs = [] for i in range(0, len(expr.args) + 1, 2): for neg in combinations(expr.args, i): clause = [ ~to_NNF(s) if s in neg else to_NNF(s) for s in expr.args ] cnfs.append(OR(*clause)) return ~AND(*cnfs) if isinstance(expr, Implies): L, R = to_NNF(expr.args[0]), to_NNF(expr.args[1]) return OR(~L, R) if isinstance(expr, Equivalent): cnfs = [] for a, b in zip_longest(expr.args, expr.args[1:], fillvalue=expr.args[0]): a = to_NNF(a) b = to_NNF(b) cnfs.append(OR(~a, b)) return AND(*cnfs) if isinstance(expr, ITE): L = to_NNF(expr.args[0]) M = to_NNF(expr.args[1]) R = to_NNF(expr.args[2]) return AND(OR(~L, M), OR(L, R)) else: return Literal(expr)
def _eval_interval(self, sym, a, b): """Evaluates the function along the sym in a given interval ab""" # FIXME: Currently complex intervals are not supported. A possible # replacement algorithm, discussed in issue 2128, can be found in the # following papers; # http://portal.acm.org/citation.cfm?id=281649 # http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.70.4127&rep=rep1&type=pdf if a is None or b is None: # In this case, it is just simple substitution return piecewise_fold( super(Piecewise, self)._eval_interval(sym, a, b)) mul = 1 if (a == b) is True: return S.Zero elif (a > b) is True: a, b, mul = b, a, -1 elif (a <= b) is not True: newargs = [] for e, c in self.args: intervals = self._sort_expr_cond(sym, S.NegativeInfinity, S.Infinity, c) values = [] for lower, upper, expr in intervals: if (a < lower) is True: mid = lower rep = b val = e._eval_interval(sym, mid, b) val += self._eval_interval(sym, a, mid) elif (a > upper) is True: mid = upper rep = b val = e._eval_interval(sym, mid, b) val += self._eval_interval(sym, a, mid) elif (a >= lower) is True and (a <= upper) is True: rep = b val = e._eval_interval(sym, a, b) elif (b < lower) is True: mid = lower rep = a val = e._eval_interval(sym, a, mid) val += self._eval_interval(sym, mid, b) elif (b > upper) is True: mid = upper rep = a val = e._eval_interval(sym, a, mid) val += self._eval_interval(sym, mid, b) elif ((b >= lower) is True) and ((b <= upper) is True): rep = a val = e._eval_interval(sym, a, b) else: raise NotImplementedError( """The evaluation of a Piecewise interval when both the lower and the upper limit are symbolic is not yet implemented.""" ) values.append(val) if len(set(values)) == 1: try: c = c.subs(sym, rep) except AttributeError: pass e = values[0] newargs.append((e, c)) else: for i in range(len(values)): newargs.append( (values[i], (c is True and i == len(values) - 1) or And(rep >= intervals[i][0], rep <= intervals[i][1]))) return self.func(*newargs) # Determine what intervals the expr,cond pairs affect. int_expr = self._sort_expr_cond(sym, a, b) # Finally run through the intervals and sum the evaluation. ret_fun = 0 for int_a, int_b, expr in int_expr: if isinstance(expr, Piecewise): # If we still have a Piecewise by now, _sort_expr_cond would # already have determined that its conditions are independent # of the integration variable, thus we just use substitution. ret_fun += piecewise_fold( super(Piecewise, expr)._eval_interval(sym, Max(a, int_a), Min(b, int_b))) else: ret_fun += expr._eval_interval(sym, Max(a, int_a), Min(b, int_b)) return mul * ret_fun
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 (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 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_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_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_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(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')) # 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 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_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 _contains(self, other): from sympy.logic.boolalg import And return And(*[set.contains(other) for set in self.args])
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]
def as_relational(self, symbol): """Rewrite an Intersection in terms of equalities and logic operators""" return And(*[set.as_relational(symbol) for set in self.args])
import pprint import re from copy import deepcopy from PLA_functions import * _input = {"(~(a & b))", "(a|b)", "a", "b"} a, b, c, d, p, q, r = symbols("a, b, c, d, p, q, r") props = {a, b, c, d} form1 = (~(a & d) | (b & c)) form2 = a | b | d res = And(form1, form2) res = to_cnf(res) print(res) regular = pre_cnf_to_cnf(res, props) print(regular) flist = build_formula_list(_input) print("f list") for f in flist: print(f) basis = build_res_set(flist, props) print("f set") for s in basis:
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_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_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 _contains(self, other): return And(Contains(other, self.base_set), Lambda(self.sym, self.condition)(other))
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(l, le)
def _handle_irel(self, x, handler): """Return either None (if the conditions of self depend only on x) else a Piecewise expression whose expressions (handled by the handler that was passed) are paired with the governing x-independent relationals, e.g. Piecewise((A, a(x) & b(y)), (B, c(x) | c(y)) -> Piecewise( (handler(Piecewise((A, a(x) & True), (B, c(x) | True)), b(y) & c(y)), (handler(Piecewise((A, a(x) & True), (B, c(x) | False)), b(y)), (handler(Piecewise((A, a(x) & False), (B, c(x) | True)), c(y)), (handler(Piecewise((A, a(x) & False), (B, c(x) | False)), True)) """ # identify governing relationals rel = self.atoms(Relational) irel = list(ordered([r for r in rel if x not in r.free_symbols and r not in (S.true, S.false)])) if irel: args = {} exprinorder = [] for truth in product((1, 0), repeat=len(irel)): reps = dict(zip(irel, truth)) # only store the true conditions since the false are implied # when they appear lower in the Piecewise args if 1 not in truth: cond = None # flag this one so it doesn't get combined else: andargs = Tuple(*[i for i in reps if reps[i]]) free = list(andargs.free_symbols) if len(free) == 1: from sympy.solvers.inequalities import ( reduce_inequalities, _solve_inequality) try: t = reduce_inequalities(andargs, free[0]) # ValueError when there are potentially # nonvanishing imaginary parts except (ValueError, NotImplementedError): # at least isolate free symbol on left t = And(*[_solve_inequality( a, free[0], linear=True) for a in andargs]) else: t = And(*andargs) if t is S.false: continue # an impossible combination cond = t expr = handler(self.xreplace(reps)) if isinstance(expr, self.func) and len(expr.args) == 1: expr, econd = expr.args[0] cond = And(econd, True if cond is None else cond) # the ec pairs are being collected since all possibilities # are being enumerated, but don't put the last one in since # its expr might match a previous expression and it # must appear last in the args if cond is not None: args.setdefault(expr, []).append(cond) # but since we only store the true conditions we must maintain # the order so that the expression with the most true values # comes first exprinorder.append(expr) # convert collected conditions as args of Or for k in args: args[k] = Or(*args[k]) # take them in the order obtained args = [(e, args[e]) for e in uniq(exprinorder)] # add in the last arg args.append((expr, True)) # if any condition reduced to True, it needs to go last # and there should only be one of them or else the exprs # should agree trues = [i for i in range(len(args)) if args[i][1] is S.true] if not trues: # make the last one True since all cases were enumerated e, c = args[-1] args[-1] = (e, S.true) else: assert len(set([e for e, c in [args[i] for i in trues]])) == 1 args.append(args.pop(trues.pop())) while trues: args.pop(trues.pop()) return Piecewise(*args)
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))
'algebraic': ['sympy.assumptions.handlers.sets.AskAlgebraicHandler'], 'is_true': ['sympy.assumptions.handlers.TautologicalHandler'] } for name, value in _handlers_dict.iteritems(): register_handler(name, value[0]) known_facts_keys = [getattr(Q, attr) for attr in Q.__dict__ \ if not attr.startswith('__')] known_facts = And(Implies(Q.real, Q.complex), Equivalent(Q.even, Q.integer & ~Q.odd), Equivalent(Q.extended_real, Q.real | Q.infinity), Equivalent(Q.odd, Q.integer & ~Q.even), Equivalent(Q.prime, Q.integer & Q.positive & ~Q.composite), Implies(Q.integer, Q.rational), Implies(Q.imaginary, Q.complex & ~Q.real), 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.infinity, Q.real), Or(Not(Q.real), Q.irrational, Q.rational), Or(Not(Q.real), Q.complex),
def test_true_false(): assert true is S.true assert false is S.false assert true is not True assert false is not False assert true assert not false assert true == True assert false == False assert not (true == False) assert not (false == True) assert not (true == false) assert hash(true) == hash(True) assert hash(false) == hash(False) assert len({true, True}) == len({false, False}) == 1 assert isinstance(true, BooleanAtom) assert isinstance(false, BooleanAtom) # We don't want to subclass from bool, because bool subclasses from # int. But operators like &, |, ^, <<, >>, and ~ act differently on 0 and # 1 then we want them to on true and false. See the docstrings of the # various And, Or, etc. functions for examples. assert not isinstance(true, bool) assert not isinstance(false, bool) # Note: using 'is' comparison is important here. We want these to return # true and false, not True and False assert Not(true) is false assert Not(True) is false assert Not(false) is true assert Not(False) is true assert ~true is false assert ~false is true for T, F in cartes([True, true], [False, false]): assert And(T, F) is false assert And(F, T) is false assert And(F, F) is false assert And(T, T) is true assert And(T, x) == x assert And(F, x) is false if not (T is True and F is False): assert T & F is false assert F & T is false if not F is False: assert F & F is false if not T is True: assert T & T is true assert Or(T, F) is true assert Or(F, T) is true assert Or(F, F) is false assert Or(T, T) is true assert Or(T, x) is true assert Or(F, x) == x if not (T is True and F is False): assert T | F is true assert F | T is true if not F is False: assert F | F is false if not T is True: assert T | T is true assert Xor(T, F) is true assert Xor(F, T) is true assert Xor(F, F) is false assert Xor(T, T) is false assert Xor(T, x) == ~x assert Xor(F, x) == x if not (T is True and F is False): assert T ^ F is true assert F ^ T is true if not F is False: assert F ^ F is false if not T is True: assert T ^ T is false assert Nand(T, F) is true assert Nand(F, T) is true assert Nand(F, F) is true assert Nand(T, T) is false assert Nand(T, x) == ~x assert Nand(F, x) is true assert Nor(T, F) is false assert Nor(F, T) is false assert Nor(F, F) is true assert Nor(T, T) is false assert Nor(T, x) is false assert Nor(F, x) == ~x assert Implies(T, F) is false assert Implies(F, T) is true assert Implies(F, F) is true assert Implies(T, T) is true assert Implies(T, x) == x assert Implies(F, x) is true assert Implies(x, T) is true assert Implies(x, F) == ~x if not (T is True and F is False): assert T >> F is false assert F << T is false assert F >> T is true assert T << F is true if not F is False: assert F >> F is true assert F << F is true if not T is True: assert T >> T is true assert T << T is true assert Equivalent(T, F) is false assert Equivalent(F, T) is false assert Equivalent(F, F) is true assert Equivalent(T, T) is true assert Equivalent(T, x) == x assert Equivalent(F, x) == ~x assert Equivalent(x, T) == x assert Equivalent(x, F) == ~x assert ITE(T, T, T) is true assert ITE(T, T, F) is true assert ITE(T, F, T) is false assert ITE(T, F, F) is false assert ITE(F, T, T) is true assert ITE(F, T, F) is false assert ITE(F, F, T) is true assert ITE(F, F, F) is false assert all(i.simplify(1, 2) is i for i in (S.true, S.false))
def heurisch_wrapper(f, x, rewrite=False, hints=None, mappings=None, retries=3, degree_offset=0, unnecessary_permutations=None): """ A wrapper around the heurisch integration algorithm. This method takes the result from heurisch and checks for poles in the denominator. For each of these poles, the integral is reevaluated, and the final integration result is given in terms of a Piecewise. Examples ======== >>> from sympy.core import symbols >>> from sympy.functions import cos >>> from sympy.integrals.heurisch import heurisch, heurisch_wrapper >>> n, x = symbols('n x') >>> heurisch(cos(n*x), x) sin(n*x)/n >>> heurisch_wrapper(cos(n*x), x) Piecewise((x, n == 0), (sin(n*x)/n, True)) See Also ======== heurisch """ f = sympify(f) if x not in f.free_symbols: return f * x res = heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations) if not isinstance(res, Basic): return res # We consider each denominator in the expression, and try to find # cases where one or more symbolic denominator might be zero. The # conditions for these cases are stored in the list slns. slns = [] for d in denoms(res): try: slns += solve(d, dict=True, exclude=(x, )) except NotImplementedError: pass if not slns: return res slns = list(uniq(slns)) # Remove the solutions corresponding to poles in the original expression. slns0 = [] for d in denoms(f): try: slns0 += solve(d, dict=True, exclude=(x, )) except NotImplementedError: pass slns = [s for s in slns if s not in slns0] if not slns: return res if len(slns) > 1: eqs = [] for sub_dict in slns: eqs.extend([Eq(key, value) for key, value in sub_dict.items()]) slns = solve(eqs, dict=True, exclude=(x, )) + slns # For each case listed in the list slns, we reevaluate the integral. pairs = [] for sub_dict in slns: expr = heurisch(f.subs(sub_dict), x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations) cond = And(*[Eq(key, value) for key, value in sub_dict.items()]) pairs.append((expr, cond)) pairs.append((heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations), True)) return Piecewise(*pairs)
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)