Example #1
0
 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)
Example #2
0
 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)
Example #3
0
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
Example #4
0
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