def _mk_iter(self):
     for _ in range(self.num_subproblems):
         fmla = CNF()
         fmla.from_file(self.cnf_path)
         new_units = random.sample(list(range(1, fmla.nv + 1)),
                                   k=self.random_units)
         new_units = [[random.choice([1, -1]) * x] for x in new_units]
         for unit_clause in new_units:
             fmla.append(unit_clause)
         yield fmla
Esempio n. 2
0
File: graph.py Progetto: Udopia/gbd
def gen_vig(path):
    g = Graph(directed=False)
    cnf = CNF()
    cnf.from_file(path, compressed_with='lzma')
    print("NVars: {}".format(cnf.nv))
    g.add_vertex(cnf.nv + 1)
    w = g.new_edge_property("float")
    for clause in cnf:
        inc = 1.0 / pow(2, len(clause))
        for tup in itertools.combinations(clause, 2):
            e = g.edge(g.vertex(abs(tup[0])), g.vertex(abs(tup[1])), add_missing=True)
            w[e] = w[e] + inc
    return (g, w)
    def extract_datapoint(self,
                          task,
                          produce_derived=False,
                          num_subproblems=0,
                          num_units=0):
        try:
            dump_dir = tempfile.TemporaryDirectory(dir=task.tmpdir)
        except:
            dump_dir = tempfile.TemporaryDirectory()

        with dump_dir as dump_dir_name:
            TOO_BIG_FLAG = False

            cnf = CNF()
            try:
                cnf.from_file(task.cnf_path, compressed_with="use_ext")
            except:
                try:
                    new_cnf_path = simplify_cnf_path(task.cnf_path,
                                                     CLAUSE_LIMIT)
                    cnf.from_file(
                        new_cnf_path, compressed_with="use_ext"
                    )  # circumvent pysat DIMACS parser complaining about invalid DIMACS files
                except:  # shrug
                    return 1, []

            if len(cnf.clauses) == 0 or cnf.nv == 0:
                return 1, []
            try:
                if len(cnf.clauses) > CLAUSE_LIMIT:
                    print(f"PROBLEM WITH {len(cnf.clauses)} CLAUSES TOO BIG")
                    status = -1
                    res = None
                    TOO_BIG_FLAG = True
                else:
                    res = gen_lbdp(tempfile.TemporaryDirectory(),
                                   cnf,
                                   dump_dir=(dump_dir_name + "/"),
                                   dumpfreq=self.dumpfreq,
                                   timeout=self.timeout,
                                   clause_limit=CLAUSE_LIMIT)
                    glue_cutoff = 50
                    if np.sum(res.glue_counts) <= glue_cutoff:
                        print(
                            f"[WARNING] PROBLEM HAS FEWER THAN {glue_cutoff} GLUE COUNTS, DISCARDING"
                        )
                        return 1, []
                    status = 0
            except FileNotFoundError as e:
                print("[WARNING]: FILE NOT FOUND", e)
                print("TASK TYPE: ", task.task_type)
                print("TASK ORIGINAL CNF ", task.original_cnf_path)
                status = 1
            except Exception as e:
                print("[WARNING]: EXITING GEN_LBDP DUE TO EXCEPTION", e)
                status = 1

            if status == 1:
                print(
                    f"FORMULA {task.cnf_path} SATISFIABLE OR ERROR RAISED, DISCARDING"
                )
                return status, []
            elif status == -1:  # UNKNOWN i.e. timed out, so split the problem
                child_paths = []
                print(f"SPLITTING CNF WITH {cnf.nv} AND {len(cnf.clauses)}")
                subproblem_random_units = 3
                if TOO_BIG_FLAG:
                    subproblem_random_units += math.ceil(
                        math.log((len(cnf.clauses) - CLAUSE_LIMIT), 2))
                num_tries = 0
                while True:
                    try:
                        print("SPLITTING WITH RANDOM UNITS: ",
                              subproblem_random_units)
                        if num_tries > 30 or subproblem_random_units >= cnf.nv:
                            print(
                                "NUM TRIES OR RANDOM UNITS EXCEEDED LIMIT, STOPPING"
                            )
                            break
                        for subproblem in Subproblems(
                                task.cnf_path,
                                num_subproblems=num_subproblems,
                                random_units=subproblem_random_units):
                            print("ENTERING SUBPROBLEM LOOP")
                            subproblem_path = os.path.join(
                                task.tmpdir, (str(uuid.uuid4()) + ".cnf.gz"))
                            subproblem.to_file(subproblem_path,
                                               compress_with="gzip")
                            try:
                                new_path = simplify_cnf_path(
                                    subproblem_path, CLAUSE_LIMIT)
                                with open(new_path, "r") as f:
                                    header = f.readline().split()[2:]
                                print("HEADER", header)
                                n_clauses = int(header[1])
                                if n_clauses > CLAUSE_LIMIT:
                                    raise IndexError(
                                        f"CLAUSE LIMIT {CLAUSE_LIMIT} EXCEEDED BY N_CLAUSES {n_clauses}"
                                    )
                                if n_clauses == 0:
                                    continue
                                child_paths.append(new_path)
                            except IndexError as e:
                                print("SIMPLIFY CNF FOUND NO SIMPLIFIED CNF")
                                print(e)
                                raise IndexError
                            except Exception as e:
                                print(
                                    "SIMPLIFY CNF PATH FAILED FOR SOME OTHER REASON"
                                )
                                print(e)
                                print("BAD PROBLEM: ", task.original_cnf_path)
                    except IndexError:
                        print("CAUGHT INDEXERROR, INCREMENTING RANDOM UNITS")
                        num_tries += 1
                        subproblem_random_units += (num_tries**2)
                        continue
                    break

                print(
                    f"SPLIT FORMULA INTO {len(child_paths)} SUBPROBLEMS: {child_paths}"
                )

                return status, child_paths
            else:
                self.writer_handle.write.remote(res)

                child_paths = []

                if produce_derived:
                    dumps = recursively_get_files(dump_dir_name,
                                                  forbidden=["bz2", "xz"],
                                                  exts=["cnf", "gz"])
                    print("GOT DUMPS: ", dumps)
                    for cnf_path in dumps:
                        try:
                            moved = shutil.move(
                                cnf_path,
                                os.path.join(task.tmpdir,
                                             str(uuid.uuid4()) + ".cnf"))
                            print(f"APPENDING DUMPED CNF: {moved}")
                            child_paths.append(moved)
                        except:
                            print("[WARNING] SOMETHING WENT TERRIBLY WRONG")

                if num_subproblems > 0 and task.task_type == 1:
                    subproblem_random_units = 3
                    while True:
                        try:
                            if subproblem_random_units > 15:
                                break
                            for subproblem in Subproblems(
                                    task.cnf_path,
                                    num_subproblems=num_subproblems,
                                    random_units=subproblem_random_units):
                                subproblem_path = os.path.join(
                                    task.tmpdir,
                                    (str(uuid.uuid4()) + ".cnf.gz"))
                                subproblem.to_file(subproblem_path,
                                                   compress_with="gzip")
                                try:
                                    new_path = simplify_cnf_path(
                                        subproblem_path, CLAUSE_LIMIT)
                                    child_paths.append(new_path)
                                except IndexError as e:
                                    print(
                                        "SIMPLIFY CNF FOUND NO SIMPLIFIED CNF")
                                    print(e)
                                    raise IndexError
                                except Exception as e:
                                    print(
                                        "SIMPLIFY CNF PATH FAILED FOR SOME OTHER REASON"
                                    )
                                    print(e)
                                    print("BAD PROBLEM: ",
                                          task.original_cnf_path)
                        except IndexError:
                            print(
                                "CAUGHT INDEXERROR, INCREMENTING RANDOM UNITS")
                            subproblem_random_units += 1
                            continue
                        break

            print("RETURNING CHILD PATHS", child_paths)
        return status, child_paths