+
    i+                     l    ^ RI Ht ^ RIHt ]P                  tR tRR ltR tRR ltRR lt	R	 t
R
 tR# )    )Permutation)_distribute_gens_by_basec                    V  Uu0 uF  p\        V4      kK  	  upV Uu0 uF  p\        V4      kK  	  up8H  # u upi u upi )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   && |/Users/tonyclaw/.openclaw/workspace/skills/math-calculator/venv/lib/python3.14/site-packages/sympy/combinatorics/testutil.py_cmp_perm_listsr      s@    2 $$eE!He$$%fE!Hf%& &$%s   8=c                 ^  a	a
 ^ RI Hp  ^ RIHo	 \	        VR4      '       d   \        V P                  RR7      4      pVP                   Uu. uF  qUP                  NK  	  upo
V	V
3R lp. pV'       gA   V F8  pV! V4      '       g   K  VP                  \        P                  ! V4      4       K:  	  V# V F$  pV! V4      '       g   K  VP                  V4       K&  	  V# \	        VR4      '       d   \        W! V4      V4      # \	        VR4      '       d   \        W! V.4      V4      # R	# u upi )
r   PermutationGroup)_af_commutes_with
generatorsTafc                 ~   <a  \         ;QJ d     VV 3R  lS 4       F  '       d   K   R# 	  R# ! VV 3R  lS 4       4      # )c              3   6   <"   T F  pS! SV4      x  K  	  R # 5iN ).0genr   xs   & r
   	<genexpr><_naive_list_centralizer.<locals>.<lambda>.<locals>.<genexpr>C   s     *UPT+<Q+D+DPTs   FT)all)r   r   genss   fr
   <lambda>)_naive_list_centralizer.<locals>.<lambda>C   s*    ss*UPT*Uss'Us'Us*UPT*U'U    getitem
array_formN)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                &   ^ RI Hp \        W4      pT p\        \	        V4      4       FN  pV! WF,          4      pVP                  4       VP                  4       8w  d    R# VP                  W,          4      pKP  	  VP                  4       ^8w  d   R# R# )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   FT)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                    Vf   V P                  V4      p\        VP                  RR7      4      p\        WRR7      p\	        W44      # )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   )r7   argcentr
centr_listcentr_list_naives   &&&  r
   _verify_centralizerrD   }   sI    : }!!#&e++t+45J.udC:88r    c                   a ^ RI Hp  Vf   V P                  V4      p\        4       p\	        VR4      '       d   VP
                  pM*\	        VR4      '       d   TpM\	        VR4      '       d   V.pV P                  4        F  oVP                  V3R lX 4       4       K   	  V! \        V4      4      pVP                  V4      # )r   r   r   __getitem__r"   c              3   4   <"   T F  qS,          x  K  	  R # 5i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)r7   r@   closurer   
conjugates
subgr_gensnaive_closurerH   s   &&&    @r
   _verify_normal_closurerR      s    @. &&s+JsL!!^^
	m	$	$
	l	#	#U
##%9j99 &$T*%56M}--r    c           	        ^ RI Hp ^ RIHpHp ^ RIHp . p\        \        V4      4       F*  p	W9,          w  rrVP                  W. .V,          V34       K,  	  V! V!  w  rpV! WV^,
          4      p\        V\        4      '       d
   ^pV.pV.pM\        V4      p. p\        V4       F/  p	VP                  V! W,          W),          V^,
          4      4       K1  	  V! V4      pT! V Uu. uF  p\        V4      NK  	  up4      p\        VP                  RR7      4      pV P                   p \#        4       pVP                  RR7       F8  pV! V V4      pV F&  p\%        V! VV4      4      pVP'                  V4       K(  	  K:  	  \        V4      pVP)                  4        RV,          pV F*  pVRR VRR 8X  d   VR	,          VR	,          8w  d    ^ # TpK,  	  \        V^ ,          4      # u upi )
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   )gens_products	dummy_sgs)_af_rmulTr   N)r   )r#   r   sympy.combinatorics.tensor_canrT   rU   r$   rV   r3   r4   r)   
isinstanceintextendr   r&   generater"   rK   r   addsort)gdummiessymvr   rT   rU   rV   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_naiverw      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   *G*c                   ^ RI Hp ^ RIHpHp \        V P                  4       4      pVP                  R RR7       V Uu. uF  qU^ ,          NK  	  ppV! V4      p^ pV F  w  rV\        V	4      ,          pK  	  V U
u. uF  p
. NK  	  pp
^ p
V Fo  w  rV	 Fd  pWh,          Wl,          8  g   K  WV,          ,          P                  V
4       WV,          ,          P                  V
^,           4       V
^,          p
Kf  	  Kq  	  . pV F  pVP                  V4       K  	  \        V4      V8X  g   Q hWV^,           .,          pV^,           p\        V4      \        \        V4      4      8X  g   Q h\        V4      p^ .\        V^ ,          4      ^,           ,          pV F!  p	V\        V	4      ;;,          ^,          uu&   K#  	  . p\        \        V4      4       F5  p
W,          pV'       g   K  V! V
4      w  ppVP                  VVV^ 34       K7  	  VP                  4        \        \        V4      4      pV! VV^ .VO5!  pV# u upi u up
i )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
)
_af_invert)get_symmetric_group_sgscanonicalizec                 &    \        V ^,          4      # )   )r4   )r   s   &r
   r   #graph_certificate.<locals>.<lambda>=  s    S1Yr    T)keyreverse)r$   ry   rY   rz   r{   r&   itemsr_   r4   r)   r\   sortedr3   r   r   )grry   rz   r{   r   r   pvertnum_indicesrc   neighr;   verticesv2r`   ri   vlennr8   r   ra   cans   &                    r
   graph_certificater     s   F <TE	JJ&J5 !5aqTT5E!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    I>I)Fr   )sympy.combinatoricsr   sympy.combinatorics.utilr   rmulr   r+   r=   rD   rR   rw   r   r   r    r
   <module>r      sA    + =&:-L`&R!9H%.PK\Nr    