a
    8Sic                      @   s.   d dl mZ d dlmZmZ G dd dZdS )    )deque)SetListc                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	dd Z
e	dd Zdd Zdd Zeee dddZeee dddZeedddZeee dddZedd d!Zd"S )#DiGraphzReally simple unweighted directed graph data structure to track dependencies.

    The API is pretty much the same as networkx so if you add something just
    copy their API.
    c                 C   s"   i | _ i | _i | _i | _d| _d S )Nr   )_node_succ_pred_node_order_insertion_idxself r   R/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/package/_digraph.py__init__   s
    zDiGraph.__init__c                 K   sX   || j vrD|| j |< i | j|< i | j|< | j| j|< |  jd7  _n| j | | dS )zAdd a node to the graph.

        Args:
            n: the node. Can we any object that is a valid dict key.
            **kwargs: any attributes you want to attach to the node.
           N)r   r   r   r
   r	   update)r   nkwargsr   r   r   add_node   s    



zDiGraph.add_nodec                 C   s4   |  | |  | d| j| |< d| j| |< dS )zAdd an edge to graph between nodes ``u`` and ``v``

        ``u`` and ``v`` will be created if they do not already exist.
        TN)r   r   r   )r   uvr   r   r   add_edge*   s    

zDiGraph.add_edgec              
   C   sL   zt | j| W S  tyF } ztd| d|W Y d}~n
d}~0 0 dS )z.Returns an iterator over successor nodes of n.	The node  is not in the digraph.N)iterr   KeyError
ValueErrorr   r   er   r   r   
successors7   s    zDiGraph.successorsc              
   C   sL   zt | j| W S  tyF } ztd| d|W Y d}~n
d}~0 0 dS )z1Returns an iterator over predecessors nodes of n.r   r   N)r   r   r   r   r   r   r   r   predecessors>   s    zDiGraph.predecessorsc                 c   s,   | j  D ]\}}|D ]}||fV  qq
dS )z6Returns an iterator over all edges (u, v) in the graphN)r   items)r   r   r   Zsuccr   r   r   edgesE   s    zDiGraph.edgesc                 C   s   | j S )z6Returns a dictionary of all nodes to their attributes.)r   r   r   r   r   nodesL   s    zDiGraph.nodesc                 C   s
   t | jS )zIterate over the nodes.)r   r   r   r   r   r   __iter__Q   s    zDiGraph.__iter__c                 C   s&   z|| j v W S  ty    Y dS 0 dS )z>Returns True if ``n`` is a node in the graph, False otherwise.FN)r   	TypeError)r   r   r   r   r   __contains__U   s    zDiGraph.__contains__)srcreturnc                 C   sV   t |}t|}t|dkrR| }| |D ] }||vr.|| || q.q|S )z2Returns a set of nodes that are reachable from srcr   )setr   lenpopleftr   addappendr   r'   resultworking_setcurr   r   r   r   forward_transitive_closure\   s    
z"DiGraph.forward_transitive_closurec                 C   sV   t |}t|}t|dkrR| }| |D ] }||vr.|| || q.q|S )zGReturns a set of nodes that are reachable from src in reverse directionr   )r)   r   r*   r+   r    r,   r-   r.   r   r   r   backward_transitive_closurei   s    
z#DiGraph.backward_transitive_closure)r'   dstc                 C   sp   t  }| |}||vr|S t|}t|dkrh| }| |D ]"}||v rB||| || qBq$| S )zAReturns a subgraph rooted at src that shows all the paths to dst.r   )	r   r2   r   r*   r+   r    r   r-   to_dot)r   r'   r4   Zresult_graphZforward_reachable_from_srcr0   r1   r   r   r   r   	all_pathsv   s    
zDiGraph.all_paths)r4   r(   c                 C   sr   g }|rf| | | j|  }d\}}|D ]6}| j|d}|du rJ q|du sZ||k r,|}|}q,qtt|S )z_Returns a list of nodes that show the first path that resulted in dst being added to the graph.) NN)r-   r   keysr	   getlistreversed)r   r4   path
candidatesmin_idx	candidateidxr   r   r   
first_path   s    
zDiGraph.first_path)r(   c                 C   s"   d dd | jD }d| dS )zvReturns the dot representation of the graph.

        Returns:
            A dot representation of the graph.
        
c                 s   s$   | ]\}}d | d| dV  qdS )"z" -> "z";Nr   ).0ftr   r   r   	<genexpr>       z!DiGraph.to_dot.<locals>.<genexpr>z,digraph G {
rankdir = LR;
node [shape=box];
z
}
)joinr"   )r   r"   r   r   r   r5      s    zDiGraph.to_dotN)__name__
__module____qualname____doc__r   r   r   r   r    propertyr"   r#   r$   r&   strr   r2   r3   r6   r   rA   r5   r   r   r   r   r      s"   

r   N)collectionsr   typingr   r   r   r   r   r   r   <module>   s   