def test_satisfy(): # Typical cases f = a & ~b & c & ~d assert EXPRZERO.satisfy_one() is None assert EXPRONE.satisfy_one() == {} assert f.satisfy_one() == {a: 1, b: 0, c: 1, d: 0} # PLE solution f = (a | b | c) & (~a | ~b | c) assert f.satisfy_one() == {a: 0, b: 0, c: 1} points = [p for p in Xor(a, b, c).satisfy_all()] assert points == [ {a: 0, b: 0, c: 1}, {a: 0, b: 1, c: 0}, {a: 1, b: 0, c: 0}, {a: 1, b: 1, c: 1}, ] assert Xor(a, b, c).satisfy_count() == 4 # Assumptions f = OneHot(a, b, c) g = Xor(a, b, c) with a, ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0} with a & ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0}
def test_nf(): f = Xor(a, b, c) g = a * b + a * c + b * c assert str(f.to_dnf()) == "a' * b' * c + a' * b * c' + a * b' * c' + a * b * c" assert str(f.to_cnf()) == "(a + b + c) * (a + b' + c') * (a' + b + c') * (a' + b' + c)" assert str(g.to_cdnf()) == "a' * b * c + a * b' * c + a * b * c' + a * b * c" assert str(g.to_ccnf()) == "(a + b + c) * (a + b + c') * (a + b' + c) * (a' + b + c)"
def test_expr2dimacssat(): assert_raises(ValueError, expr2dimacssat, Xor(0, a, simplify=False)) ret = expr2dimacssat(Xor(a, ~b)) assert ret in {'p satx 2\nxor(-2 1)', 'p satx 2\nxor(1 -2)'} ret = expr2dimacssat(Xor(a, Equal(b, ~c))) assert ret in { 'p satex 3\nxor(=(2 -3) 1)', 'p satex 3\nxor(1 =(2 -3))', 'p satex 3\nxor(=(-3 2) 1)', 'p satex 3\nxor(1 =(-3 2))' } ret = expr2dimacssat(Equal(a, ~b)) assert ret in {'p sate 2\n=(1 -2)', 'p sate 2\n=(-2 1)'} ret = expr2dimacssat(And(a, ~b)) assert ret in {'p sat 2\n*(1 -2)', 'p sat 2\n*(-2 1)'} ret = expr2dimacssat(Or(a, ~b)) assert ret in {'p sat 2\n+(1 -2)', 'p sat 2\n+(-2 1)'} ret = expr2dimacssat(Not(a | ~b)) assert ret in {'p sat 2\n-(+(1 -2))', 'p sat 2\n-(+(-2 1))'}
def test_depth(): assert (a | b).depth == 1 assert (a | (b & c)).depth == 2 assert (a | (b & (c | d))).depth == 3 assert (a & b).depth == 1 assert (a & (b | c)).depth == 2 assert (a & (b | (c & d))).depth == 3 assert Not(a | b).depth == 2 assert Not(a | (b & c)).depth == 3 assert Not(a | (b & (c | d))).depth == 4 assert Xor(a, b, c).depth == 1 assert Xor(a, b, c | d).depth == 2 assert Xor(a, b, c | Xor(d, e)).depth == 3 assert Equal(a, b, c).depth == 1 assert Equal(a, b, c | d).depth == 2 assert Equal(a, b, c | Xor(d, e)).depth == 3 assert Implies(p, q).depth == 1 assert Implies(p, a | b).depth == 2 assert Implies(p, Xor(a, b)).depth == 2 assert ITE(s, a, b).depth == 1 assert ITE(s, a | b, b).depth == 2 assert ITE(s, a | b, Xor(a, b)).depth == 2
def test_unate(): # c' * (a' + b') f = -c * (-a + -b) assert f.is_neg_unate([a, b, c]) assert f.is_neg_unate([a, b]) assert f.is_neg_unate([a, c]) assert f.is_neg_unate([b, c]) assert f.is_neg_unate(a) assert f.is_neg_unate(b) assert f.is_neg_unate(c) assert f.is_neg_unate() f = c * (a + b) assert f.is_pos_unate([a, b, c]) assert f.is_pos_unate([a, b]) assert f.is_pos_unate([a, c]) assert f.is_pos_unate([b, c]) assert f.is_pos_unate(a) assert f.is_pos_unate(b) assert f.is_pos_unate(c) assert f.is_pos_unate() f = Xor(a, b, c) assert f.is_binate([a, b, c]) assert f.is_binate([a, b]) assert f.is_binate([a, c]) assert f.is_binate([b, c]) assert f.is_binate(a) assert f.is_binate(b) assert f.is_binate(c)
def test_unate(): f = ~c & (~a | ~b) assert f.is_neg_unate([a, b, c]) assert f.is_neg_unate([a, b]) assert f.is_neg_unate([a, c]) assert f.is_neg_unate([b, c]) assert f.is_neg_unate(a) assert f.is_neg_unate(b) assert f.is_neg_unate(c) assert f.is_neg_unate() f = c & (a | b) assert f.is_pos_unate([a, b, c]) assert f.is_pos_unate([a, b]) assert f.is_pos_unate([a, c]) assert f.is_pos_unate([b, c]) assert f.is_pos_unate(a) assert f.is_pos_unate(b) assert f.is_pos_unate(c) assert f.is_pos_unate() f = Xor(a, b, c) assert f.is_binate([a, b, c]) assert f.is_binate([a, b]) assert f.is_binate([a, c]) assert f.is_binate([b, c]) assert f.is_binate(a) assert f.is_binate(b) assert f.is_binate(c)
def test_satisfy(): # Typical cases f = a & ~b & c & ~d assert Zero.satisfy_one() is None assert One.satisfy_one() == {} assert f.satisfy_one() == {a: 1, b: 0, c: 1, d: 0} # PLE solution f = (a | b | c) & (~a | ~b | c) assert f.satisfy_one() == {a: 0, b: 0, c: 1} points = [p for p in Xor(a, b, c).satisfy_all()] assert points == [ {a: 0, b: 0, c: 1}, {a: 0, b: 1, c: 0}, {a: 1, b: 0, c: 0}, {a: 1, b: 1, c: 1}, ] assert Xor(a, b, c).satisfy_count() == 4 # CNF SAT UNSAT sat = Majority(a, b, c, conj=True) unsat = Zero.expand([a, b, c], conj=True) assert unsat.satisfy_one() is None assert not list(unsat.satisfy_all()) assert list(sat.satisfy_all()) # Assumptions f = OneHot(a, b, c) g = Xor(a, b, c) with a, ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0} with a & ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0}
def test_satisfy(): # Typical cases f = a & ~b & c & ~d assert Zero.satisfy_one() is None assert One.satisfy_one() == {} assert f.satisfy_one() == {a: 1, b: 0, c: 1, d: 0} # PLE solution f = (a | b | c) & (~a | ~b | c) assert f.satisfy_one() == {a: 0, b: 0, c: 1} points = [p for p in Xor(a, b, c).satisfy_all()] assert points == [ { a: 0, b: 0, c: 1 }, { a: 0, b: 1, c: 0 }, { a: 1, b: 0, c: 0 }, { a: 1, b: 1, c: 1 }, ] assert Xor(a, b, c).satisfy_count() == 4 # CNF SAT UNSAT sat = Majority(a, b, c, conj=True) unsat = Zero.expand([a, b, c], conj=True) assert unsat.satisfy_one() is None assert not list(unsat.satisfy_all()) assert list(sat.satisfy_all()) # Assumptions f = OneHot(a, b, c) g = Xor(a, b, c) with a, ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0} with a & ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0}
def test_basic(): a, b, c, d, p, q, s = map(exprvar, 'abcdpqs') assert expr("a & ~b | b & ~c").equivalent(a & ~b | b & ~c) assert expr("p => q").equivalent(~p | q) assert expr("a <=> b").equivalent(~a & ~b | a & b) assert expr("s ? a : b").equivalent(s & a | ~s & b) assert expr("Not(a)").equivalent(Not(a)) assert expr("Or(a, b, c)").equivalent(Or(a, b, c)) assert expr("And(a, b, c)").equivalent(And(a, b, c)) assert expr("Xor(a, b, c)").equivalent(Xor(a, b, c)) assert expr("Xnor(a, b, c)").equivalent(Xnor(a, b, c)) assert expr("Equal(a, b, c)").equivalent(Equal(a, b, c)) assert expr("Unequal(a, b, c)").equivalent(Unequal(a, b, c)) assert expr("Implies(p, q)").equivalent(Implies(p, q)) assert expr("ITE(s, a, b)").equivalent(ITE(s, a, b)) assert expr("Nor(a, b, c)").equivalent(Nor(a, b, c)) assert expr("Nand(a, b, c)").equivalent(Nand(a, b, c)) assert expr("OneHot0(a, b, c)").equivalent(OneHot0(a, b, c)) assert expr("OneHot(a, b, c)").equivalent(OneHot(a, b, c)) assert expr("Majority(a, b, c)").equivalent(Majority(a, b, c)) assert expr("AchillesHeel(a, b, c, d)").equivalent(AchillesHeel( a, b, c, d))
def test_satisfy(): # Typical cases f = a & ~b & c & ~d assert EXPRZERO.satisfy_one() is None assert EXPRONE.satisfy_one() == {} assert f.satisfy_one() == {a: 1, b: 0, c: 1, d: 0} # PLE solution f = (a | b | c) & (~a | ~b | c) assert f.satisfy_one() == {a: 0, b: 0, c: 1} points = [p for p in Xor(a, b, c).satisfy_all()] assert points == [ { a: 0, b: 0, c: 1 }, { a: 0, b: 1, c: 0 }, { a: 1, b: 0, c: 0 }, { a: 1, b: 1, c: 1 }, ] assert Xor(a, b, c).satisfy_count() == 4 # Assumptions f = OneHot(a, b, c) g = Xor(a, b, c) with a, ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0} with a & ~b: assert f.satisfy_one() == {a: 1, b: 0, c: 0} assert g.satisfy_one() == {a: 1, b: 0, c: 0}
def test_table(): assert truthtable([], [0]).is_zero() assert truthtable([], [1]).is_one() f = Xor(a, b, c, d) tt = expr2truthtable(f) assert truthtable2expr(tt).equivalent(f) assert truthtable2expr(tt, conj=True).equivalent(f) assert str(tt) == XOR_STR assert repr(tt) == XOR_STR assert tt.support == {aa, bb, cc, dd} assert tt.inputs == (aa, bb, cc, dd) assert truthtable2expr(tt.restrict({aa: 0})).equivalent(Xor(b, c, d)) assert tt.restrict({ee: 0}) == tt assert tt.satisfy_one() == {aa: 1, bb: 0, cc: 0, dd: 0} assert [p for p in tt.satisfy_all()] == [{ aa: 1, bb: 0, cc: 0, dd: 0 }, { aa: 0, bb: 1, cc: 0, dd: 0 }, { aa: 0, bb: 0, cc: 1, dd: 0 }, { aa: 1, bb: 1, cc: 1, dd: 0 }, { aa: 0, bb: 0, cc: 0, dd: 1 }, { aa: 1, bb: 1, cc: 0, dd: 1 }, { aa: 1, bb: 0, cc: 1, dd: 1 }, { aa: 0, bb: 1, cc: 1, dd: 1 }] assert tt.satisfy_count() == 8 assert truthtable((a, b), "0000").satisfy_one() == None
def test_xor(): assert Xor() is Zero assert Xor(a) is a assert Xor(0, 0) is Zero assert Xor(0, 1) is One assert Xor(1, 0) is One assert Xor(1, 1) is Zero assert Xor(0, 0, 0) is Zero assert Xor(0, 0, 1) is One assert Xor(0, 1, 0) is One assert Xor(0, 1, 1) is Zero assert Xor(1, 0, 0) is One assert Xor(1, 0, 1) is Zero assert Xor(1, 1, 0) is Zero assert Xor(1, 1, 1) is One assert Xor(a, 0) is a assert Xor(1, a) is ~a assert Xor(~a, a) is One assert str(Xor(a, 0, simplify=False)) == "Xor(a, 0)" assert str(Xor(1, a, simplify=False)) == "Xor(1, a)" assert str(Xor(~a, a, simplify=False)) == "Xor(~a, a)"
def test_xor(): # Function assert Xor(~a, b).support == {a, b} # Expression assert Xor() is EXPRZERO assert Xor(a) == a assert Xor(0, 0) is EXPRZERO assert Xor(0, 1) is EXPRONE assert Xor(1, 0) is EXPRONE assert Xor(1, 1) is EXPRZERO assert Xor(0, 0, 0) is EXPRZERO assert Xor(0, 0, 1) is EXPRONE assert Xor(0, 1, 0) is EXPRONE assert Xor(0, 1, 1) is EXPRZERO assert Xor(1, 0, 0) is EXPRONE assert Xor(1, 0, 1) is EXPRZERO assert Xor(1, 1, 0) is EXPRZERO assert Xor(1, 1, 1) is EXPRONE assert 0 ^ a is a assert a ^ 0 is a assert 1 ^ a is ~a assert a ^ 1 is ~a # associative assert str((a ^ b) ^ c ^ d) == "Xor(a, b, c, d)" assert str(a ^ (b ^ c) ^ d) == "Xor(a, b, c, d)" assert str(a ^ b ^ (c ^ d)) == "Xor(a, b, c, d)" assert str((a ^ b) ^ (c ^ d)) == "Xor(a, b, c, d)" assert str((a ^ b ^ c) ^ d) == "Xor(a, b, c, d)" assert str(a ^ (b ^ c ^ d)) == "Xor(a, b, c, d)" assert str(a ^ (b ^ (c ^ d))) == "Xor(a, b, c, d)" assert str(((a ^ b) ^ c) ^ d) == "Xor(a, b, c, d)" assert a ^ a is EXPRZERO assert a ^ a ^ a is a assert a ^ a ^ a ^ a is EXPRZERO assert a ^ ~a is EXPRONE assert ~a ^ a is EXPRONE assert str(Xor(a, 0, simplify=False)) == "Xor(0, a)"
def test_issue81(): # Or(x) = x assert str(Or(Or(a, b))) == "Or(a, b)" assert str(Or(And(a, b))) == "And(a, b)" assert str(Or(Nor(a, b))) == "Not(Or(a, b))" assert str(Or(Nand(a, b))) == "Not(And(a, b))" assert str(Or(Xor(a, b))) == "Xor(a, b)" assert str(Or(Xnor(a, b))) == "Not(Xor(a, b))" # And(x) = x assert str(And(Or(a, b))) == "Or(a, b)" assert str(And(And(a, b))) == "And(a, b)" assert str(And(Nor(a, b))) == "Not(Or(a, b))" assert str(And(Nand(a, b))) == "Not(And(a, b))" assert str(And(Xor(a, b))) == "Xor(a, b)" assert str(And(Xnor(a, b))) == "Not(Xor(a, b))" # Nor(x) = ~x assert str(Nor(Or(a, b))) == "Not(Or(a, b))" assert str(Nor(And(a, b))) == "Not(And(a, b))" assert str(Nor(Nor(a, b))) == "Or(a, b)" assert str(Nor(Nand(a, b))) == "And(a, b)" assert str(Nor(Xor(a, b))) == "Not(Xor(a, b))" assert str(Nor(Xnor(a, b))) == "Xor(a, b)" # Nand(x) = ~x assert str(Nand(Or(a, b))) == "Not(Or(a, b))" assert str(Nand(And(a, b))) == "Not(And(a, b))" assert str(Nand(Nor(a, b))) == "Or(a, b)" assert str(Nand(Nand(a, b))) == "And(a, b)" assert str(Nand(Xor(a, b))) == "Not(Xor(a, b))" assert str(Nand(Xnor(a, b))) == "Xor(a, b)" # Xor(x) = x assert str(Xor(Or(a, b))) == "Or(a, b)" assert str(Xor(And(a, b))) == "And(a, b)" assert str(Xor(Nor(a, b))) == "Not(Or(a, b))" assert str(Xor(Nand(a, b))) == "Not(And(a, b))" assert str(Xor(Xor(a, b))) == "Xor(a, b)" assert str(Xor(Xnor(a, b))) == "Not(Xor(a, b))" # Xnor(x) = ~x assert str(Xnor(Or(a, b))) == "Not(Or(a, b))" assert str(Xnor(And(a, b))) == "Not(And(a, b))" assert str(Xnor(Nor(a, b))) == "Or(a, b)" assert str(Xnor(Nand(a, b))) == "And(a, b)" assert str(Xnor(Xor(a, b))) == "Not(Xor(a, b))" assert str(Xnor(Xnor(a, b))) == "Xor(a, b)"
def test_xor(): # Function assert Xor(~a, b).support == {a, b} # Expression assert Xor() is Zero assert Xor(a) is a assert Xor(0, 0) is Zero assert Xor(0, 1) is One assert Xor(1, 0) is One assert Xor(1, 1) is Zero assert Xor(0, 0, 0) is Zero assert Xor(0, 0, 1) is One assert Xor(0, 1, 0) is One assert Xor(0, 1, 1) is Zero assert Xor(1, 0, 0) is One assert Xor(1, 0, 1) is Zero assert Xor(1, 1, 0) is Zero assert Xor(1, 1, 1) is One assert (0 ^ a).equivalent(a) assert (a ^ 0).equivalent(a) assert (1 ^ a).equivalent(~a) assert (a ^ 1).equivalent(~a) # associative assert ((a ^ b) ^ c ^ d).equivalent(Xor(a, b, c, d)) assert (a ^ (b ^ c) ^ d).equivalent(Xor(a, b, c, d)) assert (a ^ b ^ (c ^ d)).equivalent(Xor(a, b, c, d)) assert ((a ^ b) ^ (c ^ d)).equivalent(Xor(a, b, c, d)) assert ((a ^ b ^ c) ^ d).equivalent(Xor(a, b, c, d)) assert (a ^ (b ^ c ^ d)).equivalent(Xor(a, b, c, d)) assert (a ^ (b ^ (c ^ d))).equivalent(Xor(a, b, c, d)) assert (((a ^ b) ^ c) ^ d).equivalent(Xor(a, b, c, d)) assert (a ^ a).equivalent(Zero) assert (a ^ a ^ a).equivalent(a) assert (a ^ a ^ a ^ a).equivalent(Zero) assert (a ^ ~a).equivalent(One) assert (~a ^ a).equivalent(One) assert str(Xor(a, 0, simplify=False)) == "Xor(a, 0)"