
    wg+                     d    d dl mZ d dlmZ ej                  Zd ZddZd ZddZddZ	d	 Z
d
 Zy)    )Permutation)_distribute_gens_by_basec                 |    | D ch c]  }t        |       c}|D ch c]  }t        |       c}k(  S c c}w c c}w )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

    )tuple)firstsecondas      a/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/combinatorics/testutil.py_cmp_perm_listsr      s8    2 $$E!H$$%E!H%& &$%s   49c                   	
 ddl m} 	 ddlm	 t	        |d      rt        | j                  d            }|j                  D cg c]  }|j                   c}
	
fd}g }|s6|D ]/  } ||      s|j                  t        j                  |             1 |S |D ]  } ||      s|j                  |        |S t	        |d      rt        |  ||      |      S t	        |d	      rt        |  ||g      |      S y c c}w )
Nr   PermutationGroup)_af_commutes_with
generatorsTafc                 0     t         fdD              S )Nc              3   0   K   | ]  } |        y wN ).0genr   xs     r
   	<genexpr>z<_naive_list_centralizer.<locals>.<lambda>.<locals>.<genexpr>C   s     *U+<Q+D*Us   )all)r   r   genss   `r
   <lambda>z)_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!8U# J%g.$++K,?,?,HIJ   $ 5%g.$++G45  			"&t-=e-DbII		%&t-=ug-FKK 
& 9s   C>c                 
   ddl m} t        ||      }| }t        t	        |            D ]D  } |||         }|j                         |j                         k7  r y|j                  ||         }F |j                         dk7  ryy)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t<3t9 D$%6q%9:	##%)::/::47C	D
 !Q&r   Nc                     || j                  |      }t        |j                  d            }t        | |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

    Tr   )centralizerr$   r%   r)   r   )r6   argcentr
centr_listcentr_list_naives        r
   _verify_centralizerrC   }   sN    : }!!#&e++t+45J.ucdC:'788r   c                 \   ddl m} 	 || j                  |      }t               }t	        |d      r|j
                  }nt	        |d      r|}nt	        |d      r|g}| j                         D ]  |j                  fdD                 |t        |            }|j                  |      S )Nr   r   r   __getitem__r    c              3   (   K   | ]	  }|z    y wr   r   )r   r   els     r
   r   z)_verify_normal_closure.<locals>.<genexpr>   s     9s#(9s   )
r!   r   normal_closuresetr#   r   r%   updater$   is_subgroup)r6   r?   closurer   
conjugates
subgr_gensnaive_closurerG   s          @r
   _verify_normal_closurerP      s    @. &&s+JsL!^^
	m	$
	l	#U
##% :9j99:$T*%56M}--r   c           	      n   ddl m} ddlm}m} ddlm} g }t        t        |            D ]%  }	||	   \  }
}}}|j                  |
|g g|z  |f       '  || \  }}} ||||dz
        }t        |t              r	d}|g}|g}nt        |      }g }t        |      D ]$  }	|j                   |||	   ||	   |dz
               &  ||      } ||D cg c]  }t        |       c}      }t        |j                  d            }| j                   } t#               }|j                  d      D ]5  } || |      }|D ]%  }t%         |||            }|j'                  |       ' 7 t        |      }|j)                          d	|z  }|D ]  }|d
d |d
d k(  r|d   |d   k7  r y|} t        |d         S c c}w )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   Tr   )r   N)r!   r   sympy.combinatorics.tensor_canrR   rS   r"   rT   r2   r3   r'   
isinstanceintextendr   r$   generater    rI   r   addsort)gdummiessymvr   rR   rS   rT   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_naiverv      s   N AG9	B3q6] 5%&qT"U
		66B48U345 '+D%gsDF+E#s	)eH	E9 >Ywqz3q64!8<=>A%8Q+a.89At$%E	A	BZZ4Z  QN 	Ahq!n%AFF1I	
 	RAFFH9D Sb6T#2YuR 	
 !:# 9s   F2c                    ddl m} ddlm}m} t        | j                               }|j                  d d       |D cg c]  }|d   	 }} ||      }d}|D ]  \  }}	|t        |	      z  } |D 
cg c]  }
g  }}
d}
|D ]N  \  }}	|	D ]D  }||   ||   k  s|||      j                  |
       |||      j                  |
dz          |
dz  }
F P g }|D ]  }|j                  |        t        |      |k(  sJ |||dz   gz  }|dz   }t        |      t        t        |            k(  sJ t        |      }dgt        |d         dz   z  }|D ]  }	|t        |	      xx   dz  cc<    g }t        t        |            D ]*  }
||
   }|s ||
      \  }}|j                  |||df       , |j                          t        t        |            } |||dg| }|S c c}w c c}
w )	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                     t        | d         S )Nr1   )r3   )r   s    r
   r   z#graph_certificate.<locals>.<lambda>=  s    S1Y r   T)keyreverser1   rU   )r"   rx   rX   ry   rz   r$   itemsr^   r3   r'   r[   sortedr2   r   r}   )grrx   ry   rz   r~   r   pvertnum_indicesrb   neighr:   verticesv2r_   rh   vlennr7   r   r`   cans                        r
   graph_certificater     s5   F <TE	JJ&J5 !aQqT!E!uE K "5s5z!" ""q"H"	A 5 	BQx%)#q"))!,r#**1Q3/Q		 	A 	q6[   +{Q	''A?D!9U4[))))AA3HQK "#D SZA
A3t9 )G03JD$HHdD!Q'(	)
 IIK5%&G
q'1
)q
)CJO " #s    G 4	G%)Fr   )sympy.combinatoricsr   sympy.combinatorics.utilr   rmulr   r)   r<   rC   rP   rv   r   r   r   r
   <module>r      sA    + =&:-L`&R!9H%.PK\Nr   