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