a
    h^                     @   sT   d Z ddlmZ ddlZddlmZ ddgZedejdd Z	ejd	d Z
dS )
z
Dominance algorithms.
    )reduceN)not_implemented_forimmediate_dominatorsdominance_frontiersZ
undirectedc                    s   || vrt d||itt | |}dd t|D  |  |   fdd}d}|rd}|D ]B}t|fdd	| j| D }|v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   K/var/www/auris/lib/python3.9/site-packages/networkx/algorithms/dominance.py
<dictcomp>?       z(immediate_dominators.<locals>.<dictcomp>c                    sB   | |kr> |   | k r"|  } q |   | kr | }q"q | S Nr   )r	   vdfnidomr   r
   	intersectC   s    
z'immediate_dominators.<locals>.intersectTFc                 3   s   | ]}| v r|V  qd S r   r   )r   r   )r   r   r
   	<genexpr>O   r   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}||v 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      r   z'dominance_frontiers.<locals>.<dictcomp>   )r   r   lenr   add)r   r   r   Zdfr	   r   r   r   r
   r   W   s    &)__doc__	functoolsr   Znetworkxr   Znetworkx.utilsr   __all__	_dispatchr   r   r   r   r   r
   <module>   s   H