o
    FZh+                     @   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   K/var/www/auris/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   )Z_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   Z_af_new_naive_list_centralizer)selfotherr   r   elementsZcommutes_with_gensZ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orderZ
stabilizer)groupbaser"   r   Zstrong_gens_distrZcurrent_stabilizeri	candidater   r   r   _verify_bsgsT   s   
r9   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   )Zcentralizerr)   r*   r,   r   )r5   argZcentrZ
centr_listZcentr_list_naiver   r   r   _verify_centralizer}   s
   

r;   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   Znormal_closuresetr(   r   r*   updater)   Zis_subgroup)r5   r:   closurer   Z
conjugatesZ
subgr_gensZnaive_closurer   r=   r   _verify_normal_closure   s   




rB   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   r1   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_canrC   rD   r'   rE   r2   r3   r+   
isinstanceintextendr)   generater%   r?   r   addsort)gdummiessymvr   rC   rD   rE   v1r7   Zbase_iZgens_iZn_iZsym_isizeZsbaseZsgensZdgensZ	num_typesSDZdliststshdqr   prevr   r   r   canonicalize_naive   sJ   '
 
r_   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 )Nr1   )r3   r    r   r   r   r#   =  s    z#graph_certificate.<locals>.<lambda>T)keyreversec                 S   s   g | ]}|d  qS rG   r   r   r   r   r   r   >  r   z%graph_certificate.<locals>.<listcomp>c                 S   s   g | ]}g qS r   r   )r
   r7   r   r   r   r   I  s    r1   rF   )r'   r`   rJ   ra   rb   r)   itemsrP   r3   r+   rM   sortedr2   r   rd   )grr`   ra   rb   re   ZpvertZnum_indicesrT   ZneighZverticesr7   v2rQ   rV   Zvlennr6   r"   rR   Zcanr   r   r   graph_certificate  sR   #rj   )Fr   )Zsympy.combinatoricsr   Zsympy.combinatorics.utilr   Zrmulr   r,   r9   r;   rB   r_   rj   r   r   r   r   <module>   s    
0
)
$(N