o
    ˷eU                     @   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rEtdd 
 }| D ]	}|j|j qK| D ]}||jdd qW  rx| D ]}||jddd qi|S | D ]}||jdd qz|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        | ]}|     kV  qd S r   is_multigraph.0GU X/var/www/ideatree/venv/lib/python3.10/site-packages/networkx/algorithms/operators/all.py	<genexpr>8       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 |  }|S  t|  }|S r   )
isinstancestrrepr)xnameprefixr   r   label@   s
   
z,union_all.<locals>.add_prefix.<locals>.label)nx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>I   s    zunion_all.<locals>.<listcomp>c                 s   s    | ]}t |V  qd S r   )lenr   r   r   r   r   K   s    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   
   s2   '
"r   c                 C   sz   t | } | s
tddg}| dd D ]}|t||d   qdd t| |D }t|}| D ]	}|j|j q1|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   convert_node_labels_to_integers)r   r   r8   r   r   r   r!      s    z&disjoint_union_all.<locals>.<listcomp>)r'   r(   appendr"   zipr   r   r/   )r4   first_labelsr   	relabeledr6   r   r   r   r   h   s   r   c                    s   t | } | s
td| d  t fdd| D rtd  }| D ]	}|j|j q$| D ]}||j	dd q0 
 rQ| D ]}||jddd qB|S | D ]}||jdd qS|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   r   r   r	   r   r   r   r   r      r   zcompose_all.<locals>.<genexpr>r   Tr#   r%   )r'   r(   r)   r   r*   r.   r   r/   r0   r1   r
   r2   r3   )r4   r6   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  }  }||  	 r=d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   r   r   r	   r   r   r   r   r      r   z#intersection_all.<locals>.<genexpr>r   c                 S   s   g | ]}t |jqS r   )r,   r1   r   r   r   r   r!      s    z$intersection_all.<locals>.<listcomp>c                 S   s   g | ]
}t |jd dqS )T)r&   r,   r3   r   r   r   r   r!      s    c                 S   s   g | ]}t | qS r   r>   r   r   r   r   r!      s    )r'   r(   r)   r   r*   r,   intersectionr.   r0   r
   r2   )r4   node_intersectionr6   	edge_setsedge_intersectionr   r   r   r      s   



r   )r   )
__doc__	itertoolsr   networkxr   __all__r   r   r   r   r   r   r   r   <module>   s    
^/8