(self, base=None, gens=None)
return _base, strong_gens
Extend a sequence of points and generating set to a base and strong
        generating set.

        Parameters
        ==========

        base
            The sequence of points to be extended to a base. Optional
            parameter with default value ``[]``.
        gens
            The generating set to be extended to a strong generating set
            relative to the base obtained. Optional parameter with default
            value ``self.generators``.

        Returns
        =======

        (base, strong_gens)
            ``base`` is the base obtained, and ``strong_gens`` is the strong
            generating set relative to it. The original parameters ``base``,
            ``gens`` remain unchanged.

        Examples
        ========

        >>> from sympy.combinatorics.named_groups import AlternatingGroup
        >>> from sympy.combinatorics.perm_groups import PermutationGroup
        >>> from sympy.combinatorics.testutil import _verify_bsgs
        >>> A = AlternatingGroup(7)
        >>> base = [2, 3]
        >>> seq = [2, 3]
        >>> base, strong_gens = A.schreier_sims_incremental(base=seq)
        >>> _verify_bsgs(A, base, strong_gens)
        True
        >>> base[:2]
        [2, 3]

        Notes
        =====

        This version of the Schreier-Sims algorithm runs in polynomial time.
        There are certain assumptions in the implementation - if the trivial
        group is provided, ``base`` and ``gens`` are returned immediately,
        as any sequence of points is a base for the trivial group. If the
        identity is present in the generators ``gens``, it is removed as
        it is a redundant generator.
        The implementation is described in [1], pp. 90-93.

        See Also
        ========

        schreier_sims, schreier_sims_random
Extend a sequence of points and generating set to a base and strong
        generating set.
Extend a sequence of points and generating set to a base and strong generating set .
def schreier_sims_incremental(self, base=None, gens=None):
        """Extend a sequence of points and generating set to a base and strong
        generating set.

        Parameters
        ==========

        base
            The sequence of points to be extended to a base. Optional
            parameter with default value ``[]``.
        gens
            The generating set to be extended to a strong generating set
            relative to the base obtained. Optional parameter with default
            value ``self.generators``.

        Returns
        =======

        (base, strong_gens)
            ``base`` is the base obtained, and ``strong_gens`` is the strong
            generating set relative to it. The original parameters ``base``,
            ``gens`` remain unchanged.

        Examples
        ========

        >>> from sympy.combinatorics.named_groups import AlternatingGroup
        >>> from sympy.combinatorics.perm_groups import PermutationGroup
        >>> from sympy.combinatorics.testutil import _verify_bsgs
        >>> A = AlternatingGroup(7)
        >>> base = [2, 3]
        >>> seq = [2, 3]
        >>> base, strong_gens = A.schreier_sims_incremental(base=seq)
        >>> _verify_bsgs(A, base, strong_gens)
        True
        >>> base[:2]
        [2, 3]

        Notes
        =====

        This version of the Schreier-Sims algorithm runs in polynomial time.
        There are certain assumptions in the implementation - if the trivial
        group is provided, ``base`` and ``gens`` are returned immediately,
        as any sequence of points is a base for the trivial group. If the
        identity is present in the generators ``gens``, it is removed as
        it is a redundant generator.
        The implementation is described in [1], pp. 90-93.

        See Also
        ========

        schreier_sims, schreier_sims_random

        """
        if base is None:
            base = []
        if gens is None:
            gens = self.generators[:]
        degree = self.degree
        id_af = list(range(degree))
        # handle the trivial group
        if len(gens) == 1 and gens[0].is_Identity:
            return base, gens
        # prevent side effects
        _base, _gens = base[:], gens[:]
        # remove the identity as a generator
        _gens = [x for x in _gens if not x.is_Identity]
        # make sure no generator fixes all base points
        for gen in _gens:
            if all(x == gen._array_form[x] for x in _base):
                for new in id_af:
                    if gen._array_form[new] != new:
                        break
                else:
                    assert None  # can this ever happen?
                _base.append(new)
        # distribute generators according to basic stabilizers
        strong_gens_distr = _distribute_gens_by_base(_base, _gens)
        # initialize the basic stabilizers, basic orbits and basic transversals
        orbs = {}
        transversals = {}
        base_len = len(_base)
        for i in range(base_len):
            transversals[i] = dict(_orbit_transversal(degree, strong_gens_distr[i],
                _base[i], pairs=True, af=True))
            orbs[i] = list(transversals[i].keys())
        # main loop: amend the stabilizer chain until we have generators
        # for all stabilizers
        i = base_len - 1
        while i >= 0:
            # this flag is used to continue with the main loop from inside
            # a nested loop
            continue_i = False
            # test the generators for being a strong generating set
            db = {}
            for beta, u_beta in list(transversals[i].items()):
                for gen in strong_gens_distr[i]:
                    gb = gen._array_form[beta]
                    u1 = transversals[i][gb]
                    g1 = _af_rmul(gen._array_form, u_beta)
                    if g1 != u1:
                        # test if the schreier generator is in the i+1-th
                        # would-be basic stabilizer
                        y = True
                        try:
                            u1_inv = db[gb]
                        except KeyError:
                            u1_inv = db[gb] = _af_invert(u1)
                        schreier_gen = _af_rmul(u1_inv, g1)
                        h, j = _strip_af(schreier_gen, _base, orbs, transversals, i)
                        if j <= base_len:
                            # new strong generator h at level j
                            y = False
                        elif h:
                            # h fixes all base points
                            y = False
                            moved = 0
                            while h[moved] == moved:
                                moved += 1
                            _base.append(moved)
                            base_len += 1
                            strong_gens_distr.append([])
                        if y is False:
                            # if a new strong generator is found, update the
                            # data structures and start over
                            h = _af_new(h)
                            for l in range(i + 1, j):
                                strong_gens_distr[l].append(h)
                                transversals[l] =\
                                dict(_orbit_transversal(degree, strong_gens_distr[l],
                                    _base[l], pairs=True, af=True))
                                orbs[l] = list(transversals[l].keys())
                            i = j - 1
                            # continue main loop using the flag
                            continue_i = True
                    if continue_i is True:
                        break
                if continue_i is True:
                    break
            if continue_i is True:
                continue
            i -= 1
        # build the strong generating set
        strong_gens = []
        for gens in strong_gens_distr:
            for gen in gens:
                if gen not in strong_gens:
                    strong_gens.append(gen)
        return _base, strong_gens
def schreier_sims_incremental ( self , base = None , gens = None ) : if base is None : base = [ ] if gens is None : gens = self . generators [ : ] degree = self . degree id_af = list ( range ( degree ) ) # handle the trivial group if len ( gens ) == 1 and gens [ 0 ] . is_Identity : return base , gens # prevent side effects _base , _gens = base [ : ] , gens [ : ] # remove the identity as a generator _gens = [ x for x in _gens if not x . is_Identity ] # make sure no generator fixes all base points for gen in _gens : if all ( x == gen . _array_form [ x ] for x in _base ) : for new in id_af : if gen . _array_form [ new ] != new : break else : assert None # can this ever happen? _base . append ( new ) # distribute generators according to basic stabilizers strong_gens_distr = _distribute_gens_by_base ( _base , _gens ) # initialize the basic stabilizers, basic orbits and basic transversals orbs = { } transversals = { } base_len = len ( _base ) for i in range ( base_len ) : transversals [ i ] = dict ( _orbit_transversal ( degree , strong_gens_distr [ i ] , _base [ i ] , pairs = True , af = True ) ) orbs [ i ] = list ( transversals [ i ] . keys ( ) ) # main loop: amend the stabilizer chain until we have generators # for all stabilizers i = base_len - 1 while i >= 0 : # this flag is used to continue with the main loop from inside # a nested loop continue_i = False # test the generators for being a strong generating set db = { } for beta , u_beta in list ( transversals [ i ] . items ( ) ) : for gen in strong_gens_distr [ i ] : gb = gen . _array_form [ beta ] u1 = transversals [ i ] [ gb ] g1 = _af_rmul ( gen . _array_form , u_beta ) if g1 != u1 : # test if the schreier generator is in the i+1-th # would-be basic stabilizer y = True try : u1_inv = db [ gb ] except KeyError : u1_inv = db [ gb ] = _af_invert ( u1 ) schreier_gen = _af_rmul ( u1_inv , g1 ) h , j = _strip_af ( schreier_gen , _base , orbs , transversals , i ) if j <= base_len : # new strong generator h at level j y = False elif h : # h fixes all base points y = False moved = 0 while h [ moved ] == moved : moved += 1 _base . append ( moved ) base_len += 1 strong_gens_distr . append ( [ ] ) if y is False : # if a new strong generator is found, update the # data structures and start over h = _af_new ( h ) for l in range ( i + 1 , j ) : strong_gens_distr [ l ] . append ( h ) transversals [ l ] = dict ( _orbit_transversal ( degree , strong_gens_distr [ l ] , _base [ l ] , pairs = True , af = True ) ) orbs [ l ] = list ( transversals [ l ] . keys ( ) ) i = j - 1 # continue main loop using the flag continue_i = True if continue_i is True : break if continue_i is True : break if continue_i is True : continue i -= 1 # build the strong generating set strong_gens = [ ] for gens in strong_gens_distr : for gen in gens : if gen not in strong_gens : strong_gens . append ( gen ) return _base , strong_gens