o
    ˷eB                     @   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_frontiers
undirectedc                    s   || vr	t d||itt | |}dd t|D  |  |   fdd}d}|rYd}|D ]!}t|fdd	| j| D }|vsP| |krV||< d}q5|s1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   T/var/www/ideatree/venv/lib/python3.10/site-packages/networkx/algorithms/dominance.py
<dictcomp>>   s    z(immediate_dominators.<locals>.<dictcomp>c                    sd   | |kr0 |   | k r|  }  |   | k s |   | kr,| } |   | ks | |ks| S Nr   )r
   vdfnidomr   r   	intersectB   s   z'immediate_dominators.<locals>.intersectTFc                 3   s    | ]	}| v r|V  qd S r   r   )r   r   )r   r   r   	<genexpr>N   s    z'immediate_dominators.<locals>.<genexpr>)	nxNetworkXErrorlistdfs_postorder_nodes	enumeratepopreverser   pred)Gstartorderr   changedr
   new_idomr   r   r   r      s&   +
c                 C   s   t | |}dd |D }|D ].}t| j| dkr=| j| D ]}||v r<||| kr<|| | || }||| ks+q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   dfr
   r   r   r   r   r   V   s   %)
__doc__	functoolsr   networkxr   networkx.utilsr   __all__r   r   r   r   r   r   <module>   s    
H