U
    ?hB                     @   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}|rd}|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   O/var/www/html/venv/lib/python3.8/site-packages/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