def test_parity(self): opb = """\ * #variable= 3 #constraint= 4 * +1 x1 +1 x2 +1 x3 >= 1; +1 x1 -1 x2 -1 x3 >= -1; -1 x1 +1 x2 -1 x3 >= -1; -1 x1 -1 x2 +1 x3 >= -1; """ F = CNF() F.add_parity(["a", "b", "c"], 1) self.assertCnfEqualsOPB(F, opb)
def test_parity(self) : opb="""\ * #variable= 3 #constraint= 4 * +1 x1 +1 x2 +1 x3 >= 1; +1 x1 -1 x2 -1 x3 >= -1; -1 x1 +1 x2 -1 x3 >= -1; -1 x1 -1 x2 +1 x3 >= -1; """ F=CNF() F.add_parity(["a","b","c"],1) self.assertCnfEqualsOPB(F,opb)
def TseitinFormula(graph,charges=None): """Build a Tseitin formula based on the input graph. Odd charge is put on the first vertex by default, unless other vertices are is specified in input. Arguments: - `graph`: input graph - `charges': odd or even charge for each vertex """ V=enumerate_vertices(graph) if charges==None: charges=[1]+[0]*(len(V)-1) # odd charge on first vertex else: charges = [bool(c) for c in charges] # map to boolean if len(charges)<len(V): charges=charges+[0]*(len(V)-len(charges)) # pad with even charges # init formula tse=CNF() edgename = { } for (u,v) in sorted(graph.edges(),key=sorted): edgename[(u,v)] = "E_{{{0},{1}}}".format(u,v) edgename[(v,u)] = "E_{{{0},{1}}}".format(u,v) tse.add_variable(edgename[(u,v)]) tse.mode_strict() # add constraints for v,charge in zip(V,charges): # produce all clauses and save half of them names = [ edgename[(u,v)] for u in neighbors(graph,v) ] tse.add_parity(names,charge) return tse
def TseitinFormula(graph, charges=None, encoding=None): """Build a Tseitin formula based on the input graph. Odd charge is put on the first vertex by default, unless other vertices are is specified in input. Arguments: - `graph`: input graph - `charges': odd or even charge for each vertex """ V = enumerate_vertices(graph) if charges == None: charges = [1] + [0] * (len(V) - 1) # odd charge on first vertex else: charges = [bool(c) for c in charges] # map to boolean if len(charges) < len(V): charges = charges + [0] * (len(V) - len(charges) ) # pad with even charges # init formula tse = CNF() edgename = {} for (u, v) in sorted(graph.edges(), key=sorted): edgename[(u, v)] = "E_{{{0},{1}}}".format(u, v) edgename[(v, u)] = "E_{{{0},{1}}}".format(u, v) tse.add_variable(edgename[(u, v)]) tse.mode_strict() # add constraints for v, charge in zip(V, charges): # produce all clauses and save half of them names = [edgename[(u, v)] for u in neighbors(graph, v)] if encoding == None: tse.add_parity(names, charge) else: def toArgs(listOfTuples, operator, degree): return list(sum(listOfTuples, ())) + [operator, degree] terms = list(map(lambda x: (1, x), names)) w = len(terms) k = w // 2 if encoding == "extendedPBAnyHelper": for i in range(k): helper = ("xor_helper", i, v) tse.add_variable(helper) terms.append((2, helper)) elif encoding == "extendedPBOneHelper": helpers = list() for i in range(k): helper = ("xor_helper", i, v) helpers.append(helper) tse.add_variable(helper) terms.append(((i + 1) * 2, helper)) tse.add_linear(*toArgs([(1, x) for x in helpers], "<=", 1)) elif encoding == "extendedPBExpHelper": for i in range(math.ceil(math.log(k, 2)) + 1): helper = ("xor_helper", i, v) tse.add_variable(helper) terms.append((2**i * 2, helper)) else: raise ValueError("Invalid encoding '%s'" % encoding) degree = 2 * k + (charge % 2) tse.add_linear(*toArgs(terms, "==", degree)) return tse