コード例 #1
0
ファイル: Utils.py プロジェクト: AlanGamaonov/spbu-gdb2020
    def get_intersection(graph1, graph2):
        result = Graph()
        result.vertices_count = graph1.vertices_count * graph2.vertices_count

        for i in graph1.start_vertices:
            for j in graph2.start_vertices:
                result.start_vertices.add(i * graph1.vertices_count + j)

        for i in graph1.terminal_vertices:
            for j in graph2.terminal_vertices:
                result.terminal_vertices.add(i * graph1.vertices_count + j)

        for label in graph1.label_matrices.keys():
            if label in graph2.label_matrices.keys():
                result.label_matrices[label] = graph1.label_matrices[
                    label].kronecker(graph2.label_matrices[label])

        return result
コード例 #2
0
ファイル: Utils.py プロジェクト: AlanGamaonov/spbu-gdb2020
    def cfpq_tensor_product(graph: Graph, grammar: CFG):
        if graph.vertices_count == 0:
            return False

        result = graph.get_copy()

        rfa = Graph()
        rfa_heads = dict()

        rfa.vertices_count = sum(
            [len(production.body) + 1 for production in grammar.productions])
        index = 0
        for production in grammar.productions:
            start_state = index
            terminal_state = index + len(production.body)

            rfa.start_vertices.add(start_state)
            rfa.terminal_vertices.add(terminal_state)
            rfa_heads[(start_state, terminal_state)] = production.head.value

            for variable in production.body:
                matrix = rfa.label_matrices.get(
                    variable.value,
                    Matrix.sparse(BOOL, rfa.vertices_count,
                                  rfa.vertices_count))
                matrix[index, index + 1] = True
                rfa.label_matrices[variable.value] = matrix
                index += 1

            index += 1

        for production in grammar.productions:
            if len(production.body) == 0:
                matrix = Matrix.sparse(BOOL, graph.vertices_count,
                                       graph.vertices_count)
                matrix += Matrix.identity(BOOL, graph.vertices_count)

                result.label_matrices[production.head] = matrix

        changed = True
        while changed:
            changed = False
            intersection = Utils.get_intersection(rfa, result)
            closure = Utils.get_transitive_closure_squaring(intersection)

            for i, j, _ in zip(*closure.to_lists()):
                rfa_from, rfa_to = i // result.vertices_count, j // result.vertices_count
                graph_from, graph_to = i % result.vertices_count, j % result.vertices_count

                if (rfa_from, rfa_to) not in rfa_heads:
                    continue

                variable = rfa_heads[(rfa_from, rfa_to)]

                matrix = result.label_matrices.get(
                    variable,
                    Matrix.sparse(BOOL, graph.vertices_count,
                                  graph.vertices_count))

                if matrix.get(graph_from, graph_to) is None:
                    changed = True
                    matrix[graph_from, graph_to] = True
                    result.label_matrices[variable] = matrix

        return result.label_matrices.get(
            grammar.start_symbol,
            Matrix.sparse(BOOL, graph.vertices_count, graph.vertices_count))