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
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