o
    oh+                     @   s`   d dl mZ d dlmZ ejZdd ZdddZdd	 ZdddZdddZ	dd Z
dd Zd
S )    Permutation)_distribute_gens_by_basec                 C   s   dd | D dd |D kS )ao  
    Compare two lists of permutations as sets.

    Explanation
    ===========

    This is used for testing purposes. Since the array form of a
    permutation is currently a list, Permutation is not hashable
    and cannot be put into a set.

    Examples
    ========

    >>> from sympy.combinatorics.permutations import Permutation
    >>> from sympy.combinatorics.testutil import _cmp_perm_lists
    >>> a = Permutation([0, 2, 3, 4, 1])
    >>> b = Permutation([1, 2, 0, 4, 3])
    >>> c = Permutation([3, 4, 0, 1, 2])
    >>> ls1 = [a, b, c]
    >>> ls2 = [b, c, a]
    >>> _cmp_perm_lists(ls1, ls2)
    True

    c                 S      h | ]}t |qS  tuple.0ar   r   p/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/combinatorics/testutil.py	<setcomp>        z"_cmp_perm_lists.<locals>.<setcomp>c                 S   r   r   r   r	   r   r   r   r   !   r   r   )firstsecondr   r   r   _cmp_perm_lists   s   r   Fc                    s   ddl m} 	 ddlm  t|drPt| jdd}dd |jD  fd	d
}g }|s@|D ]}||r=|t	
| q/|S |D ]}||rM|| qB|S t|dr]t| |||S t|drkt| ||g|S d S )Nr   PermutationGroup)_af_commutes_with
generatorsTafc                 S   s   g | ]}|j qS r   )_array_formr
   xr   r   r   
<listcomp>B   s    z+_naive_list_centralizer.<locals>.<listcomp>c                    s   t  fddD S )Nc                 3   s    | ]} |V  qd S Nr   r
   gen)r   r   r   r   	<genexpr>C   s    z<_naive_list_centralizer.<locals>.<lambda>.<locals>.<genexpr>)allr   r   gensr!   r   <lambda>C   s    z)_naive_list_centralizer.<locals>.<lambda>getitem
array_form)sympy.combinatorics.perm_groupsr    sympy.combinatorics.permutationsr   hasattrlistgenerate_diminor   appendr   _af_new_naive_list_centralizer)selfotherr   r   elementscommutes_with_genscentralizer_listelementr   r"   r   r.   $   s0   



r.   c                 C   sp   ddl m} t||}| }tt|D ]}||| }| | kr& dS ||| }q| dkr6dS dS )a  
    Verify the correctness of a base and strong generating set.

    Explanation
    ===========

    This is a naive implementation using the definition of a base and a strong
    generating set relative to it. There are other procedures for
    verifying a base and strong generating set, but this one will
    serve for more robust testing.

    Examples
    ========

    >>> from sympy.combinatorics.named_groups import AlternatingGroup
    >>> from sympy.combinatorics.testutil import _verify_bsgs
    >>> A = AlternatingGroup(4)
    >>> A.schreier_sims()
    >>> _verify_bsgs(A, A.base, A.strong_gens)
    True

    See Also
    ========

    sympy.combinatorics.perm_groups.PermutationGroup.schreier_sims

    r   r   F   T)r'   r   r   rangelenorder
stabilizer)groupbaser#   r   strong_gens_distrcurrent_stabilizeri	candidater   r   r   _verify_bsgsT   s   
r@   Nc                 C   s:   |du r	|  |}t|jdd}t| |dd}t||S )a3  
    Verify the centralizer of a group/set/element inside another group.

    This is used for testing ``.centralizer()`` from
    ``sympy.combinatorics.perm_groups``

    Examples
    ========

    >>> from sympy.combinatorics.named_groups import (SymmetricGroup,
    ... AlternatingGroup)
    >>> from sympy.combinatorics.perm_groups import PermutationGroup
    >>> from sympy.combinatorics.permutations import Permutation
    >>> from sympy.combinatorics.testutil import _verify_centralizer
    >>> S = SymmetricGroup(5)
    >>> A = AlternatingGroup(5)
    >>> centr = PermutationGroup([Permutation([0, 1, 2, 3, 4])])
    >>> _verify_centralizer(S, A, centr)
    True

    See Also
    ========

    _naive_list_centralizer,
    sympy.combinatorics.perm_groups.PermutationGroup.centralizer,
    _cmp_perm_lists

    NTr   )centralizerr*   r+   r.   r   )r:   argcentr
centr_listcentr_list_naiver   r   r   _verify_centralizer}   s
   

rF   c                    s   ddl m} 	 |d u r| |}t }t|dr|j}nt|dr$|}nt|dr,|g}|  D ] | fdd|D  q0|t|}|	|S )Nr   r   r   __getitem__r&   c                 3   s    | ]}| A V  qd S r   r   r   elr   r   r      s    z)_verify_normal_closure.<locals>.<genexpr>)
r'   r   normal_closuresetr)   r   r+   updater*   is_subgroup)r:   rB   closurer   
conjugates
subgr_gensnaive_closurer   rH   r   _verify_normal_closure   s   




rR   c                 G   s  ddl m} ddlm}m} ddlm} g }tt|D ]}	||	 \}
}}}|	|
|g g| |f q|| \}}}||||d }t
|trPd}|g}|g}nt|}g }t|D ]}	||||	 ||	 |d  qZ||}|dd |D }t|jd	d
}| j} t }|jd	d
D ]}|| |}|D ]}t|||}|| qqt|}|  d| }|D ]}|dd |dd kr|d |d kr dS |}qt|d S )au  
    Canonicalize tensor formed by tensors of the different types.

    Explanation
    ===========

    sym_i symmetry under exchange of two component tensors of type `i`
          None  no symmetry
          0     commuting
          1     anticommuting

    Parameters
    ==========

    g : Permutation representing the tensor.
    dummies : List of dummy indices.
    msym : Symmetry of the metric.
    v : A list of (base_i, gens_i, n_i, sym_i) for tensors of type `i`.
        base_i, gens_i BSGS for tensors of this type
        n_i  number of tensors of type `i`

    Returns
    =======

    Returns 0 if the tensor is zero, else returns the array form of
    the permutation representing the canonical form of the tensor.

    Examples
    ========

    >>> from sympy.combinatorics.testutil import canonicalize_naive
    >>> from sympy.combinatorics.tensor_can import get_symmetric_group_sgs
    >>> from sympy.combinatorics import Permutation
    >>> g = Permutation([1, 3, 2, 0, 4, 5])
    >>> base2, gens2 = get_symmetric_group_sgs(2)
    >>> canonicalize_naive(g, [2, 3], 0, (base2, gens2, 2, 0))
    [0, 2, 1, 3, 4, 5]
    r   r   )gens_products	dummy_sgs)_af_rmul   r5   c                 S   s   g | ]}t |qS r   r   r   r   r   r   r     r   z&canonicalize_naive.<locals>.<listcomp>Tr   r   N)r'   r   sympy.combinatorics.tensor_canrS   rT   r(   rU   r6   r7   r,   
isinstanceintextendr*   generater&   rK   r   addsort)gdummiessymvr   rS   rT   rU   v1r>   base_igens_in_isym_isizesbasesgensdgens	num_typesSDdliststshdqr   prevr   r   r   canonicalize_naive   sJ   '
 
rx   c                 C   s  ddl m} ddlm}m} t|  }|jdd dd dd	 |D }||}d}|D ]
\}}|t|7 }q,d
d	 |D }	d}
|D ])\}}|D ]"}|| || k rj|	||  	|
 |	||  	|
d  |
d7 }
qHqBg }|	D ]}|
| qpt||ksJ |||d g7 }|d }t|tt|ksJ t|}dgt|	d d  }|	D ]}|t|  d7  < qg }tt|D ]}
||
 }|r||
\}}|	|||df q|  tt|}|||dg|R  }|S )a  
    Return a certificate for the graph

    Parameters
    ==========

    gr : adjacency list

    Explanation
    ===========

    The graph is assumed to be unoriented and without
    external lines.

    Associate to each vertex of the graph a symmetric tensor with
    number of indices equal to the degree of the vertex; indices
    are contracted when they correspond to the same line of the graph.
    The canonical form of the tensor gives a certificate for the graph.

    This is not an efficient algorithm to get the certificate of a graph.

    Examples
    ========

    >>> from sympy.combinatorics.testutil import graph_certificate
    >>> gr1 = {0:[1, 2, 3, 5], 1:[0, 2, 4], 2:[0, 1, 3, 4], 3:[0, 2, 4], 4:[1, 2, 3, 5], 5:[0, 4]}
    >>> gr2 = {0:[1, 5], 1:[0, 2, 3, 4], 2:[1, 3, 5], 3:[1, 2, 4, 5], 4:[1, 3, 5], 5:[0, 2, 3, 4]}
    >>> c1 = graph_certificate(gr1)
    >>> c2 = graph_certificate(gr2)
    >>> c1
    [0, 2, 4, 6, 1, 8, 10, 12, 3, 14, 16, 18, 5, 9, 15, 7, 11, 17, 13, 19, 20, 21]
    >>> c1 == c2
    True
    r   )
_af_invert)get_symmetric_group_sgscanonicalizec                 S   s   t | d S )Nr5   )r7   r!   r   r   r   r$   =  s    z#graph_certificate.<locals>.<lambda>T)keyreversec                 S   s   g | ]}|d  qS rW   r   r   r   r   r   r   >  r   z%graph_certificate.<locals>.<listcomp>c                 S   s   g | ]}g qS r   r   )r
   r>   r   r   r   r   I  s    r5   rV   )r(   ry   rZ   rz   r{   r*   itemsr`   r7   r,   r]   sortedr6   r   r}   )grry   rz   r{   r~   pvertnum_indicesrd   neighverticesr>   v2ra   rj   vlennr;   r#   rb   canr   r   r   graph_certificate  sR   #r   )Fr   )sympy.combinatoricsr   sympy.combinatorics.utilr   rmulr   r.   r@   rF   rR   rx   r   r   r   r   r   <module>   s    
0
)
$(N