def __init__(self): self.X = exprvars('x', (1, 10), (1, 10), (1, 10)) V = And(*[ And(*[ OneHot(*[self.X[r, c, v] for v in range(1, 10)]) for c in range(1, 10) ]) for r in range(1, 10) ]) R = And(*[ And(*[ OneHot(*[self.X[r, c, v] for c in range(1, 10)]) for v in range(1, 10) ]) for r in range(1, 10) ]) C = And(*[ And(*[ OneHot(*[self.X[r, c, v] for r in range(1, 10)]) for v in range(1, 10) ]) for c in range(1, 10) ]) B = And(*[ And(*[ OneHot(*[ self.X[3 * br + r, 3 * bc + c, v] for r in range(1, 4) for c in range(1, 4) ]) for v in range(1, 10) ]) for br in range(3) for bc in range(3) ]) self.litmap, self.S = expr2dimacscnf(And(V, R, C, B))
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_and(): assert And() is One assert And(a) is a assert And(0, 0) is Zero assert And(0, 1) is Zero assert And(1, 0) is Zero assert And(1, 1) is One assert And(0, 0, 0) is Zero assert And(0, 0, 1) is Zero assert And(0, 1, 0) is Zero assert And(0, 1, 1) is Zero assert And(1, 0, 0) is Zero assert And(1, 0, 1) is Zero assert And(1, 1, 0) is Zero assert And(1, 1, 1) is One assert And(a, 0) is Zero assert And(1, a) is a assert And(~a, a) is Zero assert str(And(a, 0, simplify=False)) == "And(a, 0)" assert str(And(1, a, simplify=False)) == "And(1, a)" assert str(And(~a, a, simplify=False)) == "And(~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_and(): # 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 | ~b & ~c) assert f.restrict({a: 1}).equivalent(b | c) assert f.restrict({a: 0, b: 0}) == ~c assert f.restrict({a: 0, b: 1}) == c assert f.restrict({a: 1, b: 0}) == c assert f.restrict({a: 1, b: 1}) is EXPRONE assert f.compose({a: d, b: c}).equivalent(~d | c) # Expression assert And() is EXPRONE assert And(a) == a assert And(0, 0) is EXPRZERO assert And(0, 1) is EXPRZERO assert And(1, 0) is EXPRZERO assert And(1, 1) is EXPRONE assert And(0, 0, 0) is EXPRZERO assert And(0, 0, 1) is EXPRZERO assert And(0, 1, 0) is EXPRZERO assert And(0, 1, 1) is EXPRZERO assert And(1, 0, 0) is EXPRZERO assert And(1, 0, 1) is EXPRZERO assert And(1, 1, 0) is EXPRZERO assert And(1, 1, 1) is EXPRONE assert 0 & a is EXPRZERO assert a & 0 is EXPRZERO assert 1 & a is a assert a & 1 is a assert (0 & a & b) is EXPRZERO assert (a & b & 0) is EXPRZERO assert (1 & a & b).equivalent(a & b) assert (a & b & 1).equivalent(a & b) assert str(And(a, 1, simplify=False)) == "And(1, a)" # associative assert str((a & b) & c & d) == "And(a, b, c, d)" assert str(a & (b & c) & d) == "And(a, b, c, d)" assert str(a & b & (c & d)) == "And(a, b, c, d)" assert str((a & b) & (c & d)) == "And(a, b, c, d)" assert str((a & b & c) & d) == "And(a, b, c, d)" assert str(a & (b & c & d)) == "And(a, b, c, d)" assert str(a & (b & (c & d))) == "And(a, b, c, d)" assert str(((a & b) & c) & d) == "And(a, b, c, d)" # idempotent assert a & a is a assert a & a & a is a assert a & a & a & a is a assert (a & a) | (a & a) is a # inverse assert ~a & a is EXPRZERO assert a & ~a is EXPRZERO
def test_is_nf(): assert And(a, b, c).is_cnf() assert And(a, (b | c), (c | d)).is_cnf() assert not And((a | b), (b | c & d)).is_cnf()
def test_and(): # 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 | ~b & ~c) assert f.restrict({a: 1}).equivalent(b | c) assert f.restrict({a: 0, b: 0}) == ~c assert f.restrict({a: 0, b: 1}) == c assert f.restrict({a: 1, b: 0}) == c assert f.restrict({a: 1, b: 1}) is One assert f.compose({a: d, b: c}).equivalent(~d | c) # Expression assert And() is One assert And(a) is a assert And(0, 0) is Zero assert And(0, 1) is Zero assert And(1, 0) is Zero assert And(1, 1) is One assert And(0, 0, 0) is Zero assert And(0, 0, 1) is Zero assert And(0, 1, 0) is Zero assert And(0, 1, 1) is Zero assert And(1, 0, 0) is Zero assert And(1, 0, 1) is Zero assert And(1, 1, 0) is Zero assert And(1, 1, 1) is One assert (0 & a).equivalent(Zero) assert (a & 0).equivalent(Zero) assert (1 & a).equivalent(a) assert (a & 1).equivalent(a) assert (0 & a & b).equivalent(Zero) assert (a & b & 0).equivalent(Zero) assert (1 & a & b).equivalent(a & b) assert (a & b & 1).equivalent(a & b) assert str(And(a, 1, simplify=False)) == "And(a, 1)" # associative assert ((a & b) & c & d).equivalent(And(a, b, c, d)) assert (a & (b & c) & d).equivalent(And(a, b, c, d)) assert (a & b & (c & d)).equivalent(And(a, b, c, d)) assert ((a & b) & (c & d)).equivalent(And(a, b, c, d)) assert ((a & b & c) & d).equivalent(And(a, b, c, d)) assert (a & (b & c & d)).equivalent(And(a, b, c, d)) assert (a & (b & (c & d))).equivalent(And(a, b, c, d)) assert (((a & b) & c) & d).equivalent(And(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(Zero) assert (a & ~a).equivalent(Zero)
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'