def test_nf(): f = a ^ b ^ c g = a & b | a & c | b & c f_dnf = f.to_dnf() f_cnf = f.to_cnf() assert f_dnf.equivalent( Or(And(~a, ~b, c), And(~a, b, ~c), And(a, ~b, ~c), And(a, b, c))) assert f_cnf.equivalent( And(Or(a, b, c), Or(a, ~b, ~c), Or(~a, b, ~c), Or(~a, ~b, c)))
def _cover2exprs(inputs, noutputs, cover): """Convert a cover to a tuple of Expression instances.""" fs = list() for i in range(noutputs): terms = list() for invec, outvec in cover: if outvec[i]: term = list() for j, v in enumerate(inputs): if invec[j] == 1: term.append(~v) elif invec[j] == 2: term.append(v) terms.append(term) fs.append(Or(*[And(*term) for term in terms])) return tuple(fs)
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_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_or(): assert Or() is Zero assert Or(a) is a assert Or(0, 0) is Zero assert Or(0, 1) is One assert Or(1, 0) is One assert Or(1, 1) is One assert Or(0, 0, 0) is Zero assert Or(0, 0, 1) is One assert Or(0, 1, 0) is One assert Or(0, 1, 1) is One assert Or(1, 0, 0) is One assert Or(1, 0, 1) is One assert Or(1, 1, 0) is One assert Or(1, 1, 1) is One assert Or(a, 0) is a assert Or(1, a) is One assert Or(~a, a) is One assert str(Or(a, 0, simplify=False)) == "Or(a, 0)" assert str(Or(1, a, simplify=False)) == "Or(1, a)" assert str(Or(~a, a, simplify=False)) == "Or(~a, 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_or(): # Function assert (~a | b).support == {a, b} f = ~a & b & c | a & ~b & c | a & b & ~c assert f.restrict({a: 0}).equivalent(b & c) assert f.restrict({a: 1}).equivalent(b & ~c | ~b & c) assert f.restrict({a: 0, b: 0}) is EXPRZERO assert f.restrict({a: 0, b: 1}) == c assert f.restrict({a: 1, b: 0}) == c assert f.restrict({a: 1, b: 1}) == ~c assert f.compose({a: d, b: c}).equivalent(~d & c) # Expression assert Or() is EXPRZERO assert Or(a) == a assert Or(0, 0) is EXPRZERO assert Or(0, 1) is EXPRONE assert Or(1, 0) is EXPRONE assert Or(1, 1) is EXPRONE assert Or(0, 0, 0) is EXPRZERO assert Or(0, 0, 1) is EXPRONE assert Or(0, 1, 0) is EXPRONE assert Or(0, 1, 1) is EXPRONE assert Or(1, 0, 0) is EXPRONE assert Or(1, 0, 1) is EXPRONE assert Or(1, 1, 0) is EXPRONE assert Or(1, 1, 1) is EXPRONE assert 0 | a is a assert a | 0 is a assert 1 | a is EXPRONE assert a | 1 is EXPRONE assert (0 | a | b).equivalent(a | b) assert (a | b | 0).equivalent(a | b) assert (1 | a | b) is EXPRONE assert (a | b | 1) is EXPRONE assert str(Or(a, 0, simplify=False)) == "Or(0, a)" # associative assert str((a | b) | c | d) == "Or(a, b, c, d)" assert str(a | (b | c) | d) == "Or(a, b, c, d)" assert str(a | b | (c | d)) == "Or(a, b, c, d)" assert str((a | b) | (c | d)) == "Or(a, b, c, d)" assert str((a | b | c) | d) == "Or(a, b, c, d)" assert str(a | (b | c | d)) == "Or(a, b, c, d)" assert str(a | (b | (c | d))) == "Or(a, b, c, d)" assert str(((a | b) | c) | d) == "Or(a, b, c, d)" # idempotent assert a | a == a assert a | a | a == a assert a | a | a | a == a assert (a | a) | (a | a) == a # inverse assert ~a | a is EXPRONE assert a | ~a is EXPRONE
def test_or(): # Function assert (~a | b).support == {a, b} f = ~a & b & c | a & ~b & c | a & b & ~c assert f.restrict({a: 0}).equivalent(b & c) assert f.restrict({a: 1}).equivalent(b & ~c | ~b & c) assert f.restrict({a: 0, b: 0}) is Zero assert f.restrict({a: 0, b: 1}) is c assert f.restrict({a: 1, b: 0}) is c assert f.restrict({a: 1, b: 1}) is ~c assert f.compose({a: d, b: c}).equivalent(~d & c) # Expression assert Or() is Zero assert Or(a) is a assert Or(0, 0) is Zero assert Or(0, 1) is One assert Or(1, 0) is One assert Or(1, 1) is One assert Or(0, 0, 0) is Zero assert Or(0, 0, 1) is One assert Or(0, 1, 0) is One assert Or(0, 1, 1) is One assert Or(1, 0, 0) is One assert Or(1, 0, 1) is One assert Or(1, 1, 0) is One assert Or(1, 1, 1) is One assert (0 | a).equivalent(a) assert (a | 0).equivalent(a) assert (1 | a).equivalent(One) assert (a | 1).equivalent(One) assert (0 | a | b).equivalent(a | b) assert (a | b | 0).equivalent(a | b) assert (1 | a | b).equivalent(One) assert (a | b | 1).equivalent(One) assert str(Or(a, 0, simplify=False)) == "Or(a, 0)" # associative assert ((a | b) | c | d).equivalent(Or(a, b, c, d)) assert (a | (b | c) | d).equivalent(Or(a, b, c, d)) assert (a | b | (c | d)).equivalent(Or(a, b, c, d)) assert ((a | b) | (c | d)).equivalent(Or(a, b, c, d)) assert ((a | b | c) | d).equivalent(Or(a, b, c, d)) assert (a | (b | c | d)).equivalent(Or(a, b, c, d)) assert (a | (b | (c | d))).equivalent(Or(a, b, c, d)) assert (((a | b) | c) | d).equivalent(Or(a, b, c, d)) # idempotent assert (a | a).equivalent(a) assert (a | a | a).equivalent(a) assert (a | a | a | a).equivalent(a) assert ((a | a) | (a | a)).equivalent(a) # inverse assert (~a | a).equivalent(One) assert (a | ~a).equivalent(One)
exprvar, 'cvp' ) # creates boolean variables c, v, and p representing contribute, vote, and punish evars = [c, v, p] uniqid2evar = {vv.uniqid: vv for vv in evars} # scenarios # --- scen = 0 if scen == 0: # no punishers, no voters f = And(Not(p), Not(v), Or(c, ~c, simplify=False), simplify=False) suffix = '0_nopun_novot' elif scen == 1: # voters and punishers # punishers don't cooperate f = And(Not(And(p, c)), Not(And(~c, v)), Or(c, ~c, simplify=False), Not(And(p, v)), simplify=False) # punish non-cooperation only poss_prules = [[And(~p, ~c)]] suffix = '1_punnocs'