public TopSortData(DSetFactory setfactory) 
 {
   this.all_nodes = setfactory();
   this.real_roots = setfactory();
 }
 public static IList/*<IStronglyConnectedComponent>*/ 
   TopologicallySortComponentGraph(DSetFactory setfactory, IEnumerable/*<IStronglyConnectedComponent>*/ roots)
 {
   return TopologicallySortGraph(setfactory, roots, iscc_navigator);
 }
    /// <summary>
    /// Topologically sorts the graph rooted in <c>roots</c> and described by
    /// <c>nav</c>. Throws a <c>CyclicGraphException</c> if the graph contains
    /// a cycle. Otherwise, returns a topologically sorted list of the graph nodes. 
    /// The returned list is in ascending order: it starts with the nodes that don't
    /// have any out-arc (i.e., arcs going out of them) and ends with the nodes
    /// that don't have any in-arcs (i.e., arcs going into them).  If the navigator
    /// works in constant time, the topological sort works in time linear with the
    /// number of nodes plus the number of edges. 
    /// 
    /// </summary>
    public static IList TopologicallySortGraph (DSetFactory setfactory, IEnumerable roots, IGraphNavigator navigator)
    {
      TopSortData data = new TopSortData(setfactory);
      data.all_nodes.AddAll(ReachableNodes(setfactory, roots, navigator));
      if(data.all_nodes.Count == 0)
        return data.list;

      // find the real roots: those nodes with no arcs pointing to them
      data.real_roots.AddAll(roots);
      foreach(object node in data.all_nodes)
        foreach(object next_node in navigator.NextNodes(node))
          data.real_roots.Remove(next_node);
      // if there is no real root, we have a cycle
      if(data.real_roots.Count == 0)
        throw new CyclicGraphException();

      dfs(data.real_roots, navigator, null, null,
        new DNodeVisitor(data.sort_end_visitor));

#if NEVER
			// check for cyles
			IMutableSet seen = new HashSet();
			foreach(object node in data.list)
			{
				foreach(object next_node in navigator.NextNodes(node))
					// all arcs must go behind in the list, to already seen nodes
					if(!seen.Contains(next_node))
						throw new CyclicGraphException();
				seen.Add(node);
			}
#endif
      return data.list;
    }
 public static ISet ReachableNodes (DSetFactory setfactory, IEnumerable roots, IGraphNavigator navigator) 
 {
   return ReachableNodes(setfactory, roots, navigator, null);
 }
 public ReachableNodesData(DSetFactory setfactory) 
 {
   this.all_nodes = setfactory();
 }
 public static ISet ReachableNodes (DSetFactory setfactory, IEnumerable roots, IGraphNavigator navigator, DNodePredicate avoid)
 {
   ReachableNodesData data = new ReachableNodesData(setfactory);
   SearchDepthFirst(roots, navigator, avoid, null,
     new DNodeVisitor(data.reachable_visitor), null);
   return data.all_nodes;
 }
 /// <summary>
 /// Full power relation constructor that allows you to finely tune the memory consumption.
 /// Internally, a relation is a dictionary that assigns to each key the set of values that are
 /// in relation with it.  This constructor allows you to specify the dictionary and the set
 /// factory.
 /// </summary>
 /// <param name="dict_fact">Dictionary factory used to construct the underlying dictionary.</param>
 /// <param name="set_fact">Set factory used to construct the set that will store the values
 /// associated with each key.</param>
 public Relation(DDictionaryFactory dict_fact, DSetFactory set_fact)
 {
   this.dict_fact = dict_fact;
   this.set_fact  = set_fact;
   init();
 }