Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 3
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
Ejemplo n.º 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
Ejemplo n.º 5
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
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.')
Ejemplo n.º 8
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")
        for i in range(args.variable):