Beispiel #1
0
def perform_rpq(graph,
                regex_automaton,
                start_lst,
                end_lst,
                use_tc_method_adj=False):
    query_dict = regex_automaton.to_GrB_matrix()
    graph_dict = graph.graph_dict
    tmp_graph_dict = {}
    num_vert = 0

    # Getting intersection with kronecker product
    for label in query_dict:
        tmp_graph_dict[label] = graph_dict[label].kronecker(query_dict[label])
        if num_vert == 0:
            num_vert = tmp_graph_dict[label].ncols

    # To GrB matrix
    tmp = LabelGraph()
    tmp.graph_dict = tmp_graph_dict
    tmp.num_vert = num_vert
    result = tmp.to_GrB_matrix()

    # Transform double index to single value
    def coord_to_index(coord):
        v_graph, v_regex = coord
        return v_graph * regex_automaton.num_vert + v_regex

    start_states = set(
        map(coord_to_index,
            product(range(graph.num_vert), regex_automaton.start_states)))
    final_states = set(
        map(coord_to_index,
            product(range(graph.num_vert), regex_automaton.final_states)))

    if (not use_tc_method_adj):
        reachability_matrix_ = get_transitive_closure(result).select(
            lib.GxB_NONZERO)
    else:
        reachability_matrix_ = get_transitive_closure_adj(result).select(
            lib.GxB_NONZERO)
    reachability_matrix = Matrix.sparse(BOOL, graph.num_vert, graph.num_vert)
    print("Started r_m\n")

    for v_i, v_j, _ in zip(
            *reachability_matrix_.select(lib.GxB_NONZERO).to_lists()):
        if (v_i in start_states) and (v_j in final_states):
            # Getting initial graph vertex from index in result matrix
            v_from = v_i // regex_automaton.num_vert
            v_to = v_j // regex_automaton.num_vert
            # Debug output
            reachability_matrix[v_from, v_to] = True
    return (reachability_matrix, reachability_matrix_.nvals)
Beispiel #2
0
def cfpq_tensor_product(g: LabelGraph, cfg: GrammarCNF):
    rfa = RFA().from_cfg(cfg)
    # Resulting matrix initialization
    result = LabelGraph()
    result.num_vert = g.num_vert
    # Empty matrix case
    if (g.num_vert == 0):
        return Matrix.sparse(BOOL, g.num_vert, g.num_vert)
    result.graph_dict = {
        label: g.graph_dict[label].dup()
        for label in g.graph_dict
    }
    for label in rfa.graph_dict:
        if label not in result.graph_dict:
            result.graph_dict[label] = Matrix.sparse(BOOL, g.num_vert,
                                                     g.num_vert)
    for term in cfg.terminals:
        if term.value not in result.graph_dict:
            result.graph_dict[term.value] = Matrix.sparse(
                BOOL, g.num_vert, g.num_vert)
    # Loops for epsilon productions
    for p in cfg.productions:
        if p.body == []:
            for v in g.vertices:
                result.graph_dict[p.head.value][v, v] = True

    matrix_changing = True

    tc = None
    while matrix_changing:
        matrix_changing = False
        tmp_graph_dict = {}
        num_vert = 0
        # Getting intersection
        for label in rfa.graph_dict:
            tmp_graph_dict[label] = result.graph_dict[label].kronecker(
                rfa.graph_dict[label])
            if num_vert == 0:
                num_vert = tmp_graph_dict[label].ncols
        # To GrB matrix
        tmp = LabelGraph()
        tmp.graph_dict = tmp_graph_dict
        tmp.num_vert = num_vert
        intersection = tmp.to_GrB_matrix()

        # Transitive closure
        old_nvals = 0 if tc is None else tc.nvals
        tc = get_transitive_closure(intersection)

        for s, o in LabelGraph.get_reachable(tc):
            # Get coordinates
            s_m, s_rfa = s // rfa.num_vert, s % rfa.num_vert
            o_m, o_rfa = o // rfa.num_vert, o % rfa.num_vert

            if s_rfa in rfa.start_states and o_rfa in rfa.final_states:
                label = rfa.var_by_vertices[(s_rfa, o_rfa)]
                result.graph_dict[label][s_m, o_m] = True
        if old_nvals != tc.nvals:
            matrix_changing = True

    return result.graph_dict[cfg.start_symbol.value]