Example #1
0
 def test_weighted_leq(self) :
     opb="""\
     * #variable= 5 #constraint= 1
     *
     -1 x1 -2 x2 -3 x3 +1 x4 +2 x5 >= -2;
     """
     F=CNF()
     F.add_linear(1,"a",2,"b",3,"c",-1,"d",-2,"e","<=",2)
     self.assertCnfEqualsOPB(F,opb)
Example #2
0
 def test_weighted_gt(self) :
     opb="""\
     * #variable= 5 #constraint= 1
     *
     +1 x1 +2 x2 +3 x3 -1 x4 -2 x5 >= 3;
     """
     F=CNF()
     F.add_linear(1,"a",2,"b",3,"c",-1,"d",-2,"e",">",2)
     self.assertCnfEqualsOPB(F,opb)
Example #3
0
 def test_weighted_leq(self):
     opb = """\
     * #variable= 5 #constraint= 1
     *
     -1 x1 -2 x2 -3 x3 +1 x4 +2 x5 >= -2;
     """
     F = CNF()
     F.add_linear(1, "a", 2, "b", 3, "c", -1, "d", -2, "e", "<=", 2)
     self.assertCnfEqualsOPB(F, opb)
Example #4
0
 def test_weighted_gt(self):
     opb = """\
     * #variable= 5 #constraint= 1
     *
     +1 x1 +2 x2 +3 x3 -1 x4 -2 x5 >= 3;
     """
     F = CNF()
     F.add_linear(1, "a", 2, "b", 3, "c", -1, "d", -2, "e", ">", 2)
     self.assertCnfEqualsOPB(F, opb)
Example #5
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
Example #6
0
class XorCard():
    """ Formula encoding Ax = b mod 2 and 1^Tx >= k for random A in R^mxn,b^m

    Personal Note: according to Kuldeep Meel these have various interesting
    applications for this kind of benchmarks. There will be a
    publication in SAT 2019 about this kind of formula.
    """

    def __init__(self, m, n, k, eq, encoding):
        self.m = m
        self.n = n
        self.k = k
        self.eq = eq
        self.encoding = encoding
        self.numXor = 0

    def x(self, i):
        return "x_%i"%(i)

    def h(self, i,j):
        return "h_(%i,%i)"%(i,j)

    def addXor(self, terms, value):
        w = len(terms)
        k = w // 2

        if k > 0:
            if self.encoding == "extendedPBAnyHelper":
                for i in range(k):
                    helper = ("xor_helper", i, self.numXor)
                    self.f.add_variable(helper)
                    terms.append((2, helper))
            elif self.encoding == "extendedPBOneHelper":
                helpers = list()
                for i in range(k):
                    helper = ("xor_helper", i, self.numXor)
                    helpers.append(helper)
                    self.f.add_variable(helper)
                    terms.append(((i+1)*2, helper))
                self.f.add_linear(*toArgs([(1, x) for x in helpers], "<=", 1))
            elif self.encoding == "extendedPBExpHelper":
                for i in range(math.ceil(math.log(k, 2)) + 1):
                    helper = ("xor_helper", i, self.numXor)
                    self.f.add_variable(helper)
                    terms.append((2**i * 2, helper))
            else:
                raise ValueError("Invalid encoding '%s'" % encoding)

        degree = 2 * k + (value % 2)
        self.f.add_linear(*toArgs(terms, "==", degree))
        self.numXor += 1

    def __call__(self):
        mn = self.m * self.n
        A = [0, 1] * (mn // 2) + [0] * (mn % 2)
        random.shuffle(A)
        A = [[A[i * self.n + j] for j in range(self.n)] for i in range(self.m)]
        b = [0, 1] * (self.m // 2) + [0] * (self.m % 2)


        self.f = CNF()

        terms = [(-1, self.x(i)) for i in range(self.n)]
        if self.eq:
            self.f.add_linear(*toArgs(terms, "==", -self.k))
        else:
            self.f.add_linear(*toArgs(terms, ">=", -self.k))

        for i in range(self.m):
            terms = [(1, self.x(j)) for j in range(self.n) if A[i][j] == 1]
            if len(terms) > 0:
                self.addXor(terms, b[i])

        return self.f
Example #7
0
 def test_bogus(self) :
     F=CNF()
     with self.assertRaises(ValueError):
         F.add_linear(1,"a",2,"b",3,"c",-1,"d",-2,"e","??",2)
Example #8
0
 def test_bogus(self):
     F = CNF()
     with self.assertRaises(ValueError):
         F.add_linear(1, "a", 2, "b", 3, "c", -1, "d", -2, "e", "??", 2)