ó
 ,µ[c           @   s`   d  Z  d d l m Z d d l Z d d l m Z d d g Z e d ƒ d „  ƒ Z d	 „  Z	 d S(
   s   
Dominance algorithms.
iÿÿÿÿ(   t   reduceN(   t   not_implemented_fort   immediate_dominatorst   dominance_frontierst
   undirectedc            s  | |  k r t  j d ƒ ‚ n  i | | 6‰ t t  j |  | ƒ ƒ } d „  t | ƒ Dƒ ‰  | j ƒ  | j ƒ  ‡  ‡ f d †  } t } xv | rı t } xc | D][ } t	 | ‡ f d †  |  j
 | Dƒ ƒ } | ˆ k sã ˆ | | k r› | ˆ | <t } q› q› Wqˆ Wˆ S(   s'  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.
    s   start is not in Gc         S   s   i  |  ] \ } } | | “ q S(    (    (   t   .0t   it   u(    (    s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pys
   <dictcomp>E   s   	 c            sa   xZ |  | k r\ x" ˆ  |  ˆ  | k  r3 ˆ |  }  q Wx" ˆ  |  ˆ  | k rX ˆ | } q7 Wq W|  S(   N(    (   R   t   v(   t   dfnt   idom(    s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pyt	   intersectI   s    c         3   s!   |  ] } | ˆ  k r | Vq d  S(   N(    (   R   R   (   R
   (    s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pys	   <genexpr>U   s    (   t   nxt   NetworkXErrort   listt   dfs_postorder_nodest	   enumeratet   popt   reverset   Truet   FalseR    t   pred(   t   Gt   startt   orderR   t   changedR   t   new_idom(    (   R	   R
   s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pyR      s"    +

	&
c         C   s¬   t  j |  | ƒ } d „  | Dƒ } xƒ | D]{ } t |  j | ƒ d k r) xY |  j | D]G } | | k rV x2 | | | k r™ | | j | ƒ | | } qk WqV qV Wq) q) W| S(   sÂ  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(    (   t   set(   R   R   (    (    s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pys
   <dictcomp>„   s   	 i   (   R   R   t   lenR   t   add(   R   R   R
   t   dfR   R   (    (    s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pyR   ]   s    %(
   t   __doc__t	   functoolsR    t   networkxR   t   networkx.utilsR   t   __all__R   R   (    (    (    s<   lib/python2.7/site-packages/networkx/algorithms/dominance.pyt   <module>   s   I