def simple_cycles_as_edges(G): cycles = list(simple_cycles(G)) def c2e(c): for i in range(len(c)): n1 = c[i] n2 = c[(i + 1) % len(c)] yield n1, n2 return set([tuple(c2e(c)) for c in cycles])
def dpgraph_(name2dp, connections, split): try: connections = set(connections) check_connections(name2dp, connections) G = get_connection_multigraph(connections) cycles = list(simple_cycles(G)) if not cycles: res = dpconnect(name2dp, connections, split=split) assert isinstance(res, SimpleWrap), (type(res), name2dp) return res # At this point we never resort to the rest - # this is always called without cycles assert False # c = choose_connection_to_cut1(connections, name2dp) # # other_connections = set() # other_connections.update(connections) # other_connections.remove(c) # # def connections_include_resource(conns, s): # for c in conns: # if c.s1 == s: # return True # else: # return False # # # we have to make sure that the signal that we need is not closed # if connections_include_resource(other_connections, c.s1): # split1 = [c.s1] # else: # split1 = [] # # split1.extend(split) # # ndp = dpgraph(name2dp, other_connections, split=split1) # # # now we make sure that the signals we have are preserved # ndp.rindex(c.s1) # ndp.findex(c.s2) # l = dploop0(ndp, c.s1, c.s2) # # l.rindex(c.s1) # # if c.s1 in split: # return l # # else: # F = ndp.get_rtype(c.s1) # term = dpwrap(Terminator(F), c.s1, []) # # res = connect2(l, term, # set([Connection("-", c.s1, "-", c.s1)]), split=[]) # # return res except DPSemanticError as e: raise_wrapped(DPSemanticError, e, 'Error while calling dpgraph().', compact=True, names=format_dict_long(name2dp, informal=True), connection=format_list_long(connections, informal=True)) except DPInternalError as e: raise_wrapped(DPInternalError, e, 'Error while calling dpgraph().', names=format_dict_long(name2dp, informal=True), connection=format_list_long(connections, informal=True))
def dependency_graph(df, clean_graph_loops=True): """Generate the dependency graph of the coq files. :param df: the DataFrame of all the files tokens. :param clean_graph_loops: remove cyclic dependencies in graph :return: DiGraph with files id as nodes and dependencies as edges. :rtype: networkx.DiGraph """ def linker(from_node, to_nodes): """Return a list of networkx formatted edges. Those edges represents the dependencies in the coq files. :param from_node: id of the dependent node :param to_nodes: list of ids of required files :return: list of networkx formatted edges. :rtype: list of tuple (int, int) ..note: linker is also in charge of removing the unknown dependencies represented by `-1` in the `to_nodes` list. """ return map(lambda x: (from_node, x), filter(lambda x: x != -1, to_nodes)) def indexer(d): return [x[1] for x in sorted(d, key=lambda x: x[0])] file_ids = df['file_id'].unique() G = nx.DiGraph() G.add_nodes_from(file_ids) print('Generating dependencies labels for nodes') with ProcessPoolExecutor(max_workers=16) as executor: # list of slices of pandas dataframe, each containing the # tokens of an unique file file_datasets = list( map(lambda x: (x, df[df['file_id'] == x]), sorted(file_ids))) # list of labels of the files dependencies labels_futures = list( map(lambda x: (x[0], executor.submit(deps_for_file, x[1])), file_datasets)) # list of relative folder to include in the file PATH # for imports loadpath_futures = list( map(lambda x: (x[0], executor.submit(create_file_path, x[1])), file_datasets)) def extract_res(x): r = x[1].result() return x[0], r labels = list(map(extract_res, labels_futures)) loadpaths = list(map(extract_res, loadpath_futures)) # Sorting the results labels = indexer(labels) loadpaths = indexer(loadpaths) # Creating dependency dataset (one row / file) deps = df[['file_id', 'file']].drop_duplicates(subset='file_id', keep='first').sort_values('file_id') deps['deps_labels'] = labels deps['deps_path'] = loadpaths dependencies_list = list( itertools.chain.from_iterable( (resolve_dependencies_labels(deps, x) for x in ('/HoTT/theories', '/UniMath/UniMath')))) edges = itertools.chain.from_iterable( map(lambda x: linker(*x), dependencies_list)) G.add_edges_from(edges) if clean_graph_loops: for c in al.simple_cycles(G): print('Cycle detected:', c) cycle_edges = [(c[x], c[(x + 1) % len(c)]) for x in range(len(c))] print('Removing edges:', cycle_edges) G.remove_edges_from(cycle_edges) return G