コード例 #1
0
ファイル: cnf_io.py プロジェクト: AndreKobaek/k-sat
def read_cnf_file(filename: str) -> CNF:
    with open(filename, "r") as cnfFile:
        lines = list(filter(lambda line: line.strip(), cnfFile.readlines()))
    cnf = CNF()
    cnf.clauses = list(list())
    for line in lines:
        if len(line) > 20 and line[:20] == "c automorphism group":
            cnf.automorphism_group_size = int(line.split()[-1])
        elif line[0] == "c":
            continue
        elif line[0] == "p":
            metadata = line.split()
            cnf.number_of_literals = int(metadata[2])
            cnf.number_of_clauses = int(metadata[3])
        else:
            cnf.clauses.append([int(x) for x in line.split()[:-1]])
    return cnf
コード例 #2
0
def produce_cnf(
    problemType: str,
    pattern_filename: str,
    graph_filename: str,
    target_dir: str = suggested_dir,
    compute_automorph_size=True,
) -> str:
    cnf_file_name = "{}/cnf-{}-h-{}-g-{}.cnf".format(
        target_dir,
        problemType.strip("--"),
        pattern_filename.split("/")[-1].split(".")[0],
        graph_filename.split("/")[-1].split(".")[0],
    )
    # if file already exists, return filename.
    if path.isfile(cnf_file_name):
        return cnf_file_name
    # read input files
    pattern = read_graph(pattern_filename)
    graph = read_graph(graph_filename)
    # create CNF:
    cnf = CNF(number_of_literals=pattern.number_of_verticies *
              graph.number_of_verticies,
              clauses=list(list()))

    def pair(a: int, v: int) -> int:
        return (a - 1) * graph.number_of_verticies + v

    # adding clauses to guarantee that each a is mapped to at least one vertex
    for a in range(1, pattern.number_of_verticies + 1):
        cnf.clauses.append(
            list(pair(a, v) for v in range(1, graph.number_of_verticies + 1)))

    for a in range(1, pattern.number_of_verticies + 1):
        for v in range(1, graph.number_of_verticies + 1):
            for w in range(v + 1, graph.number_of_verticies + 1):
                cnf.clauses.append([-pair(a, v), -pair(a, w)])

    # dictionary, to use for finding non existant pairs:

    non_existant_pairs = {}
    for i in range(1, graph.number_of_verticies + 1):
        non_existant_pairs[i] = list(range(i, graph.number_of_verticies + 1))

    for v, w in graph.edges:
        assert v < w
        non_existant_pairs[v].remove(w)

    for a, b in pattern.edges:
        for v, ws in non_existant_pairs.items():
            for w in ws:
                cnf.clauses.append([-pair(a, v), -pair(b, w)])
                if pair(a, v) != pair(a, w) or pair(b, w) != pair(b, v):
                    cnf.clauses.append([-pair(a, w), -pair(b, v)])

    # changed second pair to negative, not in the SS notes.
    if problemType == "--emb":
        for v in range(1, graph.number_of_verticies + 1):
            for a in range(1, pattern.number_of_verticies + 1):
                for b in range(a + 1, pattern.number_of_verticies + 1):
                    clause = [-pair(a, v), -pair(b, v)]
                    if clause not in cnf.clauses:
                        cnf.clauses.append(clause)

        # count the automorphism group size, by counting embeddings of the pattern unto the pattern.
        # embed it in a comment comment line on top.
    auto_size = 0
    if compute_automorph_size:
        auto_size_problem = produce_cnf("--emb", pattern_filename,
                                        pattern_filename, target_dir, False)
        auto_size = int(count_sharp_file(auto_size_problem)[0])

    cnf.number_of_clauses = len(cnf.clauses)
    write_cnf_file(cnf, cnf_file_name, auto_size)
    return cnf_file_name