Exemplo n.º 1
0
 def __init__(self, title, formulas, shouldBeSat=False):
     self.title = title
     #self.formulas = [ simplify_logic(f) for f in formulas ] # a list of formula from imprecise (easy to solve) to precise (hard to solve)
     #self.formulas = [ simplify(f) for f in formulas ]
     #self.formulas = [ to_nnf(f, simplify=False) for f in formulas ]
     self.formulas = [to_nnf(f) for f in formulas]
     self.sat = shouldBeSat
     self.model = None
Exemplo n.º 2
0
    def test_Equivalent(self):

        assert Equivalent(true, false) is false
        assert Equivalent(0, D) is Not(D)
        assert Equivalent(Equivalent(A, B), C) is not Equivalent(Equivalent(C, Equivalent(A, B)))
        assert Equivalent(B < 1, B >= 1) is false
        assert Equivalent(C < 1, C >= 1, 0) is false
        assert Equivalent(D < 1, D >= 1, 1) is false
        assert Equivalent(E < 1, S(1) > E) is Equivalent(1, 1)
        assert Equivalent(Equality(C, D), Equality(D, C)) is true

        #to_nnf in Equivalent (could be in Equivalent)
        assert to_nnf(Equivalent(D, B, C)) == (~D | B) & (~B | C) & (~C | D)
Exemplo n.º 3
0
    def test_to_nnf(self):
       
        #ITE
        assert to_nnf(ITE(A, B, C)) is (~A | B) & (A | C)

        assert to_nnf(Not(A | B)) is ~A & ~B
        assert to_nnf(Not(D & C & A)) is ~D | ~C | ~A
        assert to_nnf(Not(D ^ B ^ C)) is \
        (~D | B | C) & (D | ~B | C) & (D | B | ~C) & (~D | ~B | ~C)
    
        assert to_nnf(Not(ITE(C, B, A))) is (~C | ~B) & (C | ~A)
        assert to_nnf((A >> B) ^ (B >> A)) is (A & ~B) | (~A & B)
Exemplo n.º 4
0
def test_to_nnf():
    assert to_nnf(true) is true
    assert to_nnf(false) is false
    assert to_nnf(A) == A
    assert to_nnf(A | ~A | B) is true
    assert to_nnf(A & ~A & B) is false
    assert to_nnf(A >> B) == ~A | B
    assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
    assert to_nnf(A ^ B ^ C) == \
            (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
    assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
    assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
    assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
    assert to_nnf(Not(A >> B)) == A & ~B
    assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
    assert to_nnf(Not(A ^ B ^ C)) == \
            (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
    assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
    assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
    assert to_nnf((A >> B) ^ (B >> A), False) == \
            (~A | ~B | A | B) & ((A & ~B) | (~A & B))
Exemplo n.º 5
0
def test_to_nnf():
    assert to_nnf(true) is true
    assert to_nnf(false) is false
    assert to_nnf(A) == A
    assert to_nnf(A | ~A | B) is true
    assert to_nnf(A & ~A & B) is false
    assert to_nnf(A >> B) == ~A | B
    assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
    assert to_nnf(A ^ B ^ C) == \
        (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
    assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
    assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
    assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
    assert to_nnf(Not(A >> B)) == A & ~B
    assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
    assert to_nnf(Not(A ^ B ^ C)) == \
        (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
    assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
    assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
    assert to_nnf((A >> B) ^ (B >> A), False) == \
        (~A | ~B | A | B) & ((A & ~B) | (~A & B))
    assert ITE(A, 1, 0).to_nnf() == A
    assert ITE(A, 0, 1).to_nnf() == ~A
    # although ITE can hold non-Boolean, it will complain if
    # an attempt is made to convert the ITE to Boolean nnf
    raises(TypeError, lambda: ITE(A < 1, [1], B).to_nnf())
Exemplo n.º 6
0
def test_to_nnf():
    assert to_nnf(true) is true
    assert to_nnf(false) is false
    assert to_nnf(A) == A
    assert to_nnf(A | ~A | B) is true
    assert to_nnf(A & ~A & B) is false
    assert to_nnf(A >> B) == ~A | B
    assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
    assert to_nnf(A ^ B ^ C) == \
            (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
    assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
    assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
    assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
    assert to_nnf(Not(A >> B)) == A & ~B
    assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
    assert to_nnf(Not(A ^ B ^ C)) == \
            (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
    assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
    assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
    assert to_nnf((A >> B) ^ (B >> A), False) == \
            (~A | ~B | A | B) & ((A & ~B) | (~A & B))
    assert ITE(A, 1, 0).to_nnf() == A
    assert ITE(A, 0, 1).to_nnf() == ~A
    # although ITE can hold non-Boolean, it will complain if
    # an attempt is made to convert the ITE to Boolean nnf
    raises(TypeError, lambda: ITE(A < 1, [1], B).to_nnf())
Exemplo n.º 7
0
def test_to_nnf():
    assert to_nnf(true) is true
    assert to_nnf(false) is false
    assert to_nnf(A) == A
    assert to_nnf(A | ~A | B) is true
    assert to_nnf(A & ~A & B) is false
    assert to_nnf(A >> B) == ~A | B
    assert to_nnf(Equivalent(A, B, C)) == (~A | B) & (~B | C) & (~C | A)
    assert to_nnf(A ^ B ^ C) == \
            (A | B | C) & (~A | ~B | C) & (A | ~B | ~C) & (~A | B | ~C)
    assert to_nnf(ITE(A, B, C)) == (~A | B) & (A | C)
    assert to_nnf(Not(A | B | C)) == ~A & ~B & ~C
    assert to_nnf(Not(A & B & C)) == ~A | ~B | ~C
    assert to_nnf(Not(A >> B)) == A & ~B
    assert to_nnf(Not(Equivalent(A, B, C))) == And(Or(A, B, C), Or(~A, ~B, ~C))
    assert to_nnf(Not(A ^ B ^ C)) == \
            (~A | B | C) & (A | ~B | C) & (A | B | ~C) & (~A | ~B | ~C)
    assert to_nnf(Not(ITE(A, B, C))) == (~A | ~B) & (A | ~C)
    assert to_nnf((A >> B) ^ (B >> A)) == (A & ~B) | (~A & B)
    assert to_nnf((A >> B) ^ (B >> A), False) == \
            (~A | ~B | A | B) & ((A & ~B) | (~A & B))
Exemplo n.º 8
0
def logicrelsimp(expr, form='dnf', deep=True):
    """ logically simplify relations using totality (WARNING: it is unstable)
    >>> from sympy import *
    >>> from symplus.strplus import init_mprinting
    >>> init_mprinting()
    >>> x, y, z = symbols('x y z')
    >>> logicrelsimp((x>0) >> ((x<=0)&(y<0)))
    x =< 0
    >>> logicrelsimp((x>0) >> (x>=0))
    True
    >>> logicrelsimp((x<0) & (x>0))
    False
    >>> logicrelsimp(((x<0) | (y>0)) & ((x>0) | (y<0)))
    (x < 0) /\ (y < 0) \/ (x > 0) /\ (y > 0)
    >>> logicrelsimp(((x<0) & (y>0)) | ((x>0) & (y<0)))
    (x < 0) /\ (y > 0) \/ (x > 0) /\ (y < 0)
    """
    from sympy.core.symbol import Wild
    from sympy.core import sympify
    from sympy.logic.boolalg import (SOPform, POSform, to_nnf,
                                     _find_predicates, simplify_logic)
    Nt = lambda x: Not(x, evaluate=False)

    if form not in ('cnf', 'dnf'):
        raise ValueError("form can be cnf or dnf only")
    expr = sympify(expr)
    if not isinstance(expr, BooleanFunction):
        return expr

    # canonicalize relations
    expr = expr.replace(lambda rel: isinstance(rel, Rel),
                        lambda rel: canonicalize_polyeq(rel))

    # to nnf
    w = Wild('w')
    expr = to_nnf(expr)
    expr = expr.replace(Not(w), lambda w: Not(w, evaluate=True))

    if is_simplerel(expr):
        # standardize relation
        expr = expr.replace(Ne(w,0), Nt(Eq(w,0)))
        expr = expr.replace(Ge(w,0), Nt(Lt(w,0)))
        expr = expr.replace(Le(w,0), Nt(Gt(w,0)))

        expr = simplify_logic(expr, form, deep)

        return expr

    else:
        # standardize relation
        expr = expr.replace(Ne(w,0), Or(Gt(w,0), Lt(w,0)))
        expr = expr.replace(Ge(w,0), Or(Gt(w,0), Eq(w,0)))
        expr = expr.replace(Le(w,0), Or(Lt(w,0), Eq(w,0)))

        # make totality
        variables = _find_predicates(expr)
        relations = (v for v in variables if isinstance(v, Rel) and v.args[1] == 0)
        totalities = []
        for a in set(rel.args[0] for rel in relations):
            totalities.append(
                Or(And(Gt(a,0), Nt(Eq(a,0)), Nt(Lt(a,0))),
                   And(Nt(Gt(a,0)), Eq(a,0), Nt(Lt(a,0))),
                   And(Nt(Gt(a,0)), Nt(Eq(a,0)), Lt(a,0))))
        totality = And(*totalities)

        # make truth table, don't care table
        truthtable = []
        dontcares = []
        for t in product([0, 1], repeat=len(variables)):
            t = list(t)
            if totality.xreplace(dict(zip(variables, t))) == False:
                dontcares.append(t)
            elif expr.xreplace(dict(zip(variables, t))) == True:
                truthtable.append(t)

        if deep:
            variables = [simplify(v) for v in variables]
        if form == 'dnf':
            expr = SOPform(variables, truthtable, dontcares)
        elif form == 'cnf':
            expr = POSform(variables, truthtable, dontcares)

        return expr