a
    1bT                     @   sF   d Z ddlmZ ddlZg dZdddZdd	 Zd
d Zdd Z	dS )zOperations on many graphs.
    )zip_longestN)	union_allcompose_alldisjoint_union_allintersection_allNc                    s  t | } | std| d  t fdd| D r<tddd fdd	t| |D } td
d | D tt j	|  krtdd 
 }| D ]}|j|j q| D ]}||jdd q  r| D ]}||jddd qn| D ]}||jdd q|S )a  Returns the union of all graphs.

    The graphs must be disjoint, otherwise an exception is raised.

    Parameters
    ----------
    graphs : list of graphs
       List of NetworkX graphs

    rename : bool , default=(None, None)
       Node names of G and H can be changed by specifying the tuple
       rename=('G-','H-') (for example).  Node "u" in G is then renamed
       "G-u" and "v" in H is renamed "H-v".

    Returns
    -------
    U : a graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    To force a disjoint union with node relabeling, use
    disjoint_union_all(G,H) or convert_node_labels_to integers().

    Graph, edge, and node attributes are propagated to the union graph.
    If a graph attribute is present in multiple graphs, then the value
    from the last graph in the list with that attribute is used.

    See Also
    --------
    union
    disjoint_union_all
    z'cannot apply union_all to an empty listr   c                 3   s   | ]}|     kV  qd S r   is_multigraph.0GU @lib/python3.9/site-packages/networkx/algorithms/operators/all.py	<genexpr>7       zunion_all.<locals>.<genexpr>)All graphs must be graphs or multigraphs.c                    s$    d u r| S  fdd}t | |S )Nc                    s$   t | tr |  }n t|  }|S r   )
isinstancestrrepr)xnameprefixr   r   label?   s    

z,union_all.<locals>.add_prefix.<locals>.label)nxZrelabel_nodes)graphr   r   r   r   r   
add_prefix;   s    zunion_all.<locals>.add_prefixc                    s   g | ]\}} ||qS r   r   )r   r   r   )r   r   r   
<listcomp>H   r   zunion_all.<locals>.<listcomp>c                 s   s   | ]}t |V  qd S r   )lenr
   r   r   r   r   J   r   z-The node sets of the graphs are not disjoint.z[Use appropriate rename=(G1prefix,G2prefix,...,GNprefix)or use disjoint_union(G1,G2,...,GN).Tdatakeysr"   )list
ValueErroranyr   NetworkXErrorr   sumr    setunion	__class__r   updateadd_nodes_fromnodesr	   add_edges_fromedges)graphsrenameRr   r   )r   r   r   r   	   s0    '
"r   c                 C   sz   t | } | stddg}| dd D ]}|t||d   q&dd t| |D }t|}| D ]}|j|j qb|S )a  Returns the disjoint union of all graphs.

    This operation forces distinct integer node labels starting with 0
    for the first graph in the list and numbering consecutively.

    Parameters
    ----------
    graphs : list
       List of NetworkX graphs

    Returns
    -------
    U : A graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    It is recommended that the graphs be either all directed or all undirected.

    Graph, edge, and node attributes are propagated to the union graph.
    If a graph attribute is present in multiple graphs, then the value
    from the last graph in the list with that attribute is used.
    z0cannot apply disjoint_union_all to an empty listr   Nc                 S   s   g | ]\}}t j||d qS ))first_label)r   Zconvert_node_labels_to_integers)r   r   r6   r   r   r   r      s   z&disjoint_union_all.<locals>.<listcomp>)r%   r&   appendr    zipr   r   r-   )r2   Zfirst_labelsr   Z	relabeledr4   r   r   r   r   g   s    r   c                    s   t | } | std| d  t fdd| D r<td  }| D ]}|j|j qH| D ]}||j	dd q` 
 r| D ]}||jddd qn| D ]}||jdd q|S )	a  Returns the composition of all graphs.

    Composition is the simple union of the node sets and edge sets.
    The node sets of the supplied graphs need not be disjoint.

    Parameters
    ----------
    graphs : list
       List of NetworkX graphs

    Returns
    -------
    C : A graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    It is recommended that the supplied graphs be either all directed or all
    undirected.

    Graph, edge, and node attributes are propagated to the union graph.
    If a graph attribute is present in multiple graphs, then the value
    from the last graph in the list with that attribute is used.
    z)cannot apply compose_all to an empty listr   c                 3   s   | ]}|     kV  qd S r   r   r
   r   r   r   r      r   zcompose_all.<locals>.<genexpr>r   Tr!   r#   )r%   r&   r'   r   r(   r,   r   r-   r.   r/   r	   r0   r1   )r2   r4   r   r   r   r   r      s"    
r   c                    s   t | } | std| d  t fdd| D r<tdtjdd | D  }  }||  	 rzdd | D }nd	d | D }tj| }|
| |S )
a  Returns a new graph that contains only the nodes and the edges that exist in
    all graphs.

    Parameters
    ----------
    graphs : list
       List of NetworkX graphs

    Returns
    -------
    R : A new graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    Attributes from the graph, nodes, and edges are not copied to the new
    graph.
    z.cannot apply intersection_all to an empty listr   c                 3   s   | ]}|     kV  qd S r   r   r
   r   r   r   r      r   z#intersection_all.<locals>.<genexpr>r   c                 S   s   g | ]}t |jqS r   )r*   r/   r
   r   r   r   r      r   z$intersection_all.<locals>.<listcomp>c                 S   s   g | ]}t |jd dqS )T)r$   r*   r1   r
   r   r   r   r      r   c                 S   s   g | ]}t | qS r   r9   r
   r   r   r   r      r   )r%   r&   r'   r   r(   r*   intersectionr,   r.   r	   r0   )r2   Znode_intersectionr4   Z	edge_setsZedge_intersectionr   r   r   r      s    



r   )r   )
__doc__	itertoolsr   Znetworkxr   __all__r   r   r   r   r   r   r   r   <module>   s   
^/8