o
    2g                     @  sR   d Z ddlmZ ddlmZmZmZmZ edZdddZ	dddZ
dddZdS )z&Helpers for manipulations with graphs.    )annotations)AbstractSetIterableIteratorTypeVarTverticesAbstractSet[T]edgesdict[T, list[T]]returnIterator[set[T]]c                 #  sP    t  g i g  d fdd| D ]}|vr%|E dH  qdS )	a  Compute Strongly Connected Components of a directed graph.

    Args:
      vertices: the labels for the vertices
      edges: for each vertex, gives the target vertices of its outgoing edges

    Returns:
      An iterator yielding strongly connected components, each
      represented as a set of vertices.  Each input vertex will occur
      exactly once; vertices not part of a SCC are returned as
      singleton sets.

    From https://code.activestate.com/recipes/578507/.
    vr   r   r   c                 3  s    t | < |   |   |  D ]&}|vr%|E d H  q|vr=|  d k r=   |  d k s1q d |  kre   t|  d  }|  d = | |V  d S d S )N)lenappendpopsetupdate)r   wscc
boundariesdfsr
   
identifiedindexstack H/home/garg/my-data/venv/lib/python3.10/site-packages/mypy/graph_utils.pyr       s&   


z*strongly_connected_components.<locals>.dfsN)r   r   r   r   )r   )r   r
   r   r   r   r   strongly_connected_components
   s   r   sccslist[set[T]])dict[AbstractSet[T], set[AbstractSet[T]]]c                   sX   dd | D  i }| D ]}t  }|D ]}| fdd|| D  q||t|< q|S )zLUse original edges to organize SCCs in a graph by dependencies between them.c                 S  s    i | ]}|D ]}|t |qqS r   )	frozenset).0r   r   r   r   r   
<dictcomp><   s     z prepare_sccs.<locals>.<dictcomp>c                 3  s    | ]} | V  qd S )Nr   )r$   xsccsmapr   r   	<genexpr>A   s    zprepare_sccs.<locals>.<genexpr>)r   r   r#   )r    r
   datar   depsr   r   r'   r   prepare_sccs8   s   r,   r*   dict[T, set[T]]Iterable[set[T]]c                 #  s    |   D ]	\}}|| qtj|   t|   D ]}t | |< q	 dd |   D   s1n V   fdd|   D } q%| rIJ d| dS )a  Topological sort.

    Args:
      data: A map from vertices to all vertices that it has an edge
            connecting it to.  NOTE: This data structure
            is modified in place -- for normalization purposes,
            self-dependencies are removed and entries representing
            orphans are added.

    Returns:
      An iterator yielding sets of vertices that have an equivalent
      ordering.

    Example:
      Suppose the input has the following structure:

        {A: {B, C}, B: {D}, C: {D}}

      This is normalized to:

        {A: {B, C}, B: {D}, C: {D}, D: {}}

      The algorithm will yield the following values:

        {D}
        {B, C}
        {A}

    From https://code.activestate.com/recipes/577413/.
    Tc                 S  s   h | ]\}}|s|qS r   r   r$   itemdepr   r   r   	<setcomp>k   s    ztopsort.<locals>.<setcomp>c                   s"   i | ]\}}| vr||  qS r   r   r/   readyr   r   r%   o   s   " ztopsort.<locals>.<dictcomp>z#A cyclic dependency exists amongst N)itemsdiscardr   unionvalueskeys)r*   kr   r0   r   r3   r   topsortF   s    r;   N)r   r	   r
   r   r   r   )r    r!   r
   r   r   r"   )r*   r-   r   r.   )__doc__
__future__r   typingr   r   r   r   r   r   r,   r;   r   r   r   r   <module>   s    

.