def _baseCase(self, lits, bound, implicationVars):
        coeffs, rhs = self._plainAdded(lits, bound)
        if self._canBeAddedPlain(coeffs, rhs, bound):
            # we can just add all clauses of the right size
            ineq = fe.GEQ([(1, x) for x in lits], bound)

            clauses = fe.transformToCNF(ineq)
            clauses = fe.And([fe.GEQ([(1, x) for x in c], 1) for c in clauses])

            # add hint on the divisor for testing
            clauses.divisor = coeffs

            numClauses = len(clauses)

            for a, x in implicationVars:
                if a == bound:
                    # small trick for nicer looking constraints. While this
                    # will not sum up to divisor * a it will still be a after
                    # division and rounding up
                    r = 0
                    value = 1
                else:
                    # summing everything up should yield divisor * a
                    afterSum = abs(a) * clauses.divisor
                    r = afterSum % numClauses
                    value = afterSum // numClauses

                for c in clauses:
                    if r > 0:
                        coeff = value + 1
                        r -= 1
                    else:
                        coeff = value
                    coeff = int(math.copysign(coeff, a))
                    if coeff != 0:
                        c.terms.append((coeff, x))

            # add vars for cancelation
            cancel = self.cancelationTerms(numClauses)
            for clause, extension in zip(clauses, cancel):
                clause.terms.extend(extension)

            return clauses
        else:
            return None
Пример #2
0
    def addRowConstraint(self, i):
        T = [j for j in range(self.numCols) if self.a[i][j] != 1]
        if len(T) == 0:
            return super().addRowConstraint(i)
        R = [j for j in range(self.numCols) if self.a[i][j] == 1]
        middle = len(R) // 2
        F = R[:middle]
        S = R[middle:]

        result = fe.And()
        result.append(
            fe.GEQ([(self.r[i], self.h(i))] +
                   [(self.a[i][j], self.x(i, j)) for j in T] +
                   [(self.a[i][j], self.x(i, j)) for j in F], self.r[i]))

        result.append(
            fe.GEQ([(self.r[i], fe.Not(self.h(i)))] +
                   [(self.a[i][j], self.x(i, j)) for j in T] +
                   [(self.a[i][j], self.x(i, j)) for j in S], self.r[i]))

        return result
Пример #3
0
 def addRowConstraint(self, i):
     return fe.GEQ([(self.a[i][j], self.x(i, j)) for j in range(self.numCols)], self.r[i])
Пример #4
0
 def addRowConstraint(self, i):
     def f(x): return x if x == 1 else 2 * x
     return fe.GEQ([(f(self.a[i][j]), self.x(i, j)) for j in range(self.numCols)], self.r[i])
def main():
    v = DisplayResult()
    transform = TransformToCNFWithRecoveryTree()
    f = fe.GEQ([(1, "x%i" % i) for i in range(4)], 2)
    # f = fe.LEQ([(1, "x%i"%i) for i in range(6)], 3)
    v.visit(transform(f))