def test_to_cnf(): A, B, C = map(Boolean, symbols('ABC')) 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(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)) == \ And(Or(Not(B), A), Or(Not(C), A), Or(B, C, Not(A)))
def test_class_handler_registry(): my_handler_registry = ClassFactRegistry() # The predicate doesn't matter here, so just use is_true fact1 = Equivalent(Q.is_true, AllArgs(Q.is_true)) fact2 = Equivalent(Q.is_true, AnyArgs(Q.is_true)) my_handler_registry[Mul] = {fact1} my_handler_registry[Expr] = {fact2} assert my_handler_registry[Basic] == set() assert my_handler_registry[Expr] == {fact2} assert my_handler_registry[Mul] == {fact1, fact2}
def result(self, obj, simplify=True, evaluate=None): assumptions = {self.determine_assumptions(obj): self.source} for i in range(-1, -len(self.index) - 1, -1): this = self._objs[i - 1] args = [*this.args] args[self.index[i]] = obj stop = i == -len(self.index) if stop: kwargs = assumptions else: kwargs = this.kwargs if evaluate is not None: kwargs['evaluate'] = evaluate if self._domain_defined and this.func.is_ExprWithLimits: _, *limits = args for i, limit in enumerate(limits): if limit[0] in self._domain_defined: x, domain = limit.coerce_setlimit() domain_defined = self._domain_defined.pop(x) if domain != domain_defined: if domain_defined in domain: args[i + 1] = (x, domain_defined) break else: if this.is_All: for x in set(self._domain_defined): if this._has(x): args.append((x, self._domain_defined.pop(x))) obj = this.func(*args, **kwargs) if simplify and (not obj.is_All or stop or not self._objs[i - 2].is_Any): # exclude case Any[C](All[x](f(x) == C)) obj = obj.simplify() if stop: break else: assert not len(self.index) obj = obj.copy(**assumptions) if obj.equivalent == self.source and obj == self.source: return self.source from sympy import Boolean if isinstance(self.source, Boolean): if 'given' in assumptions: from sympy import Suffice return Suffice(self.source, obj, plausible=None) if 'equivalent' in assumptions: from sympy import Equivalent return Equivalent(self.source, obj, plausible=None) return obj
def parse_logic(self, logic, switch_sides=False, convert_to_converse=False): """ Read the logic model and formulate the symbolic expression :param logic A Logic model instance :param switch_sides: if True, reverse the sides indicated by the logic model's side field :param convert_to_converse: if True, swap hyps and concs :return: symbolic expression """ # FIXME: dumb hard coding side_swap = { 0: 0, 1: 1, 2: 3, 3: 2, 4: 4 } hyps = logic.hyps.all() concs = logic.concs.all() if convert_to_converse: hyps, concs = concs, hyps hyp_expr = [] conc_expr = [] # form expression for hypothesis for pside in hyps: if switch_sides is True: pside.side = side_swap[pside.side] hyp_expr.append(self.parse_pside(pside)) # form expression for conclusion for pside in concs: if switch_sides is True: pside.side = side_swap[pside.side] conc_expr.append(self.parse_pside(pside)) hyp_expr = And(*hyp_expr) conc_expr = And(*conc_expr) # FIXME: dumb hard coding # is it an implication or an equivalence? if logic.variety == 0: return Implies(hyp_expr, conc_expr) elif logic.variety == 1: return Equivalent(hyp_expr, conc_expr)
def test_count_ops_non_visual(): def count(val): return count_ops(val, visual=False) assert count(x) == 0 assert count(x) is not S.Zero assert count(x + y) == 1 assert count(x + y) is not S.One assert count(x + y*x + 2*y) == 4 assert count({x + y: x}) == 1 assert count({x + y: S(2) + x}) is not S.One assert count(Or(x,y)) == 1 assert count(And(x,y)) == 1 assert count(Not(x)) == 0 assert count(Nor(x,y)) == 1 assert count(Nand(x,y)) == 1 assert count(Xor(x,y)) == 3 assert count(Implies(x,y)) == 1 assert count(Equivalent(x,y)) == 1 assert count(ITE(x,y,z)) == 3 assert count(ITE(True,x,y)) == 0
def test_pretty_Boolean(): expr = Not(x, evaluate=False) assert pretty(expr) == "Not(x)" assert upretty(expr) == u"¬ x" expr = And(x, y) assert pretty(expr) == "And(x, y)" assert upretty(expr) == u"x ∧ y" expr = Or(x, y) assert pretty(expr) == "Or(x, y)" assert upretty(expr) == u"x ∨ y" expr = Xor(x, y, evaluate=False) assert pretty(expr) == "Xor(x, y)" assert upretty(expr) == u"x ⊻ y" expr = Nand(x, y, evaluate=False) assert pretty(expr) == "Nand(x, y)" assert upretty(expr) == u"x ⊼ y" expr = Nor(x, y, evaluate=False) assert pretty(expr) == "Nor(x, y)" assert upretty(expr) == u"x ⊽ y" expr = Implies(x, y, evaluate=False) assert pretty(expr) == "Implies(x, y)" assert upretty(expr) == u"x → y" expr = Equivalent(x, y, evaluate=False) assert pretty(expr) == "Equivalent(x, y)" assert upretty(expr) == u"x ≡ y"
def test_Equivalent(): assert str(Equivalent(y, x)) == "Equivalent(x, y)"
def test_Equivalent(): A, B, C = map(Boolean, symbols('A,B,C')) assert Equivalent(A, B) == Equivalent(B, A) == Equivalent(A, B, A) assert Equivalent() == True assert Equivalent(A, A) == Equivalent(A) == True assert Equivalent(True, True) == Equivalent(False, False) == True assert Equivalent(True, False) == Equivalent(False, True) == 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
def test_count_ops_visual(): ADD, MUL, POW, SIN, COS, EXP, AND, D, G, M = symbols( 'Add Mul Pow sin cos exp And Derivative Integral Sum'.upper()) DIV, SUB, NEG = symbols('DIV SUB NEG') LT, LE, GT, GE, EQ, NE = symbols('LT LE GT GE EQ NE') NOT, OR, AND, XOR, IMPLIES, EQUIVALENT, _ITE, BASIC, TUPLE = symbols( 'Not Or And Xor Implies Equivalent ITE Basic Tuple'.upper()) def count(val): return count_ops(val, visual=True) assert count(7) is S.Zero assert count(S(7)) is S.Zero assert count(-1) == NEG assert count(-2) == NEG assert count(S(2) / 3) == DIV assert count(Rational(2, 3)) == DIV assert count(pi / 3) == DIV assert count(-pi / 3) == DIV + NEG assert count(I - 1) == SUB assert count(1 - I) == SUB assert count(1 - 2 * I) == SUB + MUL assert count(x) is S.Zero assert count(-x) == NEG assert count(-2 * x / 3) == NEG + DIV + MUL assert count(Rational(-2, 3) * x) == NEG + DIV + MUL assert count(1 / x) == DIV assert count(1 / (x * y)) == DIV + MUL assert count(-1 / x) == NEG + DIV assert count(-2 / x) == NEG + DIV assert count(x / y) == DIV assert count(-x / y) == NEG + DIV assert count(x**2) == POW assert count(-x**2) == POW + NEG assert count(-2 * x**2) == POW + MUL + NEG assert count(x + pi / 3) == ADD + DIV assert count(x + S.One / 3) == ADD + DIV assert count(x + Rational(1, 3)) == ADD + DIV assert count(x + y) == ADD assert count(x - y) == SUB assert count(y - x) == SUB assert count(-1 / (x - y)) == DIV + NEG + SUB assert count(-1 / (y - x)) == DIV + NEG + SUB assert count(1 + x**y) == ADD + POW assert count(1 + x + y) == 2 * ADD assert count(1 + x + y + z) == 3 * ADD assert count(1 + x**y + 2 * x * y + y**2) == 3 * ADD + 2 * POW + 2 * MUL assert count(2 * z + y + x + 1) == 3 * ADD + MUL assert count(2 * z + y**17 + x + 1) == 3 * ADD + MUL + POW assert count(2 * z + y**17 + x + sin(x)) == 3 * ADD + POW + MUL + SIN assert count(2 * z + y**17 + x + sin(x**2)) == 3 * ADD + MUL + 2 * POW + SIN assert count(2 * z + y**17 + x + sin(x**2) + exp(cos(x))) == 4 * ADD + MUL + 2 * POW + EXP + COS + SIN assert count(Derivative(x, x)) == D assert count(Integral(x, x) + 2 * x / (1 + x)) == G + DIV + MUL + 2 * ADD assert count(Sum(x, (x, 1, x + 1)) + 2 * x / (1 + x)) == M + DIV + MUL + 3 * ADD assert count(Basic()) is S.Zero assert count({x + 1: sin(x)}) == ADD + SIN assert count([x + 1, sin(x) + y, None]) == ADD + SIN + ADD assert count({x + 1: sin(x), y: cos(x) + 1}) == SIN + COS + 2 * ADD assert count({}) is S.Zero assert count([x + 1, sin(x) * y, None]) == SIN + ADD + MUL assert count([]) is S.Zero assert count(Basic()) == 0 assert count(Basic(Basic(), Basic(x, x + y))) == ADD + 2 * BASIC assert count(Basic(x, x + y)) == ADD + BASIC assert [count(Rel(x, y, op)) for op in '< <= > >= == <> !='.split() ] == [LT, LE, GT, GE, EQ, NE, NE] assert count(Or(x, y)) == OR assert count(And(x, y)) == AND assert count(Or(x, Or(y, And(z, a)))) == AND + OR assert count(Nor(x, y)) == NOT + OR assert count(Nand(x, y)) == NOT + AND assert count(Xor(x, y)) == XOR assert count(Implies(x, y)) == IMPLIES assert count(Equivalent(x, y)) == EQUIVALENT assert count(ITE(x, y, z)) == _ITE assert count([Or(x, y), And(x, y), Basic(x + y)]) == ADD + AND + BASIC + OR assert count(Basic(Tuple(x))) == BASIC + TUPLE #It checks that TUPLE is counted as an operation. assert count(Eq(x + y, S(2))) == ADD + EQ
def test_count_ops_visual(): ADD, MUL, POW, SIN, COS, EXP, AND, D, G = symbols( 'Add Mul Pow sin cos exp And Derivative Integral'.upper()) DIV, SUB, NEG = symbols('DIV SUB NEG') OR, AND, IMPLIES, EQUIVALENT, BASIC, TUPLE = symbols( 'Or And Implies Equivalent Basic Tuple'.upper()) def count(val): return count_ops(val, visual=True) assert count(7) is S.Zero assert count(S(7)) is S.Zero assert count(-1) == NEG assert count(-2) == NEG assert count(S(2)/3) == DIV assert count(pi/3) == DIV assert count(-pi/3) == DIV + NEG assert count(I - 1) == SUB assert count(1 - I) == SUB assert count(1 - 2*I) == SUB + MUL assert count(x) is S.Zero assert count(-x) == NEG assert count(-2*x/3) == NEG + DIV + MUL assert count(1/x) == DIV assert count(1/(x*y)) == DIV + MUL assert count(-1/x) == NEG + DIV assert count(-2/x) == NEG + DIV assert count(x/y) == DIV assert count(-x/y) == NEG + DIV assert count(x**2) == POW assert count(-x**2) == POW + NEG assert count(-2*x**2) == POW + MUL + NEG assert count(x + pi/3) == ADD + DIV assert count(x + S(1)/3) == ADD + DIV assert count(x + y) == ADD assert count(x - y) == SUB assert count(y - x) == SUB assert count(-1/(x - y)) == DIV + NEG + SUB assert count(-1/(y - x)) == DIV + NEG + SUB assert count(1 + x**y) == ADD + POW assert count(1 + x + y) == 2*ADD assert count(1 + x + y + z) == 3*ADD assert count(1 + x**y + 2*x*y + y**2) == 3*ADD + 2*POW + 2*MUL assert count(2*z + y + x + 1) == 3*ADD + MUL assert count(2*z + y**17 + x + 1) == 3*ADD + MUL + POW assert count(2*z + y**17 + x + sin(x)) == 3*ADD + POW + MUL + SIN assert count(2*z + y**17 + x + sin(x**2)) == 3*ADD + MUL + 2*POW + SIN assert count(2*z + y**17 + x + sin( x**2) + exp(cos(x))) == 4*ADD + MUL + 2*POW + EXP + COS + SIN assert count(Derivative(x, x)) == D assert count(Integral(x, x) + 2*x/(1 + x)) == G + DIV + MUL + 2*ADD assert count(Basic()) is S.Zero assert count({x + 1: sin(x)}) == ADD + SIN assert count([x + 1, sin(x) + y, None]) == ADD + SIN + ADD assert count({x + 1: sin(x), y: cos(x) + 1}) == SIN + COS + 2*ADD assert count({}) is S.Zero assert count([x + 1, sin(x)*y, None]) == SIN + ADD + MUL assert count([]) is S.Zero assert count(Basic()) == 0 assert count(Basic(Basic(),Basic(x,x+y))) == ADD + 2*BASIC assert count(Basic(x, x + y)) == ADD + BASIC assert count(Or(x,y)) == OR assert count(And(x,y)) == AND assert count(And(x**y,z)) == AND + POW assert count(Or(x,Or(y,And(z,a)))) == AND + 2*OR assert count(Nor(x,y)) == AND assert count(Nand(x,y)) == OR assert count(Xor(x,y)) == 2*AND + OR assert count(Implies(x,y)) == IMPLIES assert count(Equivalent(x,y)) == EQUIVALENT assert count(ITE(x,y,z)) == 2*AND + OR assert count([Or(x,y), And(x,y), Basic(x+y)]) == ADD + AND + BASIC + OR assert count(Basic(Tuple(x))) == BASIC + TUPLE #It checks that TUPLE is counted as an operation. assert count(Eq(x + y, S(2))) == ADD
from sympy import symbols, Equivalent, to_cnf, dotprint from graphviz import Source if __name__ == "__main__": # Define expression B1, P1, P2 = symbols('B1,P1,P2') p_1 = Equivalent(B1, (P1 | P2)) & ~B1 # ( B1 <-> (P1 & P2)) & ~B1 p_1_cnf = to_cnf(p_1) # Create the graphviz content expression_tree = dotprint(p_1) # Using the graphviz module write tree to file and generate .svg with result src = Source(expression_tree) src.render('expr_tree', view=True, format='pdf')