U
    9vfB  ã                   @   sH   d Z ddlmZ ddlZddlmZ ddgZedƒdd„ ƒZd	d„ Z	dS )
z
Dominance algorithms.
é    )ÚreduceN)Únot_implemented_forÚimmediate_dominatorsÚdominance_frontiersZ
undirectedc                    s´   || krt  d¡‚||i‰tt  | |¡ƒ}dd„ t|ƒD ƒ‰ | ¡  | ¡  ‡ ‡fdd„}d}|r°d}|D ]B}t|‡fdd	„| j| D ƒƒ}|ˆks ˆ| |krj|ˆ|< d}qjq^ˆS )
a'  Returns the immediate dominators of all nodes of a directed graph.

    Parameters
    ----------
    G : a DiGraph or MultiDiGraph
        The graph where dominance is to be computed.

    start : node
        The start node of dominance computation.

    Returns
    -------
    idom : dict keyed by nodes
        A dict containing the immediate dominators of each node reachable from
        `start`.

    Raises
    ------
    NetworkXNotImplemented
        If `G` is undirected.

    NetworkXError
        If `start` is not in `G`.

    Notes
    -----
    Except for `start`, the immediate dominators are the parents of their
    corresponding nodes in the dominator tree.

    Examples
    --------
    >>> G = nx.DiGraph([(1, 2), (1, 3), (2, 5), (3, 4), (4, 5)])
    >>> sorted(nx.immediate_dominators(G, 1).items())
    [(1, 1), (2, 1), (3, 1), (4, 3), (5, 1)]

    References
    ----------
    .. [1] K. D. Cooper, T. J. Harvey, and K. Kennedy.
           A simple, fast dominance algorithm.
           Software Practice & Experience, 4:110, 2001.
    zstart is not in Gc                 S   s   i | ]\}}||“qS © r   )Ú.0ÚiÚur   r   úA/tmp/pip-unpacked-wheel-_lngutwb/networkx/algorithms/dominance.pyÚ
<dictcomp>>   s      z(immediate_dominators.<locals>.<dictcomp>c                    sB   | |kr>ˆ |  ˆ | k r"ˆ|  } qˆ |  ˆ | kr ˆ| }q"q | S ©Nr   )r	   Úv©ÚdfnÚidomr   r
   Ú	intersectB   s    
z'immediate_dominators.<locals>.intersectTFc                 3   s   | ]}|ˆ kr|V  qd S r   r   )r   r   )r   r   r
   Ú	<genexpr>N   s      z'immediate_dominators.<locals>.<genexpr>)	ÚnxZNetworkXErrorÚlistZdfs_postorder_nodesÚ	enumerateÚpopÚreverser   Úpred)ÚGÚstartÚorderr   Úchangedr	   Znew_idomr   r   r
   r      s"    +
c                 C   sv   t  | |¡}dd„ |D ƒ}|D ]R}t| j| ƒdkr| j| D ]0}||kr>||| kr>||  |¡ || }qJq>q|S )aÂ  Returns the dominance frontiers of all nodes of a directed graph.

    Parameters
    ----------
    G : a DiGraph or MultiDiGraph
        The graph where dominance is to be computed.

    start : node
        The start node of dominance computation.

    Returns
    -------
    df : dict keyed by nodes
        A dict containing the dominance frontiers of each node reachable from
        `start` as lists.

    Raises
    ------
    NetworkXNotImplemented
        If `G` is undirected.

    NetworkXError
        If `start` is not in `G`.

    Examples
    --------
    >>> G = nx.DiGraph([(1, 2), (1, 3), (2, 5), (3, 4), (4, 5)])
    >>> sorted((u, sorted(df)) for u, df in nx.dominance_frontiers(G, 1).items())
    [(1, []), (2, [5]), (3, [5]), (4, [5]), (5, [])]

    References
    ----------
    .. [1] K. D. Cooper, T. J. Harvey, and K. Kennedy.
           A simple, fast dominance algorithm.
           Software Practice & Experience, 4:110, 2001.
    c                 S   s   i | ]}|t ƒ “qS r   )Úset)r   r	   r   r   r
   r   }   s      z'dominance_frontiers.<locals>.<dictcomp>é   )r   r   Úlenr   Úadd)r   r   r   Zdfr	   r   r   r   r
   r   V   s    %)
Ú__doc__Ú	functoolsr   Znetworkxr   Znetworkx.utilsr   Ú__all__r   r   r   r   r   r
   Ú<module>   s   
H