U
    •Ê¹j   ã                   @   s.   d dl mZ d dlmZmZ G dd„ dƒZdS )é    )Údeque)ÚListÚSetc                   @   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 )#ÚDiGraphz´Really 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   úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/package/_digraph.pyÚ__init__   s
    zDiGraph.__init__c                 K   sX   || j krD|| j |< i | j|< i | j|< | j| j|< |  jd7  _n| j |  |¡ dS )zºAdd 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 )z‚Add 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   sJ   zt | j| ƒW S  tk
rD } ztd|› d�ƒ|‚W 5 d}~X Y nX 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   sJ   zt | j| ƒW S  tk
rD } ztd|› d�ƒ|‚W 5 d}~X Y nX 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   Ú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 kW S  tk
r"   Y dS X 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 ] }||k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 ] }||k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 ƒ }|  |¡}||kr|S t|ƒ}t|ƒdkrh| ¡ }|  |¡D ]"}||krB| ||¡ | |¡ qBq$| ¡ S )zAReturns a subgraph rooted at src that shows all the paths to dst.r   )	r   r3   r   r+   r,   r    r   r.   Úto_dot)r   r(   r5   Zresult_graphZforward_reachable_from_srcr1   r2   r   r   r   r   Ú	all_pathsv   s    
zDiGraph.all_paths)r5   r)   c                 C   sr   g }|rf|  |¡ | j|  ¡ }d\}}|D ]6}| j |d¡}|dkrJ q|dk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   r5   Ú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>¦   s     z!DiGraph.to_dot.<locals>.<genexpr>z,digraph G {
rankdir = LR;
node [shape=box];
z
}
)Újoinr#   )r   r#   r   r   r   r6       s    üzDiGraph.to_dotN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r    Úpropertyr#   r$   r%   r'   Ústrr   r3   r4   r7   r   rB   r6   r   r   r   r   r      s"   

r   N)Úcollectionsr   Útypingr   r   r   r   r   r   r   Ú<module>   s   