
    \h+                     j    S SK Jr  S SKJr  \R                  rS rSS jrS rSS jrSS jr	S	 r
S
 rg)    )Permutation)_distribute_gens_by_basec                     U  Vs1 s H  n[        U5      iM     snU Vs1 s H  n[        U5      iM     sn:H  $ s  snf s  snf )a'  
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

)tuple)firstsecondas      T/var/www/auris/envauris/lib/python3.13/site-packages/sympy/combinatorics/testutil.py_cmp_perm_listsr      s@    2 $$eE!He$$%fE!Hf%& &$%s   :?c                 L  ^	^
 SSK Jn   SSKJm	  [	        US5      (       a  [        U R                  SS95      nUR                   Vs/ s H  oUR                  PM     snm
U	U
4S jn/ nU(       d?  U H7  nU" U5      (       d  M  UR                  [        R                  " U5      5        M9     U$ U H#  nU" U5      (       d  M  UR                  U5        M%     U$ [	        US5      (       a  [        X" U5      U5      $ [	        US	5      (       a  [        X" U/5      U5      $ g s  snf )
Nr   PermutationGroup)_af_commutes_with
generatorsTafc                 2   >^  [        UU 4S jT 5       5      $ )Nc              3   6   >#    U  H  nT" TU5      v   M     g 7fN ).0genr   xs     r
   	<genexpr><_naive_list_centralizer.<locals>.<lambda>.<locals>.<genexpr>C   s     *UPT+<Q+D+DPTs   )all)r   r   genss   `r
   <lambda>)_naive_list_centralizer.<locals>.<lambda>C   s    s*UPT*U'U    getitem
array_form)sympy.combinatorics.perm_groupsr    sympy.combinatorics.permutationsr   hasattrlistgenerate_diminor   _array_formappendr   _af_new_naive_list_centralizer)selfotherr   r   elementsr   commutes_with_genscentralizer_listelementr   r   s            @@r
   r+   r+   $   s   @2 Cul##,,,56','7'78'7!'78U#%g..$++K,?,?,HI $   $%g..$++G4 $  			"	"&t-=e-DbII		%	%&t-=ug-FKK 
& 9s   D!c                    SSK Jn  [        X5      nU n[        [	        U5      5       HD  nU" XF   5      nUR                  5       UR                  5       :w  a    gUR                  X   5      nMF     UR                  5       S:w  a  gg)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	candidates           r
   _verify_bsgsr>   T   s    8 A0<3t9$%6%9:	##%)::/::47C	 
 !Q&r    Nc                     Uc  U R                  U5      n[        UR                  SS95      n[        XSS9n[	        X45      $ )a  
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

Tr   )centralizerr&   r'   r+   r   )r8   argcentr
centr_listcentr_list_naives        r
   _verify_centralizerrE   }   sI    : }!!#&e++t+45J.udC:88r    c                   ^ SSK Jn   Uc  U R                  U5      n[        5       n[	        US5      (       a  UR
                  nO([	        US5      (       a  UnO[	        US5      (       a  U/nU R                  5        H  mUR                  U4S jW 5       5        M      U" [        U5      5      nUR                  U5      $ )Nr   r   r   __getitem__r"   c              3   ,   >#    U  H	  oT-  v   M     g 7fr   r   )r   r   els     r
   r   )_verify_normal_closure.<locals>.<genexpr>   s     9js(js   )
r#   r   normal_closuresetr%   r   r'   updater&   is_subgroup)r8   rA   closurer   
conjugates
subgr_gensnaive_closurerI   s          @r
   _verify_normal_closurerS      s    @. &&s+JsL!!^^
	m	$	$
	l	#	#U
##%9j99 &$T*%56M}--r    c           	      z   SSK Jn  SSKJnJn  SSKJn  / n[        [        U5      5       H"  n	X9   u  ppUR                  X/ /U-  U45        M$     U" U6 u  pnU" XUS-
  5      n[        U[        5      (       a	  SnU/nU/nO[        U5      n/ n[        U5       H#  n	UR                  U" X   X)   US-
  5      5        M%     U" U5      nU" U Vs/ s H  n[        U5      PM     sn5      n[        UR                  SS95      nU R                   n [#        5       nUR                  SS9 H8  nU" U U5      nU H&  n[%        U" UU5      5      nUR'                  U5        M(     M:     [        U5      nUR)                  5         S	U-  nU H  nUS
S US
S :X  a  US   US   :w  a    gUnM!     [        US   5      $ s  snf )a  
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   r3   Tr   )r   N)r#   r   sympy.combinatorics.tensor_canrU   rV   r$   rW   r4   r5   r)   
isinstanceintextendr   r&   generater"   rL   r   addsort)gdummiessymvr   rU   rV   rW   v1r<   base_igens_in_isym_isizesbasesgensdgens	num_typesSr   Ddliststshdqr	   prevs                                 r
   canonicalize_naivery      s   N AG9	B3q6]%&T"
		6B48U34  '+DgDF+E#s	)eH	E9Ywz364!8<= A%8%Q+a.%89At$%E	A	BZZ4Z QNAhq!n%AFF1I  !
 	RAFFH9DSb6T#2YuR 	 
 !:# 9s   F8c                    SSK Jn  SSKJnJn  [        U R                  5       5      nUR                  S SS9  U Vs/ s H  oUS   PM	     nnU" U5      nSnU H  u  pU[        U	5      -  nM     U V
s/ s H  n
/ PM     nn
Sn
U HN  u  pU	 HC  nXh   Xl   :  d  M  XU      R                  U
5        XU      R                  U
S-   5        U
S-  n
ME     MP     / nU H  nUR                  U5        M     [        U5      U:X  d   eXUS-   /-  nUS-   n[        U5      [        [        U5      5      :X  d   e[        U5      nS/[        US   5      S-   -  nU H  n	U[        U	5      ==   S-  ss'   M     / n[        [        U5      5       H0  n
X   nU(       d  M  U" U
5      u  nnUR                  UUUS45        M2     UR                  5         [        [        U5      5      nU" UUS/UQ76 nU$ s  snf s  sn
f )	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                     [        U S   5      $ )Nr3   )r5   )r   s    r
   r   #graph_certificate.<locals>.<lambda>=  s    S1Yr    T)keyreverser3   rX   )r$   r{   r[   r|   r}   r&   itemsra   r5   r)   r^   sortedr4   r   r   )grr{   r|   r}   r   r   pvertnum_indicesre   neighr<   verticesv2rb   rk   vlennr9   r   rc   cans                        r
   graph_certificater     s	   F <TE	JJ&J5 !5aqT5E!uE Ks5z!  ""EqEH"	ABx%)#q"))!,r#**1Q3/Q	   	A	 q6[   {Q	''A?D!9U4[))))AA3HQK "#DSZA 
A3t9G103JD$HHdD!Q'(	 
 IIK5%&G
q'1
)q
)CJO " #s   G04G5)Fr   )sympy.combinatoricsr   sympy.combinatorics.utilr   rmulr   r+   r>   rE   rS   ry   r   r   r    r
   <module>r      sA    + =&:-L`&R!9H%.PK\Nr    