Пример #1
0
    def solve(self, cnf):
        s = Solution()

        infile = NamedTemporaryFile(mode='w')
        outfile = NamedTemporaryFile(mode='r')

        io = DimacsCnf()
        infile.write(io.tostring(cnf))
        infile.flush()

        ret = call(self.command % (infile.name, outfile.name), shell=True)

        infile.close()

        if ret != 10:
            return s

        s.success = True

        lines = outfile.readlines()[1:]

        for line in lines:
            varz = line.split(" ")[:-1]
            for v in varz:
                v = v.strip()
                value = v[0] != '-'
                v = v.lstrip('-')
                vo = io.varobj(v)
                s.varmap[vo] = value

        # Close deletes the tmp files
        outfile.close()

        return s
Пример #2
0
    def solve(self, cnf):
        s = Solution()

        infile = NamedTemporaryFile(mode='w')
        outfile = NamedTemporaryFile(mode='r')

        io = DimacsCnf()
        infile.write(io.tostring(cnf))
        infile.flush()

        ret = call(self.command % (infile.name, outfile.name), shell=True)

        infile.close()

        if ret != 10:
            return s

        s.success = True

        lines = outfile.readlines()[1:]

        for line in lines:
            varz = line.split(" ")[:-1]
            for v in varz:
                v = v.strip()
                value = v[0] != '-'
                v = v.lstrip('-')
                vo = io.varobj(v)
                s.varmap[vo] = value

        # Close deletes the tmp files
        outfile.close()

        return s
Пример #3
0
    def build_model(self):

        nproc = self._instance.nproc
        nmach = self._instance.nmach
        nserv = self._instance.nserv
        nneigh = len(self._instance.N)
        nloc = len(self._instance.L)

        P = self._instance.P
        M = self._instance.M
        S = self._instance.S
        N = self._instance.N
        L = self._instance.L

        io = DimacsCnf()

        self.x = np.empty((nproc, nmach), dtype=object)
        for p in P:
            for m in M:
                self.x[p, m] = Variable('x[%d,%d]' % (p, m))

        # proc alloc
        all_proc_expr = Cnf()

        for p in P:
            p_expr1 = Cnf()
            p_expr2 = Cnf()
            p_expr3 = Cnf()

            for m1 in M:
                if any(self._instance.R[p] > self._instance.C[m1]):
                    p_expr1 &= -self.x[p, m1]
                else:
                    p_expr1 |= self.x[p, m1]

                    for m2 in range(m1 + 1, nmach):
                        p_expr2 &= self.x[p, m1] >> -self.x[p, m2]

            all_proc_expr &= p_expr1 & p_expr2 & p_expr3

        self.global_expr &= all_proc_expr

        # conflict
        all_conflict_expr = Cnf()

        for m in M:
            for s in S:
                if len(S[s]) == 1: continue
                conflict_expr = Cnf()
                for p1 in range(len(S[s])):
                    for p2 in range(p1 + 1, len(S[s])):
                        conflict_expr &= self.x[S[s][p1],
                                                m] >> -self.x[S[s][p2], m]
                all_conflict_expr &= conflict_expr

        self.global_expr &= all_conflict_expr
Пример #4
0
    def solve(self, cnf):
        s = Solution()

        # NamedTemporaryFile doesn't work on Windows, see https://stackoverflow.com/questions/15169101/how-to-create-a-temporary-file-that-can-be-read-by-a-subprocess
        infile, infilename = tempfile.mkstemp(suffix="cnf")

        try:
            io = DimacsCnf()
            os.write(infile, io.tostring(cnf))
            os.close(infile)

            try:
                cmd = self.command % (infilename.replace("\\", "/"))
                check_output(cmd, stderr=STDOUT, shell=True)
            # Lingeling and most SAT-solvers use a non-zero return code, which in most POSIX command indicates an error.
            # That's why python raises an exception, but here it's expected
            except CalledProcessError as call:
                if call.returncode != 10 and call.returncode != 20:
                    s.error = call.output
                    return s
        finally:
            os.remove(infilename)

        if call.returncode != 10:
            return s

        s.success = True

        for line in call.output.split("\n"):
            # Solution line example: v 1 -2 3 -4 5 6 0
            if len(line) > 0 and line[0] == 'v':
                varz = line.split(" ")[1:-1]
                for v in varz:
                    v = v.strip()
                    value = v[0] != '-'
                    v = v.lstrip('-')
                    vo = io.varobj(v)
                    s.varmap[vo] = value

        return s
Пример #5
0
    def solve(self, cnf):
        s = Solution()

        # NamedTemporaryFile doesn't work on Windows, see https://stackoverflow.com/questions/15169101/how-to-create-a-temporary-file-that-can-be-read-by-a-subprocess
        infile, infilename = tempfile.mkstemp(suffix="cnf")

        try:
            io = DimacsCnf()
            os.write(infile, io.tostring(cnf))
            os.close(infile)

            try:
                cmd = self.command % (infilename.replace("\\","/"))
                check_output(cmd, stderr=STDOUT, shell=True)
            # Lingeling and most SAT-solvers use a non-zero return code, which in most POSIX command indicates an error.
            # That's why python raises an exception, but here it's expected
            except CalledProcessError as call:
                if call.returncode != 10 and call.returncode != 20:
                    s.error = call.output
                    return s
        finally:
            os.remove(infilename)

        if call.returncode != 10:
            return s

        s.success = True

        for line in call.output.split("\n"):
            # Solution line example: v 1 -2 3 -4 5 6 0
            if len(line) > 0 and line[0] == 'v':
                varz = line.split(" ")[1:-1]
                for v in varz:
                    v = v.strip()
                    value = v[0] != '-'
                    v = v.lstrip('-')
                    vo = io.varobj(v)
                    s.varmap[vo] = value

        return s
Пример #6
0
    def solve(self, cnf):

        s = Solution()

        with NamedTemporaryFile(mode='w') as infile, \
             NamedTemporaryFile(mode='r') as outfile:

            io = DimacsCnf()

            infile.write(io.tostring(cnf))
            infile.flush()

            try:
                output = check_output(
                    [self.command, infile.name, outfile.name],
                    universal_newlines=True, timeout=self.timeout)
            except CalledProcessError as ex:
                s.success = (ex.returncode == 10)
                output = ex.output

            s.stats = parse_stats(output)

            if not s.success:
                return s

            lines = outfile.readlines()[1:]

            for line in lines:
                varz = line.split(" ")[:-1]
                for v in varz:
                    v = v.strip()
                    value = v[0] != '-'
                    v = v.lstrip('-')
                    vo = io.varobj(v)
                    s.varmap[vo] = value

        return s
Пример #7
0
from satispy import Variable, Cnf
from satispy.solver import Minisat
from satispy.io import DimacsCnf

with open("example.dimacs", "r") as satfile:
    s = satfile.read().rstrip("\n")
    exp = DimacsCnf().fromstring(s)

print(exp)

solver = Minisat()
solution = solver.solve(exp)

if solution.success:
    print("Found a solution:")
    for v in solution.varmap:
        print(v.name + ": " + str(solution[v]))
else:
    print("The expression cannot be satisfied")
Пример #8
0
def sat(instance):
    expr = Cnf()

    nproc = instance.nproc
    nmach = instance.nmach
    nserv = instance.nserv
    nneigh = len(instance.N)
    nloc = len(instance.L)

    P = instance.P
    M = instance.M
    S = instance.S
    N = instance.N
    L = instance.L

    print(" %10.3f creating vars - x" % (time() - all_start))
    x = np.empty((nproc, nmach), dtype=object)
    for p in P:
        for m in M:
            x[p, m] = Variable('x[%d,%d]' % (p, m))

    print(" %10.3f creating vars - h" % (time() - all_start))
    h = np.empty((nserv, nneigh), dtype=object)
    for s in S:
        for n in N:
            h[s, n] = Variable('h[%d,%d]' % (s, n))

    print(" %10.3f creating vars - o" % (time() - all_start))
    o = np.empty((nserv, nloc), dtype=object)
    for s in S:
        for l in L:
            o[s, l] = Variable('o[%d,%d]' % (s, l))

    print(" %10.3f H[s,n]" % (time() - all_start))
    for s in S:
        #print(" %10.3f H[%6d,n]" %( time() - all_start,s))
        for n in N:
            pres_expr = Cnf()
            for p in S[s]:
                for m in N[n]:
                    pres_expr |= x[p, m]

            expr &= h[s, n] >> pres_expr
            expr &= pres_expr >> h[s, n]
            for sd in instance.sdep[s]:
                expr &= h[s, n] >> h[sd, n]

    print(" %10.3f O[s,l]" % (time() - all_start))
    for s in S:
        #print(" %10.3f O[%6d,l]" %( time() - all_start,s))
        if instance.delta[s] == 1: continue
        for l in L:
            pres_expr = Cnf()
            for p in S[s]:
                for m in L[l]:
                    pres_expr |= x[p, m]

            expr &= o[s, l] >> pres_expr
            expr &= pres_expr >> o[s, l]

    print(" %10.3f X[p,m]" % (time() - all_start))

    for p in P:
        #print(" %10.3f X[%6d, m]" %( time() - all_start, p))
        p_constr1 = Cnf()
        p_constr2 = Cnf()
        for m in M:
            p_constr1 |= x[p, m]

            for m2 in range(m + 1, nmach):
                p_constr2 &= x[p, m] >> -x[p, m2]
        expr &= p_constr1 & p_constr2

    print(" %10.3f X[p,m] - conflito" % (time() - all_start))

    for m in M:
        for s in S:
            conf_constr = Cnf()
            if len(S[s]) == 1: continue
            for i1 in range(len(S[s])):
                for i2 in range(i1 + 1, len(S[s])):
                    conf_constr &= x[S[s][i1], m] >> -x[S[s][i2], m]
            expr &= conf_constr

    print(" %10.3f solving" % (time() - all_start))

    io = DimacsCnf()
    #s = io.tostring(expr)
    #print(s)
    solver = Minisat('minisat %s %s')

    solution = solver.solve(expr)
    print(" %10.3f done" % (time() - all_start))

    if not solution.success:
        print(" %10.3f sem solucao" % (time() - all_start))
        exit(0)

    print(" %10.3f solucao" % (time() - all_start))

    xsol = np.empty((nproc, nmach), dtype=np.int32)
    for p in P:
        for m in M:
            #print(p,m,solution[x[p,m]])
            #print(io.varname(x[p,m]))
            xsol[p, m] = solution[x[p, m]]

    print(xsol)
    print(np.all(xsol.sum(axis=1) == 1))
    for m in M:
        print(instance.mach_validate(m, xsol[:, m]))
def propositional_nqueens(n):

    rules = 0
    t1 = time()
    exprs = Cnf()
    queens_by_point = {}
    queens_by_name = {}
    points_by_name = {}

    by_rows = [[] for x in xrange(n)]
    by_cols = [[] for x in xrange(n)]

    for point in points(n):
        name = 'queen_%d_%d' % point

        by_rows[point[1]].append(name)
        by_cols[point[0]].append(name)

        queen = Variable(name)
        queens_by_point[point] = queen
        queens_by_name[name] = queen
        points_by_name[name] = point

    for row_of_names in by_rows:
        orexp = Cnf()
        for name in row_of_names:
            orexp = orexp | queens_by_name[name]

        rules += 1
        exprs &= orexp

    for col_of_names in by_cols:
        orexp = Cnf()
        for name in col_of_names:
            orexp |= queens_by_name[name]

        rules += 1
        exprs &= orexp

    for row in xrange(n):
        for col in xrange(n):
            antecedent_name = by_rows[row][col]
            consequent_names = [by_rows[row][a] for a in xrange(n) if a != col]

            # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2))
            # translates to
            # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2))

            #andexpr = Cnf()
            #for name in consequent_names:
                #andexpr &= (-queens_by_name[name])

            #exprs &= (queens_by_name[antecedent_name] >> andexpr)

            for name in consequent_names:
                rules += 1
                exprs &= -queens_by_name[antecedent_name] | -queens_by_name[name]

    for col in xrange(n):
        for row in xrange(n):
            antecedent_name = by_cols[col][row]
            consequent_names = [by_cols[col][a] for a in xrange(n) if a != row]

            # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2))
            # translates to
            # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2))
            #andexpr = Cnf()
            #for name in consequent_names:
                #andexpr &= (-queens_by_name[name])

            #exprs &= (queens_by_name[antecedent_name] >> andexpr)

            for name in consequent_names:
                rules += 1
                exprs &= -queens_by_name[antecedent_name] | -queens_by_name[name]

    for point1 in points(n):
        for point2 in points(n):
            if point1 == point2:
                continue

            if are_diagonal(point1, point2):
                rules += 1
                #exprs &= (queens_by_point[point1] >> (-queens_by_point[point2]))
                exprs &= -queens_by_point[point1] | -queens_by_point[point2]

    for point in points(n):
        for slope in points(n, 1, 1):

            if slope == (1,1):
                continue

            lines = [ ]
            line = points_along_line(point, slope[0], slope[1], n)

            if len(line) >= 2:
                lines.append(line)

            line = points_along_line(point, -slope[0], slope[1], n)

            if len(line) >= 2:
                lines.append(line)


            if len(lines) == 0:
                continue

            for points1 in lines:
                for point1 in points1:
                    #andexpr = Cnf()
                    for point2 in points1:
                        if point2 != point1:
                            #andexpr &= (-queens_by_point[point2])
                            rules += 1
                            exprs &= -queens_by_point[point] | -queens_by_point[point1] | -queens_by_point[point2]

                    #exprs &= ((queens_by_point[point] & queens_by_point[point1]) >> andexpr)
    t2 = time()
    print('# defined %d rules in %f seconds' % (rules, t2 - t1))
    t1 = time()

    with open('/media/rust/%d.cnf' % n, 'w') as f:
        io = DimacsCnf()
        f.write(io.tostring(exprs))

    t2 = time()
    print('# wrote rules in %f seconds' % (t2 - t1))
    t1 = time()
    #return
    s = Minisat()
    #s = Lingeling(command='/home/bburns/projects/nqueens-solver/lingeling-bal-2293bef-151109/lingeling --witness=1 --verbose=1 %s')
    solution = s.solve(exprs)
    t2 = time()
    print('# solved in %f seconds' % (t2 - t1))

    if solution.error:
        raise Exception(solution.error)

    if solution.success:
        results = []

        #for a in solution.varmap:
            #if solution.varmap[a]:
                #results.append(points_by_name[a.name])
        for point in queens_by_point:
            if solution[queens_by_point[point]]:
                results.append(point)

        results.sort()

        return results
    else:
        raise Exception('Unsat.')
def propositional_nqueens(n):

    rules = 0
    t1 = time()
    exprs = Cnf()
    queens_by_point = {}
    queens_by_name = {}
    points_by_name = {}

    by_rows = [[] for x in xrange(n)]
    by_cols = [[] for x in xrange(n)]

    for point in points(n):
        name = 'queen_%d_%d' % point

        by_rows[point[1]].append(name)
        by_cols[point[0]].append(name)

        queen = Variable(name)
        queens_by_point[point] = queen
        queens_by_name[name] = queen
        points_by_name[name] = point

    for row_of_names in by_rows:
        orexp = Cnf()
        for name in row_of_names:
            orexp = orexp | queens_by_name[name]

        rules += 1
        exprs &= orexp

    for col_of_names in by_cols:
        orexp = Cnf()
        for name in col_of_names:
            orexp |= queens_by_name[name]

        rules += 1
        exprs &= orexp

    for row in xrange(n):
        for col in xrange(n):
            antecedent_name = by_rows[row][col]
            consequent_names = [by_rows[row][a] for a in xrange(n) if a != col]

            # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2))
            # translates to
            # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2))

            #andexpr = Cnf()
            #for name in consequent_names:
            #andexpr &= (-queens_by_name[name])

            #exprs &= (queens_by_name[antecedent_name] >> andexpr)

            for name in consequent_names:
                rules += 1
                exprs &= -queens_by_name[antecedent_name] | -queens_by_name[
                    name]

    for col in xrange(n):
        for row in xrange(n):
            antecedent_name = by_cols[col][row]
            consequent_names = [by_cols[col][a] for a in xrange(n) if a != row]

            # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2))
            # translates to
            # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2))
            #andexpr = Cnf()
            #for name in consequent_names:
            #andexpr &= (-queens_by_name[name])

            #exprs &= (queens_by_name[antecedent_name] >> andexpr)

            for name in consequent_names:
                rules += 1
                exprs &= -queens_by_name[antecedent_name] | -queens_by_name[
                    name]

    for point1 in points(n):
        for point2 in points(n):
            if point1 == point2:
                continue

            if are_diagonal(point1, point2):
                rules += 1
                #exprs &= (queens_by_point[point1] >> (-queens_by_point[point2]))
                exprs &= -queens_by_point[point1] | -queens_by_point[point2]

    for point in points(n):
        for slope in points(n, 1, 1):

            if slope == (1, 1):
                continue

            lines = []
            line = points_along_line(point, slope[0], slope[1], n)

            if len(line) >= 2:
                lines.append(line)

            line = points_along_line(point, -slope[0], slope[1], n)

            if len(line) >= 2:
                lines.append(line)

            if len(lines) == 0:
                continue

            for points1 in lines:
                for point1 in points1:
                    #andexpr = Cnf()
                    for point2 in points1:
                        if point2 != point1:
                            #andexpr &= (-queens_by_point[point2])
                            rules += 1
                            exprs &= -queens_by_point[point] | -queens_by_point[
                                point1] | -queens_by_point[point2]

                    #exprs &= ((queens_by_point[point] & queens_by_point[point1]) >> andexpr)
    t2 = time()
    print('# defined %d rules in %f seconds' % (rules, t2 - t1))
    t1 = time()

    with open('/media/rust/%d.cnf' % n, 'w') as f:
        io = DimacsCnf()
        f.write(io.tostring(exprs))

    t2 = time()
    print('# wrote rules in %f seconds' % (t2 - t1))
    t1 = time()
    #return
    s = Minisat()
    #s = Lingeling(command='/home/bburns/projects/nqueens-solver/lingeling-bal-2293bef-151109/lingeling --witness=1 --verbose=1 %s')
    solution = s.solve(exprs)
    t2 = time()
    print('# solved in %f seconds' % (t2 - t1))

    if solution.error:
        raise Exception(solution.error)

    if solution.success:
        results = []

        #for a in solution.varmap:
        #if solution.varmap[a]:
        #results.append(points_by_name[a.name])
        for point in queens_by_point:
            if solution[queens_by_point[point]]:
                results.append(point)

        results.sort()

        return results
    else:
        raise Exception('Unsat.')
Пример #11
0
    for i in range(args.clause):
        c = Cnf()

        k = sample(v, args.literal)
        for j in k:
            if random() >= 0.5:
                c |= j
            else:
                c |= -j
        exp &= c

    solver = Minisat()
    solution = solver.solve(exp)

    dimacsCnf = DimacsCnf()
    print(dimacsCnf.tostring(exp))
    if solution.error != False:
        print("Error:")
        print(solution.error)

    elif solution.success:
        print("Success:")
        for i in range(args.variable):
            print(v[i], solution[v[i]])

        fo = open('%s.in' % (args.file_name), "w")
        fo.write(dimacsCnf.tostring(exp))
        fo.close()

        fo = open('answer.dat', "w")