U
    tdF                     @   sX   d Z dZdZddlmZmZmZmZ ddlm	Z	 dd Z
dd	 ZdddZdddZdS )zCImplementation of union, disjoint union and intersection operators.)disjoint_unionunionintersectionz	google en    )	GraphBase_union_intersection_disjoint_union)warnc                 C   s$   t | }t|t| kr td|S )a  Converts a list of names to a set of names while checking for duplicates.

    Parameters:
        names: the list of names to convert

    Returns:
        the set of unique names appearing in the list

    Raises:
        RuntimeError: if the input name list has duplicates
    z%Graph contains duplicate vertex names)setlenAttributeError)namesZnameset r   S/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/igraph/operators/functions.pyname_set   s    r   c                 C   s  t dd | D rtdt| }|dkr2td|dkrF| d  S t| }i }t }t| dD ]\}}| D ]|}|| }|| kr|||< |||< qr|| |krqr||kr|	| || }	|| |d
||	< ||= ||d
||< qrqbd}
| D ]@}| }| D ]"}|j| |j|
|
|  |< q|
|7 }
qd}
| D ]B}| }| D ]"}|j| |j|
|
|  |< qX|
|7 }
qD|S )aC  Graph disjoint union.

    The disjoint union of two or more graphs is created.

    This function keeps the attributes of all graphs. All graph, vertex and
    edge attributes are copied to the result. If an attribute is present in
    multiple graphs and would result a name clash, then this attribute is
    renamed by adding suffixes: _1, _2, etc.

    An error is generated if some input graphs are directed and others are
    undirected.

    Parameters:
        graphs: list of graphs. A lazy sequence is not acceptable.

    Returns:
        the disjoint union graph
    c                 s   s   | ]}t |t V  qd S N
isinstancer   .0gr   r   r   	<genexpr>1   s     z!disjoint_union.<locals>.<genexpr>Not all elements are graphsr   z)disjoint_union() needs at least one graph   {:}_{:})any	TypeErrorr   
ValueErrorcopyr   r
   	enumerate
attributesaddformatvcountvertex_attributesvsecountedge_attributeses)graphsngrgraph_uniona_first_graph
a_conflictigr   a_namea_valueigfinvattrner   r   r   r      sL    
 
 r   autoc                    s  t dd | D rtd|dkr*tdt| }tdd | D }|dkr|||k}|d|fkrtd	| d
||  d n&|r||krtd| d
||  d|dkrtd|dkr| d  S |rzdd | D }tt	j
dd |D  }dd t|D  t|}g }t| |D ]\\}}	| }
tt	|t	|	 }|
|  fdd|
jd D }|
|}
||
 qn| }t dd | D }t||}|r|d }|d }n|}i }t	 }t|dD ]\}}| D ]}|| }|| kr|||< |||< q|| |krq||krP|| || }|| |d||< ||= ||d||< qڐq|rx||jd< t	j
dd |D  t	dg }| }|D ]}d}dd t|D }|D ]z}|| kr,t|j| D ]J\}}|dkrq|| dkr|||< q|| |krd} q,q|r q<q|sP||j|< qt|dD ]0\}}|| krZ|j| |jd||< qZq|rt	j
d d |D  }| }|D ]V}d}d!d t|D }t||D ]\}}|| krqt||j| D ]f\}}|dkrq|| dkr6|||< q|| |krt||jd |||||  d} qnq|r q~q|s||j|< qtt||dD ]h\}\}}|| krqd"d t|D }t||j| D ]\}}|||< q||jd||< qq|S )#a  Graph union.

    The union of two or more graphs is created. The graphs may have identical
    or overlapping vertex sets. Edges which are included in at least one graph
    will be part of the new graph.

    This function keeps the attributes of all graphs. All graph, vertex and
    edge attributes are copied to the result. If an attribute is present in
    multiple graphs and would result a name clash, then this attribute is
    renamed by adding suffixes: _1, _2, etc.

    The ``name`` vertex attribute is treated specially if the operation is
    performed based on symbolic vertex names. In this case ``name`` must be
    present in all graphs, and it is not renamed in the result graph.

    An error is generated if some input graphs are directed and others are
    undirected.

    Parameters:
        graphs: list of graphs. A lazy sequence is not acceptable.
        byname: bool or 'auto' specifying the function behaviour with
            respect to names vertices (i.e. vertices with the 'name' attribute). If
            False, ignore vertex names. If True, merge vertices based on names. If
            'auto', use True if all graphs have named vertices and False otherwise
            (in the latter case, a warning is generated too).

    Returns:
        the union graph

    Raises:
        RuntimeError: if 'byname' is set to True and some graphs are not named or
            the set of names is not unique in one of the graphs
    c                 s   s   | ]}t |t V  qd S r   r   r   r   r   r   r      s     zunion.<locals>.<genexpr>r   TFr6   #"byname" should be a bool or "auto"c                 s   s   | ]}|  V  qd S r   Zis_namedr   r   r   r   r      s     r6   r   (Some, but not all graphs are named (got  named, ! unnamed), not using vertex namesSome graphs are not named (got 	 unnamed)z union() needs at least one graphr   c                 S   s   g | ]}|j d  qS namer%   r   r   r   r   
<listcomp>   s     zunion.<locals>.<listcomp>c                 s   s   | ]}t |V  qd S r   r   r   Zvnsr   r   r   r      s     c                 S   s   i | ]\}}||qS r   r   r   r2   xr   r   r   
<dictcomp>   s      zunion.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   r   rF   Zpermutation_mapr   r   rB      s     r@   c                 s   s   | ]}t | V  qd S r   r   r'   r   r   r   r   r      s     graphedgemapsr   c                 s   s   | ]}t | V  qd S r   r
   r$   r   r   r   r   r      s     Fc                 S   s   g | ]}d qS r   r   r   r2   r   r   r   rB      s     NTc                 s   s   | ]}t | V  qd S r   r
   r'   r   r   r   r   r     s     c                 S   s   g | ]}d qS r   r   rN   r   r   r   rB     s     c                 S   s   g | ]}d qS r   r   rN   r   r   r   rB   !  s     )r   r   r   r   sumr	   RuntimeErrorr   listr
   r   r   zipadd_verticesr%   permute_verticesappendr   r    r!   r"   r#   ranger$   r&   r'   r(   print)r)   bynamer*   n_namedallnamesuninamesZnve	newgraphsr   vertex_namesng	v_missingpermutationrL   resr+   r,   r-   r.   r/   r0   r1   attrsconflictvalsr2   r5   emapiur   rI   r   r   i   s    #










 




r   Tc                    s\  t dd | D rtd|dkr*tdt| }tdd | D }|dkr|||k}|d|fkrtd	| d
||  d n&|r||krtd| d
||  d|dkrtd|dkr| d  S |rdd | D }|rtt	j
dd |D  }ntt	jdd |D  }dd t|D  t|}g }t| |D ]\}	}
|	 }|rntt	|t	|
 }|| ntt	|
t	| }||  fdd|jd D }||}|| q8n| }t dd | D }t||}|r|d }|d }n|}i }t	 }t|dD ]\}}	|	 D ]}|	| }|| krL|||< |||< q|| |kr^q||kr|| || }|| |d||< ||= ||d||< qq|r||jd< t	j
dd |D  t	dg }| }|D ]}d}dd t|D }|D ]~}	||	 krqt|	j| D ]J\}}|dkr>q(|| dkrX|||< q(|| |kr(d } qtq(|r qq|s||j|< qt|dD ]0\}}	||	 kr|	j| |jd||< qq|rXt	j
d!d |D  }| }|D ]V}d}d"d t|D }t||D ]\}	}||	 kr>q$t||	j| D ]X\}}|d#krdqN|dkrrqN|| dkr|||< qN|| |krNd } qqN|r$ qq$|s||j|< qtt||dD ]v\}\}	}||	 krqd$d t|D }t||	j| D ] \}}|d#kr2q|||< q||jd||< qܐq|S )%aJ  Graph intersection.

    The intersection of two or more graphs is created. The graphs may have
    identical or overlapping vertex sets. Edges which are included in all
    graphs will be part of the new graph.

    This function keeps the attributes of all graphs. All graph, vertex and
    edge attributes are copied to the result. If an attribute is present in
    multiple graphs and would result a name clash, then this attribute is
    renamed by adding suffixes: _1, _2, etc.

    The ``name`` vertex attribute is treated specially if the operation is
    performed based on symbolic vertex names. In this case ``name`` must be
    present in all graphs, and it is not renamed in the result graph.

    An error is generated if some input graphs are directed and others are
    undirected.

    Parameters:
        graphs: list of graphs. A lazy sequence is not acceptable.
        byname: bool or 'auto' specifying the function behaviour with
            respect to names vertices (i.e. vertices with the 'name' attribute). If
            False, ignore vertex names. If True, merge vertices based on names. If
            'auto', use True if all graphs have named vertices and False otherwise
            (in the latter case, a warning is generated too).
        keep_all_vertices: bool specifying if vertices that are not present
            in all graphs should be kept in the intersection.

    Returns:
        the intersection graph

    Raises:
        RuntimeError: if 'byname' is set to True and some graphs are not named or
            the set of names is not unique in one of the graphs
    c                 s   s   | ]}t |t V  qd S r   r   r   r   r   r   r   N  s     zintersection.<locals>.<genexpr>r   r7   r8   c                 s   s   | ]}|  V  qd S r   r9   r   r   r   r   r   U  s     r6   r   r:   r;   r<   r=   r>   z'intersection() needs at least one graphr   c                 S   s   g | ]}|j d  qS r?   rA   r   r   r   r   rB   k  s     z intersection.<locals>.<listcomp>c                 s   s   | ]}t |V  qd S r   rC   rD   r   r   r   r   n  s     c                 s   s   | ]}t |V  qd S r   rC   rD   r   r   r   r   p  s     c                 S   s   i | ]\}}||qS r   r   rE   r   r   r   rG   q  s      z intersection.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   rH   rI   r   r   rB     s     r@   c                 s   s   | ]}t | V  qd S r   rJ   r   r   r   r   r     s     rK   rL   r   c                 s   s   | ]}t | V  qd S r   rM   r   r   r   r   r     s     Fc                 S   s   g | ]}d qS r   r   rN   r   r   r   rB     s     NTc                 s   s   | ]}t | V  qd S r   rO   r   r   r   r   r     s     c                 S   s   g | ]}d qS r   r   rN   r   r   r   rB     s     c                 S   s   g | ]}d qS r   r   rN   r   r   r   rB     s     )r   r   r   r   rP   r	   rQ   r   rR   r
   r   r   r   rS   rT   Zdelete_verticesr%   rU   rV   r   r    r!   r"   r#   rW   r$   r&   r'   r(   )r)   rY   Zkeep_all_verticesr*   rZ   r[   r\   r3   r]   r   r^   r_   r`   Z	v_privatera   rL   rb   Zgraph_intsecr,   r-   r.   r/   r0   r1   rc   rd   re   r2   r5   rf   rg   r   rI   r   r   )  s    %










 






r   N)r6   )r6   T)__doc____all____docformat__Zigraph._igraphr   r   r   r   warningsr	   r   r   r   r   r   r   r   r   <module>   s   K
 A