
    E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dS )    Permutation)_distribute_gens_by_basec                 6    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                 ,    h | ]}t          |          S  tuple.0as     <lib/python3.11/site-packages/sympy/combinatorics/testutil.py	<setcomp>z"_cmp_perm_lists.<locals>.<setcomp>    s    $$$E!HH$$$    c                 ,    h | ]}t          |          S r   r	   r   s     r   r   z"_cmp_perm_lists.<locals>.<setcomp>!   s    %%%E!HH%%%r   r   )firstseconds     r   _cmp_perm_listsr      s0    2 %$e$$$%%f%%%& &r   Fc                 (  	 ddl m} 	 ddlm t	          |d          rt          |                     d                    }d |j        D             		fd}g }|s8|D ]4} ||          r'|                    t          j
        |                     5n%|D ]"} ||          r|                    |           #|S t	          |d	          rt          |  ||          |          S t	          |d
          rt          |  ||g          |          S d S )Nr   PermutationGroup)_af_commutes_with
generatorsTafc                     g | ]	}|j         
S r   )_array_formr   xs     r   
<listcomp>z+_naive_list_centralizer.<locals>.<listcomp>B   s    888!888r   c                 >     t           fdD                       S )Nc              3   0   K   | ]} |          V  d S Nr   )r   genr   r   s     r   	<genexpr>z<_naive_list_centralizer.<locals>.<lambda>.<locals>.<genexpr>C   s1      *U*U+<+<Q+D+D*U*U*U*U*U*Ur   )all)r   r   genss   `r   <lambda>z)_naive_list_centralizer.<locals>.<lambda>C   s)    s*U*U*U*U*UPT*U*U*U'U'U r   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'   s
           @@r   r2   r2   $   s   @@@@@@2 CBBBBBul## L,,,556688u'7888UUUUU 	5# J J%%g.. J$++K,?,H,HIIIJ $ 5 5%%g.. 5$++G444			"	" L&t-=-=e-D-DbIII		%	% L&t-=-=ug-F-FKKKL Lr   c                 Z   ddl m} t          ||          }| }t          t	          |                    D ][} |||                   }|                                |                                k    r dS |                    ||                   }\|                                dk    rd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	candidates           r   _verify_bsgsrE   T   s    8 A@@@@@0t<<3t99 D D$$%6q%9::	##%%):):: 	55/::47CC!!Q& u4r   Nc                     ||                      |          }t          |                    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

    NTr   )centralizerr.   r/   r2   r   )r?   argcentr
centr_listcentr_list_naives        r   _verify_centralizerrL   }   sc    :  '!!#&&e++t+4455J.ucdCCC:'7888r   c                    ddl m} 	 ||                     |          }t                      }t	          |d          r|j        }n&t	          |d          r|}nt	          |d          r|g}|                                 D ]}|D ]}|                    ||z               |t          |                    }|	                    |          S )Nr   r   r   __getitem__r*   )
r+   r   normal_closuresetr-   r   r/   addr.   is_subgroup)	r?   rH   closurer   
conjugates
subgr_genselr$   naive_closures	            r   _verify_normal_closurerX      s    @@@@@@.  ,&&s++JsL!! ^

	m	$	$ 

	l	#	# U
##%% % % 	% 	%CNN38$$$$	%$$T*%5%566M}---r   c           	         ddl m} ddlm}m} ddlm} g }t          t          |                    D ],}	||	         \  }
}}}|	                    |
|g g|z  |f           - || \  }}} ||||dz
            }t          |t                    r	d}|g}|g}nt          |          }g }t          |          D ]1}	|                     |||	         ||	         |dz
                       2 ||          } |d |D                       }t          |                    d	                    }| j        } t!                      }|                    d	          D ]A} || |          }|D ]0}t#           |||                    }|                    |           1Bt          |          }|                                 d
|z  }|D ]/}|dd         |dd         k    r|d         |d         k    r dS |}0t          |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 ot 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   r:   c                 ,    g | ]}t          |          S r   r   r   s     r   r    z&canonicalize_naive.<locals>.<listcomp>  s    888Q+a..888r   Tr   r   N)r+   r   sympy.combinatorics.tensor_canrZ   r[   r,   r\   r;   r<   r0   
isinstanceintextendr.   generater*   rP   r
   rQ   sort)gdummiessymvr   rZ   r[   r\   v1rC   base_igens_in_isym_isizesbasesgensdgens	num_typesSDdliststshdqr   prevs                                r   canonicalize_naiver      s   N A@@@@@GGGGGGGG999999	B3q66]] 5 5%&qT"U
		66B48U34444&+D%IgsDF++E#s 	)eHH	E9 > >YYwqz3q64!8<<====A88%88899At$$%%E	A	BZZ4Z    HQNN 	 	Ahhq!nn%%AFF1IIII	 	RAFFHHH9D  SbS6T#2#Y 	uR  qq!::r   c                 z   ddl m} ddlm}m} t          |                                           }|                    d d           d |D             } ||          }d}|D ]\  }}|t          |          z  }d |D             }	d}
|D ]f\  }}|D ]^}||         ||         k     rJ|	||                  	                    |
           |	||                  	                    |
d	z              |
d
z  }
_gg }|	D ]}|
                    |           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 ]3}
||
         }|r' ||
          \  }}|	                    |||df           4|                                 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                 ,    t          | d                   S )Nr:   )r<   )r   s    r   r(   z#graph_certificate.<locals>.<lambda>>  s    S1YY r   T)keyreversec                     g | ]
}|d          S r_   r   r   s     r   r    z%graph_certificate.<locals>.<listcomp>?  s    !!!aQqT!!!r   c                     g | ]}g S r   r   )r   rC   s     r   r    z%graph_certificate.<locals>.<listcomp>J  s    """q"""r   r:   r]   )r,   r   rb   r   r   r.   itemsrg   r<   r0   re   sortedr;   r   r   )grr   r   r   r   pvertnum_indicesrk   neighverticesrC   v2rh   rq   vlennr@   r'   ri   cans                       r   graph_certificater     s   F <;;;;;TTTTTTTTE	JJ&&J555!!5!!!EJuE K " "5s5zz!
 #"E"""H	A  5 	 	BQx%)# q"))!,,,r#**1Q3///Q		
 	A  	q66[    +{Q	''A?D!99U4[[))))))AA3HQK  "#D  SZZA
A3t99 ) )G 	)0033JD$HHdD!Q'(((IIKKK5%%&&G
,q'1
)q
)
)
)CJr   )Fr#   )sympy.combinatoricsr   sympy.combinatorics.utilr   rmulr   r2   rE   rL   rX   r   r   r   r   r   <module>r      s    + + + + + + = = = = = =& & &:-L -L -L -L`& & &R!9 !9 !9 !9H&. &. &. &.RK K K\N N N N Nr   