def test_subgroup_presentations(): F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**5, (x*y)**2]) H = [x*y, x**-1*y**-1*x*y*x] p1 = reidemeister_presentation(f, H) assert str(p1) == "((y_1, y_2), (y_1**2, y_2**3, y_2*y_1*y_2*y_1*y_2*y_1))" H = f.subgroup(H) assert (H.generators, H.relators) == p1 f = FpGroup(F, [x**3, y**3, (x*y)**3]) H = [x*y, x*y**-1] p2 = reidemeister_presentation(f, H) assert str(p2) == "((x_0, y_0), (x_0**3, y_0**3, x_0*y_0*x_0*y_0*x_0*y_0))" f = FpGroup(F, [x**2*y**2, y**-1*x*y*x**-3]) H = [x] p3 = reidemeister_presentation(f, H) assert str(p3) == "((x_0,), (x_0**4,))" f = FpGroup(F, [x**3*y**-3, (x*y)**3, (x*y**-1)**2]) H = [x] p4 = reidemeister_presentation(f, H) assert str(p4) == "((x_0,), (x_0**6,))" # this presentation can be improved, the most simplified form # of presentation is <a, b | a^11, b^2, (a*b)^3, (a^4*b*a^-5*b)^2> # See [2] Pg 474 group PSL_2(11) # This is the group PSL_2(11) F, a, b, c = free_group("a, b, c") f = FpGroup(F, [a**11, b**5, c**4, (b*c**2)**2, (a*b*c)**3, (a**4*c**2)**3, b**2*c**-1*b**-1*c, a**4*b**-1*a**-1*b]) H = [a, b, c**2] gens, rels = reidemeister_presentation(f, H) assert str(gens) == "(b_1, c_3)" assert len(rels) == 18
def test_order(): from sympy import S F, x, y = free_group("x, y") f = FpGroup(F, [x**4, y**2, x*y*x**-1*y]) assert f.order() == 8 f = FpGroup(F, [x*y*x**-1*y**-1, y**2]) assert f.order() == S.Infinity F, a, b, c = free_group("a, b, c") f = FpGroup(F, [a**250, b**2, c*b*c**-1*b, c**4, c**-1*a**-1*c*a, a**-1*b**-1*a*b]) assert f.order() == 2000
def test_homomorphism(): # FpGroup -> PermutationGroup F, a, b = free_group("a, b") G = FpGroup(F, [a**3, b**3, (a*b)**2]) c = Permutation(3)(0, 1, 2) d = Permutation(3)(1, 2, 3) A = AlternatingGroup(4) T = homomorphism(G, A, [a, b], [c, d]) assert T(a*b**2*a**-1) == c*d**2*c**-1 assert T.is_isomorphism() assert T(T.invert(Permutation(3)(0, 2, 3))) == Permutation(3)(0, 2, 3) T = homomorphism(G, AlternatingGroup(4), G.generators) assert T.is_trivial() assert T.kernel().order() == G.order() E, e = free_group("e") G = FpGroup(E, [e**8]) P = PermutationGroup([Permutation(0, 1, 2, 3), Permutation(0, 2)]) T = homomorphism(G, P, [e], [Permutation(0, 1, 2, 3)]) assert T.image().order() == 4 assert T(T.invert(Permutation(0, 2)(1, 3))) == Permutation(0, 2)(1, 3) T = homomorphism(E, AlternatingGroup(4), E.generators, [c]) assert T.invert(c**2) == e**-1 #order(c) == 3 so c**2 == c**-1 # FreeGroup -> FreeGroup T = homomorphism(F, E, [a], [e]) assert T(a**-2*b**4*a**2).is_identity # FreeGroup -> FpGroup G = FpGroup(F, [a*b*a**-1*b**-1]) T = homomorphism(F, G, F.generators, G.generators) assert T.invert(a**-1*b**-1*a**2) == a*b**-1 # PermutationGroup -> PermutationGroup D = DihedralGroup(8) p = Permutation(0, 1, 2, 3, 4, 5, 6, 7) P = PermutationGroup(p) T = homomorphism(P, D, [p], [p]) assert T.is_injective() assert not T.is_isomorphism() assert T.invert(p**3) == p**3 T2 = homomorphism(F, P, [F.generators[0]], P.generators) T = T.compose(T2) assert T.domain == F assert T.codomain == D assert T(a*b) == p
def define_schreier_generators(C): y = [] gamma = 1 f = C.fp_group X = f.generators C.P = [[None]*len(C.A) for i in range(C.n)] for alpha, x in product(C.omega, C.A): beta = C.table[alpha][C.A_dict[x]] if beta == gamma: C.P[alpha][C.A_dict[x]] = "<identity>" C.P[beta][C.A_dict_inv[x]] = "<identity>" gamma += 1 elif x in X and C.P[alpha][C.A_dict[x]] is None: y_alpha_x = '%s_%s' % (x, alpha) y.append(y_alpha_x) C.P[alpha][C.A_dict[x]] = y_alpha_x grp_gens = list(free_group(', '.join(y))) C._schreier_free_group = grp_gens.pop(0) C._schreier_generators = grp_gens # replace all elements of P by, free group elements for i, j in product(range(len(C.P)), range(len(C.A))): # if equals "<identity>", replace by identity element if C.P[i][j] == "<identity>": C.P[i][j] = C._schreier_free_group.identity elif isinstance(C.P[i][j], str): r = C._schreier_generators[y.index(C.P[i][j])] C.P[i][j] = r beta = C.table[i][j] C.P[beta][j + 1] = r**-1
def test_fp_subgroup(): def _test_subgroup(K, T, S): _gens = T(K.generators) assert all(elem in S for elem in _gens) assert T.is_injective() assert T.image().order() == S.order() F, x, y = free_group("x, y") f = FpGroup(F, [x**4, y**2, x*y*x**-1*y]) S = FpSubgroup(f, [x*y]) assert (x*y)**-3 in S K, T = f.subgroup([x*y], homomorphism=True) assert T(K.generators) == [y*x**-1] _test_subgroup(K, T, S) S = FpSubgroup(f, [x**-1*y*x]) assert x**-1*y**4*x in S assert x**-1*y**4*x**2 not in S K, T = f.subgroup([x**-1*y*x], homomorphism=True) assert T(K.generators[0]**3) == y**3 _test_subgroup(K, T, S) f = FpGroup(F, [x**3, y**5, (x*y)**2]) H = [x*y, x**-1*y**-1*x*y*x] K, T = f.subgroup(H, homomorphism=True) S = FpSubgroup(f, H) _test_subgroup(K, T, S)
def test_permutation_methods(): from sympy.combinatorics.fp_groups import FpSubgroup F, x, y = free_group("x, y") # DihedralGroup(8) G = FpGroup(F, [x**2, y**8, x*y*x**-1*y]) T = G._to_perm_group()[1] assert T.is_isomorphism() assert G.center() == [y**4] # DiheadralGroup(4) G = FpGroup(F, [x**2, y**4, x*y*x**-1*y]) S = FpSubgroup(G, G.normal_closure([x])) assert x in S assert y**-1*x*y in S # Z_5xZ_4 G = FpGroup(F, [x*y*x**-1*y**-1, y**5, x**4]) assert G.is_abelian assert G.is_solvable # AlternatingGroup(5) G = FpGroup(F, [x**3, y**2, (x*y)**5]) assert not G.is_solvable # AlternatingGroup(4) G = FpGroup(F, [x**3, y**2, (x*y)**3]) assert len(G.derived_series()) == 3 S = FpSubgroup(G, G.derived_subgroup()) assert S.order() == 4
def __init__(self, fp_grp, subgroup, max_cosets=None): if not max_cosets: max_cosets = CosetTable.coset_table_max_limit self.fp_group = fp_grp self.subgroup = subgroup self.coset_table_max_limit = max_cosets # "p" is setup independent of Ω and n self.p = [0] # a list of the form `[gen_1, gen_1^{-1}, ... , gen_k, gen_k^{-1}]` self.A = list(chain.from_iterable((gen, gen**-1) \ for gen in self.fp_group.generators)) #P[alpha, x] Only defined when alpha^x is defined. self.P = [[None]*len(self.A)] # the mathematical coset table which is a list of lists self.table = [[None]*len(self.A)] self.A_dict = {x: self.A.index(x) for x in self.A} self.A_dict_inv = {} for x, index in self.A_dict.items(): if index % 2 == 0: self.A_dict_inv[x] = self.A_dict[x] + 1 else: self.A_dict_inv[x] = self.A_dict[x] - 1 # used in the coset-table based method of coset enumeration. Each of # the element is called a "deduction" which is the form (α, x) whenever # a value is assigned to α^x during a definition or "deduction process" self.deduction_stack = [] # Attributes for modified methods. H = self.subgroup self._grp = free_group(', ' .join(["a_%d" % i for i in range(len(H))]))[0] self.P = [[None]*len(self.A)] self.p_p = {}
def test_subgroup_presentations(): F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**5, (x*y)**2]) H = [x*y, x**-1*y**-1*x*y*x] p1 = reidemeister_presentation(f, H) assert str(p1) == "((y_1, y_2), (y_1**2, y_2**3, y_2*y_1*y_2*y_1*y_2*y_1))" f = FpGroup(F, [x**3, y**3, (x*y)**3]) H = [x*y, x*y**-1] p2 = reidemeister_presentation(f, H) assert str(p2) == "((x_0, y_0), (x_0**3, y_0**3, x_0*y_0*x_0*y_0*x_0*y_0))" f = FpGroup(F, [x**2*y**2, y**-1*x*y*x**-3]) H = [x] p3 = reidemeister_presentation(f, H) assert str(p3) == "((x_0,), (x_0**4,))" f = FpGroup(F, [x**3*y**-3, (x*y)**3, (x*y**-1)**2]) H = [x] p4 = reidemeister_presentation(f, H) assert str(p4) == "((x_0,), (x_0**6,))" # this presentation can be improved, the most simplified form # of presentation is <a, b | a^11, b^2, (a*b)^3, (a^4*b*a^-5*b)^2> # See [2] Pg 474 group PSL_2(11) # This is the group PSL_2(11) F, a, b, c = free_group("a, b, c") f = FpGroup(F, [a**11, b**5, c**4, (b*c**2)**2, (a*b*c)**3, (a**4*c**2)**3, b**2*c**-1*b**-1*c, a**4*b**-1*a**-1*b]) H = [a, b, c**2] k = ("((a_0, b_1, c_3), " "(c_3**3, b_1**5, a_0**4*b_1**-2*a_0**-1*b_1**2, " "c_3*b_1**-2*c_3*b_1**-2*c_3*b_1**-2, b_1**-1*a_0*b_1**2*c_3**-1*b_1**-1*a_0*b_1**2*c_3**-1, " "a_0**11, a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1**2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1**2*c_3, " "a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1, " "a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1, " "a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1, " "b_1**-2*c_3*b_1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*a_0*b_1**2*c_3**-1*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2, " "b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1**2*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1, " "b_1**2*c_3*b_1**-2*c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*b_1**2*c_3**-1*b_1*c_3, " "b_1**2*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1**-2*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1, " "c_3*b_1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*c_3*b_1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*c_3*b_1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1, " "c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*b_1**2*c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*b_1**2, " "b_1**2*a_0*b_1**2*c_3**-1*b_1**-1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*b_1**2*c_3**-1*b_1**2*c_3*b_1*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1, " "c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0*c_3**-1*b_1*a_0*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0, " "a_0**5*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0**5*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1*a_0**5*b_1**-2*a_0*b_1**2*c_3**-1*b_1**-2*c_3**-1*b_1))" ) assert str(reidemeister_presentation(f, H)) == k
def test_cyclic(): F, x, y = free_group("x, y") f = FpGroup(F, [x*y, x**-1*y**-1*x*y*x]) assert f.is_cyclic f = FpGroup(F, [x*y, x*y**-1]) assert f.is_cyclic f = FpGroup(F, [x**4, y**2, x*y*x**-1*y]) assert not f.is_cyclic
def simplify_presentation(*args, **kwargs): ''' For an instance of `FpGroup`, return a simplified isomorphic copy of the group (e.g. remove redundant generators or relators). Alternatively, a list of generators and relators can be passed in which case the simplified lists will be returned. By default, the generators of the group are unchanged. If you would like to remove redundant generators, set the keyword argument `change_gens = True`. ''' change_gens = kwargs.get("change_gens", False) if len(args) == 1: if not isinstance(args[0], FpGroup): raise TypeError("The argument must be an instance of FpGroup") G = args[0] gens, rels = simplify_presentation(G.generators, G.relators, change_gens=change_gens) if gens: return FpGroup(gens[0].group, rels) return FpGroup(FreeGroup([]), []) elif len(args) == 2: gens, rels = args[0][:], args[1][:] if not gens: return gens, rels identity = gens[0].group.identity else: if len(args) == 0: m = "Not enough arguments" else: m = "Too many arguments" raise RuntimeError(m) prev_gens = [] prev_rels = [] while not set(prev_rels) == set(rels): prev_rels = rels while change_gens and not set(prev_gens) == set(gens): prev_gens = gens gens, rels = elimination_technique_1(gens, rels, identity) rels = _simplify_relators(rels, identity) if change_gens: syms = [g.array_form[0][0] for g in gens] F = free_group(syms)[0] identity = F.identity gens = F.generators subs = dict(zip(syms, gens)) for j, r in enumerate(rels): a = r.array_form rel = identity for sym, p in a: rel = rel*subs[sym]**p rels[j] = rel return gens, rels
def test_order(): F, x, y = free_group("x, y") f = FpGroup(F, [x**4, y**2, x*y*x**-1*y]) assert f.order() == 8 f = FpGroup(F, [x*y*x**-1*y**-1, y**2]) assert f.order() == S.Infinity F, a, b, c = free_group("a, b, c") f = FpGroup(F, [a**250, b**2, c*b*c**-1*b, c**4, c**-1*a**-1*c*a, a**-1*b**-1*a*b]) assert f.order() == 2000 F, x = free_group("x") f = FpGroup(F, []) assert f.order() == S.Infinity f = FpGroup(free_group('')[0], []) assert f.order() == 1
def test_fp_subgroup(): F, x, y = free_group("x, y") f = FpGroup(F, [x**4, y**2, x*y*x**-1*y]) S = FpSubgroup(f, [x*y]) assert (x*y)**-3 in S S = FpSubgroup(F, [x**-1*y*x]) assert x**-1*y**4*x in S assert x**-1*y**4*x**2 not in S
def test_isomorphisms(): F, a, b = free_group("a, b") E, c, d = free_group("c, d") # Infinite groups with differently ordered relators. G = FpGroup(F, [a**2, b**3]) H = FpGroup(F, [b**3, a**2]) assert is_isomorphic(G, H) # Trivial Case # FpGroup -> FpGroup H = FpGroup(F, [a**3, b**3, (a*b)**2]) F, c, d = free_group("c, d") G = FpGroup(F, [c**3, d**3, (c*d)**2]) check, T = group_isomorphism(G, H) assert check T(c**3*d**2) == a**3*b**2 # FpGroup -> PermutationGroup # FpGroup is converted to the equivalent isomorphic group. F, a, b = free_group("a, b") G = FpGroup(F, [a**3, b**3, (a*b)**2]) H = AlternatingGroup(4) check, T = group_isomorphism(G, H) assert check assert T(b*a*b**-1*a**-1*b**-1) == Permutation(0, 2, 3) assert T(b*a*b*a**-1*b**-1) == Permutation(0, 3, 2) # PermutationGroup -> PermutationGroup D = DihedralGroup(8) p = Permutation(0, 1, 2, 3, 4, 5, 6, 7) P = PermutationGroup(p) assert not is_isomorphic(D, P) A = CyclicGroup(5) B = CyclicGroup(7) assert not is_isomorphic(A, B) # Two groups of the same prime order are isomorphic to each other. G = FpGroup(F, [a, b**5]) H = CyclicGroup(5) assert G.order() == H.order() assert is_isomorphic(G, H)
def test_free_group(): G, a, b, c = free_group("a, b, c") assert F.generators == (x, y, z) assert x*z**2 in F assert x in F assert y*z**-1 in F assert (y*z)**0 in F assert a not in F assert a**0 not in F assert len(F) == 3 assert str(F) == '<free group on the generators (x, y, z)>' assert not F == G assert F.order() == oo assert F.is_abelian == False assert F.center() == set([F.identity]) (e,) = free_group("") assert e.order() == 1 assert e.generators == () assert e.elements == set([e.identity]) assert e.is_abelian == True
def define_schreier_generators(C, homomorphism=False): ''' Parameters ========== C -- Coset table. homomorphism -- When set to True, return a dictionary containing the images of the presentation generators in the original group. ''' y = [] gamma = 1 f = C.fp_group X = f.generators if homomorphism: # `_gens` stores the elements of the parent group to # to which the schreier generators correspond to. _gens = {} # compute the schreier Traversal tau = {} tau[0] = f.identity C.P = [[None]*len(C.A) for i in range(C.n)] for alpha, x in product(C.omega, C.A): beta = C.table[alpha][C.A_dict[x]] if beta == gamma: C.P[alpha][C.A_dict[x]] = "<identity>" C.P[beta][C.A_dict_inv[x]] = "<identity>" gamma += 1 if homomorphism: tau[beta] = tau[alpha]*x elif x in X and C.P[alpha][C.A_dict[x]] is None: y_alpha_x = '%s_%s' % (x, alpha) y.append(y_alpha_x) C.P[alpha][C.A_dict[x]] = y_alpha_x if homomorphism: _gens[y_alpha_x] = tau[alpha]*x*tau[beta]**-1 grp_gens = list(free_group(', '.join(y))) C._schreier_free_group = grp_gens.pop(0) C._schreier_generators = grp_gens if homomorphism: C._schreier_gen_elem = _gens # replace all elements of P by, free group elements for i, j in product(range(len(C.P)), range(len(C.A))): # if equals "<identity>", replace by identity element if C.P[i][j] == "<identity>": C.P[i][j] = C._schreier_free_group.identity elif isinstance(C.P[i][j], string_types): r = C._schreier_generators[y.index(C.P[i][j])] C.P[i][j] = r beta = C.table[i][j] C.P[beta][j + 1] = r**-1
def subgroup(self, gens, C=None): ''' Return the subgroup generated by `gens` using the Reidemeister-Schreier algorithm ''' if not all([isinstance(g, FreeGroupElement) for g in gens]): raise ValueError("Generators must be `FreeGroupElement`s") if not all([g.group == self.free_group for g in gens]): raise ValueError("Given generators are not members of the group") g, rels = reidemeister_presentation(self, gens, C=C) if g: g = FpGroup(g[0].group, rels) else: g = FpGroup(free_group('')[0], []) return g
def test_rewriting(): F, a, b = free_group("a, b") G = FpGroup(F, [a*b*a**-1*b**-1]) a, b = G.generators R = G._rewriting_system assert R.is_confluent == False R.make_confluent() assert R.is_confluent == True assert G.reduce(b**3*a**4*b**-2*a) == a**5*b assert G.equals(b**2*a**-1*b, b**4*a**-1*b**-1) G = FpGroup(F, [a**3, b**3, (a*b)**2]) R = G._rewriting_system R.make_confluent() assert R.is_confluent assert G.reduce(b*a**-1*b**-1*a**3*b**4*a**-1*b**-15) == a**-1*b**-1
def test_look_ahead(): # Section 3.2 [Test Example] Example (d) from [2] F, a, b, c = free_group("a, b, c") f = FpGroup(F, [a**11, b**5, c**4, (a*c)**3, b**2*c**-1*b**-1*c, a**4*b**-1*a**-1*b]) H = [c, b, c**2] table0 = [[1, 2, 0, 0, 0, 0], [3, 0, 4, 5, 6, 7], [0, 8, 9, 10, 11, 12], [5, 1, 10, 13, 14, 15], [16, 5, 16, 1, 17, 18], [4, 3, 1, 8, 19, 20], [12, 21, 22, 23, 24, 1], [25, 26, 27, 28, 1, 24], [2, 10, 5, 16, 22, 28], [10, 13, 13, 2, 29, 30]] CosetTable.max_stack_size = 10 C_c = coset_enumeration_c(f, H) C_c.compress(); C_c.standardize() assert C_c.table[: 10] == table0
def test_rewriting(): F, a, b = free_group("a, b") G = FpGroup(F, [a*b*a**-1*b**-1]) a, b = G.generators R = G._rewriting_system assert R.is_confluent assert G.reduce(b**-1*a) == a*b**-1 assert G.reduce(b**3*a**4*b**-2*a) == a**5*b assert G.equals(b**2*a**-1*b, b**4*a**-1*b**-1) G = FpGroup(F, [a**3, b**3, (a*b)**2]) R = G._rewriting_system R.make_confluent() # R._is_confluent should be set to True after # a successful run of make_confluent assert R.is_confluent # but also the system should actually be confluent assert R._check_confluence() assert G.reduce(b*a**-1*b**-1*a**3*b**4*a**-1*b**-15) == a**-1*b**-1
def test_rewriting(): F, a, b = free_group("a, b") G = FpGroup(F, [a*b*a**-1*b**-1]) a, b = G.generators R = G._rewriting_system assert R.is_confluent assert G.reduce(b**-1*a) == a*b**-1 assert G.reduce(b**3*a**4*b**-2*a) == a**5*b assert G.equals(b**2*a**-1*b, b**4*a**-1*b**-1) assert R.reduce_using_automaton(b*a*a**2*b**-1) == a**3 assert R.reduce_using_automaton(b**3*a**4*b**-2*a) == a**5*b assert R.reduce_using_automaton(b**-1*a) == a*b**-1 G = FpGroup(F, [a**3, b**3, (a*b)**2]) R = G._rewriting_system R.make_confluent() # R._is_confluent should be set to True after # a successful run of make_confluent assert R.is_confluent # but also the system should actually be confluent assert R._check_confluence() assert G.reduce(b*a**-1*b**-1*a**3*b**4*a**-1*b**-15) == a**-1*b**-1 # check for automaton reduction assert R.reduce_using_automaton(b*a**-1*b**-1*a**3*b**4*a**-1*b**-15) == a**-1*b**-1 G = FpGroup(F, [a**2, b**3, (a*b)**4]) R = G._rewriting_system assert G.reduce(a**2*b**-2*a**2*b) == b**-1 assert R.reduce_using_automaton(a**2*b**-2*a**2*b) == b**-1 assert G.reduce(a**3*b**-2*a**2*b) == a**-1*b**-1 assert R.reduce_using_automaton(a**3*b**-2*a**2*b) == a**-1*b**-1 # Check after adding a rule R.add_rule(a**2, b) assert R.reduce_using_automaton(a**2*b**-2*a**2*b) == b**-1 assert R.reduce_using_automaton(a**4*b**-2*a**2*b**3) == b
def subgroup(self, gens, C=None, homomorphism=False): ''' Return the subgroup generated by `gens` using the Reidemeister-Schreier algorithm homomorphism -- When set to True, return a dictionary containing the images of the presentation generators in the original group. Examples ======== >>> from sympy.combinatorics.fp_groups import (FpGroup, FpSubgroup) >>> from sympy.combinatorics.free_groups import free_group >>> F, x, y = free_group("x, y") >>> f = FpGroup(F, [x**3, y**5, (x*y)**2]) >>> H = [x*y, x**-1*y**-1*x*y*x] >>> K, T = f.subgroup(H, homomorphism=True) >>> T(K.generators) [x*y, x**-1*y**2*x**-1] ''' if not all([isinstance(g, FreeGroupElement) for g in gens]): raise ValueError("Generators must be `FreeGroupElement`s") if not all([g.group == self.free_group for g in gens]): raise ValueError("Given generators are not members of the group") if homomorphism: g, rels, _gens = reidemeister_presentation(self, gens, C=C, homomorphism=True) else: g, rels = reidemeister_presentation(self, gens, C=C) if g: g = FpGroup(g[0].group, rels) else: g = FpGroup(free_group('')[0], []) if homomorphism: from sympy.combinatorics.homomorphisms import homomorphism return g, homomorphism(g, self, g.generators, _gens, check=False) return g
def test_coset_enumeration(): # this test function contains the combined tests for the two strategies # i.e. HLT and Felsch strategies. # Example 5.1 from [1] F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) C_r = coset_enumeration_r(f, [x]) C_r.compress(); C_r.standardize() C_c = coset_enumeration_c(f, [x]) C_c.compress(); C_c.standardize() table1 = [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1]] assert C_r.table == table1 assert C_c.table == table1 # E₁ from [2] Pg. 474 F, r, s, t = free_group("r, s, t") E1 = FpGroup(F, [t**-1*r*t*r**-2, r**-1*s*r*s**-2, s**-1*t*s*t**-2]) C_r = coset_enumeration_r(E1, []) C_r.compress() C_c = coset_enumeration_c(E1, []) C_c.compress() table2 = [[0, 0, 0, 0, 0, 0]] assert C_r.table == table2 # test for issue #11449 assert C_c.table == table2 # Cox group from [2] Pg. 474 F, a, b = free_group("a, b") Cox = FpGroup(F, [a**6, b**6, (a*b)**2, (a**2*b**2)**2, (a**3*b**3)**5]) C_r = coset_enumeration_r(Cox, [a]) C_r.compress(); C_r.standardize() C_c = coset_enumeration_c(Cox, [a]) C_c.compress(); C_c.standardize() table3 = [[0, 0, 1, 2], [2, 3, 4, 0], [5, 1, 0, 6], [1, 7, 8, 9], [9, 10, 11, 1], [12, 2, 9, 13], [14, 9, 2, 11], [3, 12, 15, 16], [16, 17, 18, 3], [6, 4, 3, 5], [4, 19, 20, 21], [21, 22, 6, 4], [7, 5, 23, 24], [25, 23, 5, 18], [19, 6, 22, 26], [24, 27, 28, 7], [29, 8, 7, 30], [8, 31, 32, 33], [33, 34, 13, 8], [10, 14, 35, 35], [35, 36, 37, 10], [30, 11, 10, 29], [11, 38, 39, 14], [13, 39, 38, 12], [40, 15, 12, 41], [42, 13, 34, 43], [44, 35, 14, 45], [15, 46, 47, 34], [34, 48, 49, 15], [50, 16, 21, 51], [52, 21, 16, 49], [17, 50, 53, 54], [54, 55, 56, 17], [41, 18, 17, 40], [18, 28, 27, 25], [26, 20, 19, 19], [20, 57, 58, 59], [59, 60, 51, 20], [22, 52, 61, 23], [23, 62, 63, 22], [64, 24, 33, 65], [48, 33, 24, 61], [62, 25, 54, 66], [67, 54, 25, 68], [57, 26, 59, 69], [70, 59, 26, 63], [27, 64, 71, 72], [72, 73, 68, 27], [28, 41, 74, 75], [75, 76, 30, 28], [31, 29, 77, 78], [79, 77, 29, 37], [38, 30, 76, 80], [78, 81, 82, 31], [43, 32, 31, 42], [32, 83, 84, 85], [85, 86, 65, 32], [36, 44, 87, 88], [88, 89, 90, 36], [45, 37, 36, 44], [37, 82, 81, 79], [80, 74, 41, 38], [39, 42, 91, 92], [92, 93, 45, 39], [46, 40, 94, 95], [96, 94, 40, 56], [97, 91, 42, 82], [83, 43, 98, 99], [100, 98, 43, 47], [101, 87, 44, 90], [82, 45, 93, 97], [95, 102, 103, 46], [104, 47, 46, 105], [47, 106, 107, 100], [61, 108, 109, 48], [105, 49, 48, 104], [49, 110, 111, 52], [51, 111, 110, 50], [112, 53, 50, 113], [114, 51, 60, 115], [116, 61, 52, 117], [53, 118, 119, 60], [60, 70, 66, 53], [55, 67, 120, 121], [121, 122, 123, 55], [113, 56, 55, 112], [56, 103, 102, 96], [69, 124, 125, 57], [115, 58, 57, 114], [58, 126, 127, 128], [128, 128, 69, 58], [66, 129, 130, 62], [117, 63, 62, 116], [63, 125, 124, 70], [65, 109, 108, 64], [131, 71, 64, 132], [133, 65, 86, 134], [135, 66, 70, 136], [68, 130, 129, 67], [137, 120, 67, 138], [132, 68, 73, 131], [139, 69, 128, 140], [71, 141, 142, 86], [86, 143, 144, 71], [145, 72, 75, 146], [147, 75, 72, 144], [73, 145, 148, 120], [120, 149, 150, 73], [74, 151, 152, 94], [94, 153, 146, 74], [76, 147, 154, 77], [77, 155, 156, 76], [157, 78, 85, 158], [143, 85, 78, 154], [155, 79, 88, 159], [160, 88, 79, 161], [151, 80, 92, 162], [163, 92, 80, 156], [81, 157, 164, 165], [165, 166, 161, 81], [99, 107, 106, 83], [134, 84, 83, 133], [84, 167, 168, 169], [169, 170, 158, 84], [87, 171, 172, 93], [93, 163, 159, 87], [89, 160, 173, 174], [174, 175, 176, 89], [90, 90, 89, 101], [91, 177, 178, 98], [98, 179, 162, 91], [180, 95, 100, 181], [179, 100, 95, 152], [153, 96, 121, 148], [182, 121, 96, 183], [177, 97, 165, 184], [185, 165, 97, 172], [186, 99, 169, 187], [188, 169, 99, 178], [171, 101, 174, 189], [190, 174, 101, 176], [102, 180, 191, 192], [192, 193, 183, 102], [103, 113, 194, 195], [195, 196, 105, 103], [106, 104, 197, 198], [199, 197, 104, 109], [110, 105, 196, 200], [198, 201, 133, 106], [107, 186, 202, 203], [203, 204, 181, 107], [108, 116, 205, 206], [206, 207, 132, 108], [109, 133, 201, 199], [200, 194, 113, 110], [111, 114, 208, 209], [209, 210, 117, 111], [118, 112, 211, 212], [213, 211, 112, 123], [214, 208, 114, 125], [126, 115, 215, 216], [217, 215, 115, 119], [218, 205, 116, 130], [125, 117, 210, 214], [212, 219, 220, 118], [136, 119, 118, 135], [119, 221, 222, 217], [122, 182, 223, 224], [224, 225, 226, 122], [138, 123, 122, 137], [123, 220, 219, 213], [124, 139, 227, 228], [228, 229, 136, 124], [216, 222, 221, 126], [140, 127, 126, 139], [127, 230, 231, 232], [232, 233, 140, 127], [129, 135, 234, 235], [235, 236, 138, 129], [130, 132, 207, 218], [141, 131, 237, 238], [239, 237, 131, 150], [167, 134, 240, 241], [242, 240, 134, 142], [243, 234, 135, 220], [221, 136, 229, 244], [149, 137, 245, 246], [247, 245, 137, 226], [220, 138, 236, 243], [244, 227, 139, 221], [230, 140, 233, 248], [238, 249, 250, 141], [251, 142, 141, 252], [142, 253, 254, 242], [154, 255, 256, 143], [252, 144, 143, 251], [144, 257, 258, 147], [146, 258, 257, 145], [259, 148, 145, 260], [261, 146, 153, 262], [263, 154, 147, 264], [148, 265, 266, 153], [246, 267, 268, 149], [260, 150, 149, 259], [150, 250, 249, 239], [162, 269, 270, 151], [262, 152, 151, 261], [152, 271, 272, 179], [159, 273, 274, 155], [264, 156, 155, 263], [156, 270, 269, 163], [158, 256, 255, 157], [275, 164, 157, 276], [277, 158, 170, 278], [279, 159, 163, 280], [161, 274, 273, 160], [281, 173, 160, 282], [276, 161, 166, 275], [283, 162, 179, 284], [164, 285, 286, 170], [170, 188, 184, 164], [166, 185, 189, 173], [173, 287, 288, 166], [241, 254, 253, 167], [278, 168, 167, 277], [168, 289, 290, 291], [291, 292, 187, 168], [189, 293, 294, 171], [280, 172, 171, 279], [172, 295, 296, 185], [175, 190, 297, 297], [297, 298, 299, 175], [282, 176, 175, 281], [176, 294, 293, 190], [184, 296, 295, 177], [284, 178, 177, 283], [178, 300, 301, 188], [181, 272, 271, 180], [302, 191, 180, 303], [304, 181, 204, 305], [183, 266, 265, 182], [306, 223, 182, 307], [303, 183, 193, 302], [308, 184, 188, 309], [310, 189, 185, 311], [187, 301, 300, 186], [305, 202, 186, 304], [312, 187, 292, 313], [314, 297, 190, 315], [191, 316, 317, 204], [204, 318, 319, 191], [320, 192, 195, 321], [322, 195, 192, 319], [193, 320, 323, 223], [223, 324, 325, 193], [194, 326, 327, 211], [211, 328, 321, 194], [196, 322, 329, 197], [197, 330, 331, 196], [332, 198, 203, 333], [318, 203, 198, 329], [330, 199, 206, 334], [335, 206, 199, 336], [326, 200, 209, 337], [338, 209, 200, 331], [201, 332, 339, 240], [240, 340, 336, 201], [202, 341, 342, 292], [292, 343, 333, 202], [205, 344, 345, 210], [210, 338, 334, 205], [207, 335, 346, 237], [237, 347, 348, 207], [208, 349, 350, 215], [215, 351, 337, 208], [352, 212, 217, 353], [351, 217, 212, 327], [328, 213, 224, 323], [354, 224, 213, 355], [349, 214, 228, 356], [357, 228, 214, 345], [358, 216, 232, 359], [360, 232, 216, 350], [344, 218, 235, 361], [362, 235, 218, 348], [219, 352, 363, 364], [364, 365, 355, 219], [222, 358, 366, 367], [367, 368, 353, 222], [225, 354, 369, 370], [370, 371, 372, 225], [307, 226, 225, 306], [226, 268, 267, 247], [227, 373, 374, 233], [233, 360, 356, 227], [229, 357, 361, 234], [234, 375, 376, 229], [248, 231, 230, 230], [231, 377, 378, 379], [379, 380, 359, 231], [236, 362, 381, 245], [245, 382, 383, 236], [384, 238, 242, 385], [340, 242, 238, 346], [347, 239, 246, 381], [386, 246, 239, 387], [388, 241, 291, 389], [343, 291, 241, 339], [375, 243, 364, 390], [391, 364, 243, 383], [373, 244, 367, 392], [393, 367, 244, 376], [382, 247, 370, 394], [395, 370, 247, 396], [377, 248, 379, 397], [398, 379, 248, 374], [249, 384, 399, 400], [400, 401, 387, 249], [250, 260, 402, 403], [403, 404, 252, 250], [253, 251, 405, 406], [407, 405, 251, 256], [257, 252, 404, 408], [406, 409, 277, 253], [254, 388, 410, 411], [411, 412, 385, 254], [255, 263, 413, 414], [414, 415, 276, 255], [256, 277, 409, 407], [408, 402, 260, 257], [258, 261, 416, 417], [417, 418, 264, 258], [265, 259, 419, 420], [421, 419, 259, 268], [422, 416, 261, 270], [271, 262, 423, 424], [425, 423, 262, 266], [426, 413, 263, 274], [270, 264, 418, 422], [420, 427, 307, 265], [266, 303, 428, 425], [267, 386, 429, 430], [430, 431, 396, 267], [268, 307, 427, 421], [269, 283, 432, 433], [433, 434, 280, 269], [424, 428, 303, 271], [272, 304, 435, 436], [436, 437, 284, 272], [273, 279, 438, 439], [439, 440, 282, 273], [274, 276, 415, 426], [285, 275, 441, 442], [443, 441, 275, 288], [289, 278, 444, 445], [446, 444, 278, 286], [447, 438, 279, 294], [295, 280, 434, 448], [287, 281, 449, 450], [451, 449, 281, 299], [294, 282, 440, 447], [448, 432, 283, 295], [300, 284, 437, 452], [442, 453, 454, 285], [309, 286, 285, 308], [286, 455, 456, 446], [450, 457, 458, 287], [311, 288, 287, 310], [288, 454, 453, 443], [445, 456, 455, 289], [313, 290, 289, 312], [290, 459, 460, 461], [461, 462, 389, 290], [293, 310, 463, 464], [464, 465, 315, 293], [296, 308, 466, 467], [467, 468, 311, 296], [298, 314, 469, 470], [470, 471, 472, 298], [315, 299, 298, 314], [299, 458, 457, 451], [452, 435, 304, 300], [301, 312, 473, 474], [474, 475, 309, 301], [316, 302, 476, 477], [478, 476, 302, 325], [341, 305, 479, 480], [481, 479, 305, 317], [324, 306, 482, 483], [484, 482, 306, 372], [485, 466, 308, 454], [455, 309, 475, 486], [487, 463, 310, 458], [454, 311, 468, 485], [486, 473, 312, 455], [459, 313, 488, 489], [490, 488, 313, 342], [491, 469, 314, 472], [458, 315, 465, 487], [477, 492, 485, 316], [463, 317, 316, 468], [317, 487, 493, 481], [329, 447, 464, 318], [468, 319, 318, 463], [319, 467, 448, 322], [321, 448, 467, 320], [475, 323, 320, 466], [432, 321, 328, 437], [438, 329, 322, 434], [323, 474, 452, 328], [483, 494, 486, 324], [466, 325, 324, 475], [325, 485, 492, 478], [337, 422, 433, 326], [437, 327, 326, 432], [327, 436, 424, 351], [334, 426, 439, 330], [434, 331, 330, 438], [331, 433, 422, 338], [333, 464, 447, 332], [449, 339, 332, 440], [465, 333, 343, 469], [413, 334, 338, 418], [336, 439, 426, 335], [441, 346, 335, 415], [440, 336, 340, 449], [416, 337, 351, 423], [339, 451, 470, 343], [346, 443, 450, 340], [480, 493, 487, 341], [469, 342, 341, 465], [342, 491, 495, 490], [361, 407, 414, 344], [418, 345, 344, 413], [345, 417, 408, 357], [381, 446, 442, 347], [415, 348, 347, 441], [348, 414, 407, 362], [356, 408, 417, 349], [423, 350, 349, 416], [350, 425, 420, 360], [353, 424, 436, 352], [479, 363, 352, 435], [428, 353, 368, 476], [355, 452, 474, 354], [488, 369, 354, 473], [435, 355, 365, 479], [402, 356, 360, 419], [405, 361, 357, 404], [359, 420, 425, 358], [476, 366, 358, 428], [427, 359, 380, 482], [444, 381, 362, 409], [363, 481, 477, 368], [368, 393, 390, 363], [365, 391, 394, 369], [369, 490, 480, 365], [366, 478, 483, 380], [380, 398, 392, 366], [371, 395, 496, 497], [497, 498, 489, 371], [473, 372, 371, 488], [372, 486, 494, 484], [392, 400, 403, 373], [419, 374, 373, 402], [374, 421, 430, 398], [390, 411, 406, 375], [404, 376, 375, 405], [376, 403, 400, 393], [397, 430, 421, 377], [482, 378, 377, 427], [378, 484, 497, 499], [499, 499, 397, 378], [394, 461, 445, 382], [409, 383, 382, 444], [383, 406, 411, 391], [385, 450, 443, 384], [492, 399, 384, 453], [457, 385, 412, 493], [387, 442, 446, 386], [494, 429, 386, 456], [453, 387, 401, 492], [389, 470, 451, 388], [493, 410, 388, 457], [471, 389, 462, 495], [412, 390, 393, 399], [462, 394, 391, 410], [401, 392, 398, 429], [396, 445, 461, 395], [498, 496, 395, 460], [456, 396, 431, 494], [431, 397, 499, 496], [399, 477, 481, 412], [429, 483, 478, 401], [410, 480, 490, 462], [496, 497, 484, 431], [489, 495, 491, 459], [495, 460, 459, 471], [460, 489, 498, 498], [472, 472, 471, 491]] C_r.table == table3 C_c.table == table3 # Group denoted by B₂,₄ from [2] Pg. 474 F, a, b = free_group("a, b") B_2_4 = FpGroup(F, [a**4, b**4, (a*b)**4, (a**-1*b)**4, (a**2*b)**4, \ (a*b**2)**4, (a**2*b**2)**4, (a**-1*b*a*b)**4, (a*b**-1*a*b)**4]) C_r = coset_enumeration_r(B_2_4, [a]) C_c = coset_enumeration_c(B_2_4, [a]) index_r = 0 for i in range(len(C_r.p)): if C_r.p[i] == i: index_r += 1 assert index_r == 1024 index_c = 0 for i in range(len(C_c.p)): if C_c.p[i] == i: index_c += 1 assert index_c == 1024 # trivial Macdonald group G(2,2) from [2] Pg. 480 M = FpGroup(F, [b**-1*a**-1*b*a*b**-1*a*b*a**-2, a**-1*b**-1*a*b*a**-1*b*a*b**-2]) C_r = coset_enumeration_r(M, [a]) C_r.compress(); C_r.standardize() C_c = coset_enumeration_c(M, [a]) C_c.compress(); C_c.standardize() table4 = [[0, 0, 0, 0]] assert C_r.table == table4 assert C_c.table == table4
def test_scan_1(): # Example 5.1 from [1] F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) c = CosetTable(f, [x]) c.scan_and_fill(0, x) assert c.table == [[0, 0, None, None]] assert c.p == [0] assert c.n == 1 assert c.omega == [0] c.scan_and_fill(0, x**3) assert c.table == [[0, 0, None, None]] assert c.p == [0] assert c.n == 1 assert c.omega == [0] c.scan_and_fill(0, y**3) assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [None, None, 0, 1]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(0, x**-1*y**-1*x*y) assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [2, 2, 0, 1]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, x**3) assert c.table == [[0, 0, 1, 2], [3, 4, 2, 0], [2, 2, 0, 1], \ [4, 1, None, None], [1, 3, None, None]] assert c.p == [0, 1, 2, 3, 4] assert c.n == 5 assert c.omega == [0, 1, 2, 3, 4] c.scan_and_fill(1, y**3) assert c.table == [[0, 0, 1, 2], [3, 4, 2, 0], [2, 2, 0, 1], \ [4, 1, None, None], [1, 3, None, None]] assert c.p == [0, 1, 2, 3, 4] assert c.n == 5 assert c.omega == [0, 1, 2, 3, 4] c.scan_and_fill(1, x**-1*y**-1*x*y) assert c.table == [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1], \ [None, 1, None, None], [1, 3, None, None]] assert c.p == [0, 1, 2, 1, 1] assert c.n == 3 assert c.omega == [0, 1, 2] # Example 5.2 from [1] f = FpGroup(F, [x**2, y**3, (x*y)**3]) c = CosetTable(f, [x*y]) c.scan_and_fill(0, x*y) assert c.table == [[1, None, None, 1], [None, 0, 0, None]] assert c.p == [0, 1] assert c.n == 2 assert c.omega == [0, 1] c.scan_and_fill(0, x**2) assert c.table == [[1, 1, None, 1], [0, 0, 0, None]] assert c.p == [0, 1] assert c.n == 2 assert c.omega == [0, 1] c.scan_and_fill(0, y**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(0, (x*y)**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, x**2) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, y**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, (x*y)**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [3, 4, 1, 0], [None, 2, 4, None], [2, None, None, 3]] assert c.p == [0, 1, 2, 3, 4] assert c.n == 5 assert c.omega == [0, 1, 2, 3, 4] c.scan_and_fill(2, x**2) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [3, 3, 1, 0], [2, 2, 3, 3], [2, None, None, 3]] assert c.p == [0, 1, 2, 3, 3] assert c.n == 4 assert c.omega == [0, 1, 2, 3]
def test_low_index_subgroups(): F, x, y = free_group("x, y") # Example 5.10 from [1] Pg. 194 f = FpGroup(F, [x**2, y**3, (x * y)**4]) L = low_index_subgroups(f, 4) t1 = [[[0, 0, 0, 0]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 3, 3]], [[0, 0, 1, 2], [2, 2, 2, 0], [1, 1, 0, 1]], [[1, 1, 0, 0], [0, 0, 1, 1]]] for i in range(len(t1)): assert L[i].table == t1[i] f = FpGroup(F, [x**2, y**3, (x * y)**7]) L = low_index_subgroups(f, 15) t2 = [[[0, 0, 0, 0]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [4, 4, 5, 3], [6, 6, 3, 4], [5, 5, 6, 6]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [5, 5, 3, 4], [4, 4, 6, 6]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [7, 7, 3, 4], [4, 4, 8, 9], [5, 5, 10, 11], [11, 11, 9, 6], [9, 9, 6, 8], [12, 12, 11, 7], [8, 8, 7, 10], [10, 10, 13, 14], [14, 14, 14, 12], [13, 13, 12, 13]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [7, 7, 3, 4], [4, 4, 8, 9], [5, 5, 10, 11], [11, 11, 9, 6], [12, 12, 6, 8], [10, 10, 11, 7], [8, 8, 7, 10], [9, 9, 13, 14], [14, 14, 14, 12], [13, 13, 12, 13]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [7, 7, 3, 4], [4, 4, 8, 9], [5, 5, 10, 11], [11, 11, 9, 6], [12, 12, 6, 8], [13, 13, 11, 7], [8, 8, 7, 10], [9, 9, 12, 12], [10, 10, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 3, 3], [2, 2, 5, 6], [7, 7, 6, 4], [8, 8, 4, 5], [5, 5, 8, 9], [6, 6, 9, 7], [10, 10, 7, 8], [9, 9, 11, 12], [11, 11, 12, 10], [13, 13, 10, 11], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 3, 3], [2, 2, 5, 6], [7, 7, 6, 4], [8, 8, 4, 5], [5, 5, 8, 9], [6, 6, 9, 7], [10, 10, 7, 8], [9, 9, 11, 12], [13, 13, 12, 10], [12, 12, 10, 11], [11, 11, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 4, 4], [7, 7, 6, 3], [8, 8, 3, 5], [5, 5, 8, 9], [6, 6, 9, 7], [10, 10, 7, 8], [9, 9, 11, 12], [13, 13, 12, 10], [12, 12, 10, 11], [11, 11, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [5, 5, 6, 3], [9, 9, 3, 5], [10, 10, 8, 4], [8, 8, 4, 7], [6, 6, 10, 11], [7, 7, 11, 9], [12, 12, 9, 10], [11, 11, 13, 14], [14, 14, 14, 12], [13, 13, 12, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [6, 6, 6, 3], [5, 5, 3, 5], [8, 8, 8, 4], [7, 7, 4, 7]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [9, 9, 6, 3], [6, 6, 3, 5], [10, 10, 8, 4], [11, 11, 4, 7], [5, 5, 10, 12], [7, 7, 12, 9], [8, 8, 11, 11], [13, 13, 9, 10], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [9, 9, 6, 3], [6, 6, 3, 5], [10, 10, 8, 4], [11, 11, 4, 7], [5, 5, 12, 11], [7, 7, 10, 10], [8, 8, 9, 12], [13, 13, 11, 9], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [9, 9, 6, 3], [10, 10, 3, 5], [7, 7, 8, 4], [11, 11, 4, 7], [5, 5, 9, 9], [6, 6, 11, 12], [8, 8, 12, 10], [13, 13, 10, 11], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [9, 9, 6, 3], [10, 10, 3, 5], [7, 7, 8, 4], [11, 11, 4, 7], [5, 5, 12, 11], [6, 6, 10, 10], [8, 8, 9, 12], [13, 13, 11, 9], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [9, 9, 6, 3], [10, 10, 3, 5], [11, 11, 8, 4], [12, 12, 4, 7], [5, 5, 9, 9], [6, 6, 12, 13], [7, 7, 11, 11], [8, 8, 13, 10], [13, 13, 10, 12]], [[1, 1, 0, 0], [0, 0, 2, 3], [4, 4, 3, 1], [5, 5, 1, 2], [2, 2, 4, 4], [3, 3, 6, 7], [7, 7, 7, 5], [6, 6, 5, 6]]] for i in range(len(t2)): assert L[i].table == t2[i] f = FpGroup(F, [x**2, y**3, (x * y)**7]) L = low_index_subgroups(f, 10, [x]) t3 = [[[0, 0, 0, 0]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [4, 4, 5, 3], [6, 6, 3, 4], [5, 5, 6, 6]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [5, 5, 3, 4], [4, 4, 6, 6]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [6, 6, 6, 3], [5, 5, 3, 5], [8, 8, 8, 4], [7, 7, 4, 7]]] for i in range(len(t3)): assert L[i].table == t3[i]
def to_FpGroup(self): if isinstance(self.parent, FreeGroup): gen_syms = [('x_%d' % i) for i in range(len(self.generators))] return free_group(', '.join(gen_syms))[0] return self.parent.subgroup(C=self.C)
def test_FreeGroup__eq__(): assert free_group("x, y, z")[0] == free_group("x, y, z")[0] assert free_group("x, y, z")[0] is free_group("x, y, z")[0] assert free_group("x, y, z")[0] != free_group("a, x, y")[0] assert free_group("x, y, z")[0] is not free_group("a, x, y")[0] assert free_group("x, y")[0] != free_group("x, y, z")[0] assert free_group("x, y")[0] is not free_group("x, y, z")[0] assert free_group("x, y, z")[0] != free_group("x, y")[0] assert free_group("x, y, z")[0] is not free_group("x, y")[0]
from sympy.combinatorics.free_groups import free_group, FreeGroup from sympy.core import Symbol from sympy.utilities.pytest import raises from sympy import oo F, x, y, z = free_group("x, y, z") def test_FreeGroup__init__(): x, y, z = map(Symbol, "xyz") assert len(FreeGroup("x, y, z").generators) == 3 assert len(FreeGroup(x).generators) == 1 assert len(FreeGroup(("x", "y", "z"))) == 3 assert len(FreeGroup((x, y, z)).generators) == 3 def test_free_group(): G, a, b, c = free_group("a, b, c") assert F.generators == (x, y, z) assert x * z**2 in F assert x in F assert y * z**-1 in F assert (y * z)**0 in F assert a not in F assert a**0 not in F assert len(F) == 3 assert str(F) == '<free group on the generators (x, y, z)>' assert not F == G assert F.order() == oo assert F.is_abelian == False
def test_scan_1(): # Example 5.1 from [1] F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**3, x**-1 * y**-1 * x * y]) c = CosetTable(f, [x]) c.scan_and_fill(0, x) assert c.table == [[0, 0, None, None]] assert c.p == [0] assert c.n == 1 assert c.omega == [0] c.scan_and_fill(0, x**3) assert c.table == [[0, 0, None, None]] assert c.p == [0] assert c.n == 1 assert c.omega == [0] c.scan_and_fill(0, y**3) assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [None, None, 0, 1]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(0, x**-1 * y**-1 * x * y) assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [2, 2, 0, 1]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, x**3) assert c.table == [[0, 0, 1, 2], [3, 4, 2, 0], [2, 2, 0, 1], \ [4, 1, None, None], [1, 3, None, None]] assert c.p == [0, 1, 2, 3, 4] assert c.n == 5 assert c.omega == [0, 1, 2, 3, 4] c.scan_and_fill(1, y**3) assert c.table == [[0, 0, 1, 2], [3, 4, 2, 0], [2, 2, 0, 1], \ [4, 1, None, None], [1, 3, None, None]] assert c.p == [0, 1, 2, 3, 4] assert c.n == 5 assert c.omega == [0, 1, 2, 3, 4] c.scan_and_fill(1, x**-1 * y**-1 * x * y) assert c.table == [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1], \ [None, 1, None, None], [1, 3, None, None]] assert c.p == [0, 1, 2, 1, 1] assert c.n == 3 assert c.omega == [0, 1, 2] # Example 5.2 from [1] f = FpGroup(F, [x**2, y**3, (x * y)**3]) c = CosetTable(f, [x * y]) c.scan_and_fill(0, x * y) assert c.table == [[1, None, None, 1], [None, 0, 0, None]] assert c.p == [0, 1] assert c.n == 2 assert c.omega == [0, 1] c.scan_and_fill(0, x**2) assert c.table == [[1, 1, None, 1], [0, 0, 0, None]] assert c.p == [0, 1] assert c.n == 2 assert c.omega == [0, 1] c.scan_and_fill(0, y**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(0, (x * y)**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, x**2) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, y**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]] assert c.p == [0, 1, 2] assert c.n == 3 assert c.omega == [0, 1, 2] c.scan_and_fill(1, (x * y)**3) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [3, 4, 1, 0], [None, 2, 4, None], [2, None, None, 3]] assert c.p == [0, 1, 2, 3, 4] assert c.n == 5 assert c.omega == [0, 1, 2, 3, 4] c.scan_and_fill(2, x**2) assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [3, 3, 1, 0], [2, 2, 3, 3], [2, None, None, 3]] assert c.p == [0, 1, 2, 3, 3] assert c.n == 4 assert c.omega == [0, 1, 2, 3]
from sympy.combinatorics.free_groups import free_group, FreeGroup from sympy.core import Symbol from sympy.utilities.pytest import raises from sympy import oo F, x, y, z = free_group("x, y, z") def test_FreeGroup__init__(): x, y, z = map(Symbol, "xyz") assert len(FreeGroup("x, y, z").generators) == 3 assert len(FreeGroup(x).generators) == 1 assert len(FreeGroup(("x", "y", "z"))) == 3 assert len(FreeGroup((x, y, z)).generators) == 3 def test_free_group(): G, a, b, c = free_group("a, b, c") assert F.generators == (x, y, z) assert x*z**2 in F assert x in F assert y*z**-1 in F assert (y*z)**0 in F assert a not in F assert a**0 not in F assert len(F) == 3 assert str(F) == '<free group on the generators (x, y, z)>' assert not F == G assert F.order() == oo assert F.is_abelian == False
def test_modified_methods(): ''' Tests for modified coset table methods. Example 5.7 from [1] Holt, D., Eick, B., O'Brien "Handbook of Computational Group Theory". ''' F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**5, (x*y)**2]) H = [x*y, x**-1*y**-1*x*y*x] C = CosetTable(f, H) C.modified_define(0, x) identity = C._grp.identity a_0 = C._grp.generators[0] a_1 = C._grp.generators[1] assert C.P == [[identity, None, None, None], [None, identity, None, None]] assert C.table == [[1, None, None, None], [None, 0, None, None]] C.modified_define(1, x) assert C.table == [[1, None, None, None], [2, 0, None, None], [None, 1, None, None]] assert C.P == [[identity, None, None, None], [identity, identity, None, None], [None, identity, None, None]] C.modified_scan(0, x**3, C._grp.identity, fill=False) assert C.P == [[identity, identity, None, None], [identity, identity, None, None], [identity, identity, None, None]] assert C.table == [[1, 2, None, None], [2, 0, None, None], [0, 1, None, None]] C.modified_scan(0, x*y, C._grp.generators[0], fill=False) assert C.P == [[identity, identity, None, a_0**-1], [identity, identity, a_0, None], [identity, identity, None, None]] assert C.table == [[1, 2, None, 1], [2, 0, 0, None], [0, 1, None, None]] C.modified_define(2, y**-1) assert C.table == [[1, 2, None, 1], [2, 0, 0, None], [0, 1, None, 3], [None, None, 2, None]] assert C.P == [[identity, identity, None, a_0**-1], [identity, identity, a_0, None], [identity, identity, None, identity], [None, None, identity, None]] C.modified_scan(0, x**-1*y**-1*x*y*x, C._grp.generators[1]) assert C.table == [[1, 2, None, 1], [2, 0, 0, None], [0, 1, None, 3], [3, 3, 2, None]] assert C.P == [[identity, identity, None, a_0**-1], [identity, identity, a_0, None], [identity, identity, None, identity], [a_1, a_1**-1, identity, None]] C.modified_scan(2, (x*y)**2, C._grp.identity) assert C.table == [[1, 2, 3, 1], [2, 0, 0, None], [0, 1, None, 3], [3, 3, 2, 0]] assert C.P == [[identity, identity, a_1**-1, a_0**-1], [identity, identity, a_0, None], [identity, identity, None, identity], [a_1, a_1**-1, identity, a_1]] C.modified_define(2, y) assert C.table == [[1, 2, 3, 1], [2, 0, 0, None], [0, 1, 4, 3], [3, 3, 2, 0], [None, None, None, 2]] assert C.P == [[identity, identity, a_1**-1, a_0**-1], [identity, identity, a_0, None], [identity, identity, identity, identity], [a_1, a_1**-1, identity, a_1], [None, None, None, identity]] C.modified_scan(0, y**5, C._grp.identity) assert C.table == [[1, 2, 3, 1], [2, 0, 0, 4], [0, 1, 4, 3], [3, 3, 2, 0], [None, None, 1, 2]] assert C.P == [[identity, identity, a_1**-1, a_0**-1], [identity, identity, a_0, a_0*a_1**-1], [identity, identity, identity, identity], [a_1, a_1**-1, identity, a_1], [None, None, a_1*a_0**-1, identity]] C.modified_scan(1, (x*y)**2, C._grp.identity) assert C.table == [[1, 2, 3, 1], [2, 0, 0, 4], [0, 1, 4, 3], [3, 3, 2, 0], [4, 4, 1, 2]] assert C.P == [[identity, identity, a_1**-1, a_0**-1], [identity, identity, a_0, a_0*a_1**-1], [identity, identity, identity, identity], [a_1, a_1**-1, identity, a_1], [a_0*a_1**-1, a_1*a_0**-1, a_1*a_0**-1, identity]] # Modified coset enumeration test f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) C = coset_enumeration_r(f, [x]) C_m = modified_coset_enumeration_r(f, [x]) assert C_m.table == C.table
def to_FpGroup(self): if isinstance(self.parent, FreeGroup): gen_syms = [('x_%d'%i) for i in range(len(self.generators))] return free_group(', '.join(gen_syms))[0] return self.parent.subgroup(C=self.C)
def test_modified_methods(): """ Tests for modified coset table methods. Example 5.7 from [1] Holt, D., Eick, B., O'Brien "Handbook of Computational Group Theory". """ F, x, y = free_group("x, y") f = FpGroup(F, [x ** 3, y ** 5, (x * y) ** 2]) H = [x * y, x ** -1 * y ** -1 * x * y * x] C = CosetTable(f, H) C.modified_define(0, x) identity = C._grp.identity a_0 = C._grp.generators[0] a_1 = C._grp.generators[1] assert C.P == [[identity, None, None, None], [None, identity, None, None]] assert C.table == [[1, None, None, None], [None, 0, None, None]] C.modified_define(1, x) assert C.table == [[1, None, None, None], [2, 0, None, None], [None, 1, None, None]] assert C.P == [ [identity, None, None, None], [identity, identity, None, None], [None, identity, None, None], ] C.modified_scan(0, x ** 3, C._grp.identity, fill=False) assert C.P == [ [identity, identity, None, None], [identity, identity, None, None], [identity, identity, None, None], ] assert C.table == [[1, 2, None, None], [2, 0, None, None], [0, 1, None, None]] C.modified_scan(0, x * y, C._grp.generators[0], fill=False) assert C.P == [ [identity, identity, None, a_0 ** -1], [identity, identity, a_0, None], [identity, identity, None, None], ] assert C.table == [[1, 2, None, 1], [2, 0, 0, None], [0, 1, None, None]] C.modified_define(2, y ** -1) assert C.table == [ [1, 2, None, 1], [2, 0, 0, None], [0, 1, None, 3], [None, None, 2, None], ] assert C.P == [ [identity, identity, None, a_0 ** -1], [identity, identity, a_0, None], [identity, identity, None, identity], [None, None, identity, None], ] C.modified_scan(0, x ** -1 * y ** -1 * x * y * x, C._grp.generators[1]) assert C.table == [ [1, 2, None, 1], [2, 0, 0, None], [0, 1, None, 3], [3, 3, 2, None], ] assert C.P == [ [identity, identity, None, a_0 ** -1], [identity, identity, a_0, None], [identity, identity, None, identity], [a_1, a_1 ** -1, identity, None], ] C.modified_scan(2, (x * y) ** 2, C._grp.identity) assert C.table == [[1, 2, 3, 1], [2, 0, 0, None], [0, 1, None, 3], [3, 3, 2, 0]] assert C.P == [ [identity, identity, a_1 ** -1, a_0 ** -1], [identity, identity, a_0, None], [identity, identity, None, identity], [a_1, a_1 ** -1, identity, a_1], ] C.modified_define(2, y) assert C.table == [ [1, 2, 3, 1], [2, 0, 0, None], [0, 1, 4, 3], [3, 3, 2, 0], [None, None, None, 2], ] assert C.P == [ [identity, identity, a_1 ** -1, a_0 ** -1], [identity, identity, a_0, None], [identity, identity, identity, identity], [a_1, a_1 ** -1, identity, a_1], [None, None, None, identity], ] C.modified_scan(0, y ** 5, C._grp.identity) assert C.table == [ [1, 2, 3, 1], [2, 0, 0, 4], [0, 1, 4, 3], [3, 3, 2, 0], [None, None, 1, 2], ] assert C.P == [ [identity, identity, a_1 ** -1, a_0 ** -1], [identity, identity, a_0, a_0 * a_1 ** -1], [identity, identity, identity, identity], [a_1, a_1 ** -1, identity, a_1], [None, None, a_1 * a_0 ** -1, identity], ] C.modified_scan(1, (x * y) ** 2, C._grp.identity) assert C.table == [ [1, 2, 3, 1], [2, 0, 0, 4], [0, 1, 4, 3], [3, 3, 2, 0], [4, 4, 1, 2], ] assert C.P == [ [identity, identity, a_1 ** -1, a_0 ** -1], [identity, identity, a_0, a_0 * a_1 ** -1], [identity, identity, identity, identity], [a_1, a_1 ** -1, identity, a_1], [a_0 * a_1 ** -1, a_1 * a_0 ** -1, a_1 * a_0 ** -1, identity], ] # Modified coset enumeration test f = FpGroup(F, [x ** 3, y ** 3, x ** -1 * y ** -1 * x * y]) C = coset_enumeration_r(f, [x]) C_m = modified_coset_enumeration_r(f, [x]) assert C_m.table == C.table
def reidemeister_presentation(fp_grp, H, C=None): """ fp_group: A finitely presented group, an instance of FpGroup H: A subgroup whose presentation is to be found, given as a list of words in generators of `fp_grp` Examples ======== >>> from sympy.combinatorics.free_groups import free_group >>> from sympy.combinatorics.fp_groups import FpGroup, reidemeister_presentation >>> F, x, y = free_group("x, y") Example 5.6 Pg. 177 from [1] >>> f = FpGroup(F, [x**3, y**5, (x*y)**2]) >>> H = [x*y, x**-1*y**-1*x*y*x] >>> reidemeister_presentation(f, H) ((y_1, y_2), (y_1**2, y_2**3, y_2*y_1*y_2*y_1*y_2*y_1)) Example 5.8 Pg. 183 from [1] >>> f = FpGroup(F, [x**3, y**3, (x*y)**3]) >>> H = [x*y, x*y**-1] >>> reidemeister_presentation(f, H) ((x_0, y_0), (x_0**3, y_0**3, x_0*y_0*x_0*y_0*x_0*y_0)) Exercises Q2. Pg 187 from [1] >>> f = FpGroup(F, [x**2*y**2, y**-1*x*y*x**-3]) >>> H = [x] >>> reidemeister_presentation(f, H) ((x_0,), (x_0**4,)) Example 5.9 Pg. 183 from [1] >>> f = FpGroup(F, [x**3*y**-3, (x*y)**3, (x*y**-1)**2]) >>> H = [x] >>> reidemeister_presentation(f, H) ((x_0,), (x_0**6,)) """ if not C: C = coset_enumeration_r(fp_grp, H) C.compress() C.standardize() define_schreier_generators(C) reidemeister_relators(C) prev_gens = [] prev_rels = [] while not set(prev_rels) == set(C._reidemeister_relators): prev_rels = C._reidemeister_relators while not set(prev_gens) == set(C._schreier_generators): prev_gens = C._schreier_generators elimination_technique_1(C) simplify_presentation(C) syms = [g.array_form[0][0] for g in C._schreier_generators] g = free_group(syms)[0] subs = dict(zip(syms, g.generators)) C._schreier_generators = g.generators for j, r in enumerate(C._reidemeister_relators): a = r.array_form rel = g.identity for sym, p in a: rel = rel * subs[sym]**p C._reidemeister_relators[j] = rel C.schreier_generators = tuple(C._schreier_generators) C.reidemeister_relators = tuple(C._reidemeister_relators) return C.schreier_generators, C.reidemeister_relators
def reidemeister_presentation(fp_grp, H, C=None): """ fp_group: A finitely presented group, an instance of FpGroup H: A subgroup whose presentation is to be found, given as a list of words in generators of `fp_grp` Examples ======== >>> from sympy.combinatorics.free_groups import free_group >>> from sympy.combinatorics.fp_groups import FpGroup, reidemeister_presentation >>> F, x, y = free_group("x, y") Example 5.6 Pg. 177 from [1] >>> f = FpGroup(F, [x**3, y**5, (x*y)**2]) >>> H = [x*y, x**-1*y**-1*x*y*x] >>> reidemeister_presentation(f, H) ((y_1, y_2), (y_1**2, y_2**3, y_2*y_1*y_2*y_1*y_2*y_1)) Example 5.8 Pg. 183 from [1] >>> f = FpGroup(F, [x**3, y**3, (x*y)**3]) >>> H = [x*y, x*y**-1] >>> reidemeister_presentation(f, H) ((x_0, y_0), (x_0**3, y_0**3, x_0*y_0*x_0*y_0*x_0*y_0)) Exercises Q2. Pg 187 from [1] >>> f = FpGroup(F, [x**2*y**2, y**-1*x*y*x**-3]) >>> H = [x] >>> reidemeister_presentation(f, H) ((x_0,), (x_0**4,)) Example 5.9 Pg. 183 from [1] >>> f = FpGroup(F, [x**3*y**-3, (x*y)**3, (x*y**-1)**2]) >>> H = [x] >>> reidemeister_presentation(f, H) ((x_0,), (x_0**6,)) """ if not C: C = coset_enumeration_r(fp_grp, H) C.compress(); C.standardize() define_schreier_generators(C) reidemeister_relators(C) prev_gens = [] prev_rels = [] while not set(prev_rels) == set(C._reidemeister_relators): prev_rels = C._reidemeister_relators while not set(prev_gens) == set(C._schreier_generators): prev_gens = C._schreier_generators elimination_technique_1(C) simplify_presentation(C) syms = [g.array_form[0][0] for g in C._schreier_generators] g = free_group(syms)[0] subs = dict(zip(syms,g.generators)) C._schreier_generators = g.generators for j, r in enumerate(C._reidemeister_relators): a = r.array_form rel = g.identity for sym, p in a: rel = rel*subs[sym]**p C._reidemeister_relators[j] = rel C.schreier_generators = tuple(C._schreier_generators) C.reidemeister_relators = tuple(C._reidemeister_relators) return C.schreier_generators, C.reidemeister_relators
def test_low_index_subgroups(): F, x, y = free_group("x, y") # Example 5.10 from [1] Pg. 194 f = FpGroup(F, [x**2, y**3, (x*y)**4]) L = low_index_subgroups(f, 4) t1 = [[[0, 0, 0, 0]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 3, 3]], [[0, 0, 1, 2], [2, 2, 2, 0], [1, 1, 0, 1]], [[1, 1, 0, 0], [0, 0, 1, 1]]] for i in range(len(t1)): assert L[i].table == t1[i] f = FpGroup(F, [x**2, y**3, (x*y)**7]) L = low_index_subgroups(f, 15) t2 = [[[0, 0, 0, 0]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [4, 4, 5, 3], [6, 6, 3, 4], [5, 5, 6, 6]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [5, 5, 3, 4], [4, 4, 6, 6]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [7, 7, 3, 4], [4, 4, 8, 9], [5, 5, 10, 11], [11, 11, 9, 6], [9, 9, 6, 8], [12, 12, 11, 7], [8, 8, 7, 10], [10, 10, 13, 14], [14, 14, 14, 12], [13, 13, 12, 13]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [7, 7, 3, 4], [4, 4, 8, 9], [5, 5, 10, 11], [11, 11, 9, 6], [12, 12, 6, 8], [10, 10, 11, 7], [8, 8, 7, 10], [9, 9, 13, 14], [14, 14, 14, 12], [13, 13, 12, 13]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [7, 7, 3, 4], [4, 4, 8, 9], [5, 5, 10, 11], [11, 11, 9, 6], [12, 12, 6, 8], [13, 13, 11, 7], [8, 8, 7, 10], [9, 9, 12, 12], [10, 10, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 3, 3], [2, 2, 5, 6] , [7, 7, 6, 4], [8, 8, 4, 5], [5, 5, 8, 9], [6, 6, 9, 7], [10, 10, 7, 8], [9, 9, 11, 12], [11, 11, 12, 10], [13, 13, 10, 11], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 3, 3], [2, 2, 5, 6] , [7, 7, 6, 4], [8, 8, 4, 5], [5, 5, 8, 9], [6, 6, 9, 7], [10, 10, 7, 8], [9, 9, 11, 12], [13, 13, 12, 10], [12, 12, 10, 11], [11, 11, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 4, 4] , [7, 7, 6, 3], [8, 8, 3, 5], [5, 5, 8, 9], [6, 6, 9, 7], [10, 10, 7, 8], [9, 9, 11, 12], [13, 13, 12, 10], [12, 12, 10, 11], [11, 11, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [5, 5, 6, 3], [9, 9, 3, 5], [10, 10, 8, 4], [8, 8, 4, 7], [6, 6, 10, 11], [7, 7, 11, 9], [12, 12, 9, 10], [11, 11, 13, 14], [14, 14, 14, 12], [13, 13, 12, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [6, 6, 6, 3], [5, 5, 3, 5], [8, 8, 8, 4], [7, 7, 4, 7]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [9, 9, 6, 3], [6, 6, 3, 5], [10, 10, 8, 4], [11, 11, 4, 7], [5, 5, 10, 12], [7, 7, 12, 9], [8, 8, 11, 11], [13, 13, 9, 10], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [9, 9, 6, 3], [6, 6, 3, 5], [10, 10, 8, 4], [11, 11, 4, 7], [5, 5, 12, 11], [7, 7, 10, 10], [8, 8, 9, 12], [13, 13, 11, 9], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [9, 9, 6, 3], [10, 10, 3, 5], [7, 7, 8, 4], [11, 11, 4, 7], [5, 5, 9, 9], [6, 6, 11, 12], [8, 8, 12, 10], [13, 13, 10, 11], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [9, 9, 6, 3], [10, 10, 3, 5], [7, 7, 8, 4], [11, 11, 4, 7], [5, 5, 12, 11], [6, 6, 10, 10], [8, 8, 9, 12], [13, 13, 11, 9], [12, 12, 13, 13]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8] , [9, 9, 6, 3], [10, 10, 3, 5], [11, 11, 8, 4], [12, 12, 4, 7], [5, 5, 9, 9], [6, 6, 12, 13], [7, 7, 11, 11], [8, 8, 13, 10], [13, 13, 10, 12]], [[1, 1, 0, 0], [0, 0, 2, 3], [4, 4, 3, 1], [5, 5, 1, 2], [2, 2, 4, 4] , [3, 3, 6, 7], [7, 7, 7, 5], [6, 6, 5, 6]]] for i in range(len(t2)): assert L[i].table == t2[i] f = FpGroup(F, [x**2, y**3, (x*y)**7]) L = low_index_subgroups(f, 10, [x]) t3 = [[[0, 0, 0, 0]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [4, 4, 5, 3], [6, 6, 3, 4], [5, 5, 6, 6]], [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 4, 5], [6, 6, 5, 3], [5, 5, 3, 4], [4, 4, 6, 6]], [[0, 0, 1, 2], [3, 3, 2, 0], [4, 4, 0, 1], [1, 1, 5, 6], [2, 2, 7, 8], [6, 6, 6, 3], [5, 5, 3, 5], [8, 8, 8, 4], [7, 7, 4, 7]]] for i in range(len(t3)): assert L[i].table == t3[i]
def test_coset_enumeration(): # this test function contains the combined tests for the two strategies # i.e. HLT and Felsch strategies. # Example 5.1 from [1] F, x, y = free_group("x, y") f = FpGroup(F, [x**3, y**3, x**-1 * y**-1 * x * y]) C_r = coset_enumeration_r(f, [x]) C_r.compress() C_r.standardize() C_c = coset_enumeration_c(f, [x]) C_c.compress() C_c.standardize() table1 = [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1]] assert C_r.table == table1 assert C_c.table == table1 # E₁ from [2] Pg. 474 F, r, s, t = free_group("r, s, t") E1 = FpGroup( F, [t**-1 * r * t * r**-2, r**-1 * s * r * s**-2, s**-1 * t * s * t**-2]) C_r = coset_enumeration_r(E1, []) C_r.compress() C_c = coset_enumeration_c(E1, []) C_c.compress() table2 = [[0, 0, 0, 0, 0, 0]] assert C_r.table == table2 # test for issue #11449 assert C_c.table == table2 # Cox group from [2] Pg. 474 F, a, b = free_group("a, b") Cox = FpGroup(F, [a**6, b**6, (a * b)**2, (a**2 * b**2)**2, (a**3 * b**3)**5]) C_r = coset_enumeration_r(Cox, [a]) C_r.compress() C_r.standardize() C_c = coset_enumeration_c(Cox, [a]) C_c.compress() C_c.standardize() table3 = [[0, 0, 1, 2], [2, 3, 4, 0], [5, 1, 0, 6], [1, 7, 8, 9], [9, 10, 11, 1], [12, 2, 9, 13], [14, 9, 2, 11], [3, 12, 15, 16], [16, 17, 18, 3], [6, 4, 3, 5], [4, 19, 20, 21], [21, 22, 6, 4], [7, 5, 23, 24], [25, 23, 5, 18], [19, 6, 22, 26], [24, 27, 28, 7], [29, 8, 7, 30], [8, 31, 32, 33], [33, 34, 13, 8], [10, 14, 35, 35], [35, 36, 37, 10], [30, 11, 10, 29], [11, 38, 39, 14], [13, 39, 38, 12], [40, 15, 12, 41], [42, 13, 34, 43], [44, 35, 14, 45], [15, 46, 47, 34], [34, 48, 49, 15], [50, 16, 21, 51], [52, 21, 16, 49], [17, 50, 53, 54], [54, 55, 56, 17], [41, 18, 17, 40], [18, 28, 27, 25], [26, 20, 19, 19], [20, 57, 58, 59], [59, 60, 51, 20], [22, 52, 61, 23], [23, 62, 63, 22], [64, 24, 33, 65], [48, 33, 24, 61], [62, 25, 54, 66], [67, 54, 25, 68], [57, 26, 59, 69], [70, 59, 26, 63], [27, 64, 71, 72], [72, 73, 68, 27], [28, 41, 74, 75], [75, 76, 30, 28], [31, 29, 77, 78], [79, 77, 29, 37], [38, 30, 76, 80], [78, 81, 82, 31], [43, 32, 31, 42], [32, 83, 84, 85], [85, 86, 65, 32], [36, 44, 87, 88], [88, 89, 90, 36], [45, 37, 36, 44], [37, 82, 81, 79], [80, 74, 41, 38], [39, 42, 91, 92], [92, 93, 45, 39], [46, 40, 94, 95], [96, 94, 40, 56], [97, 91, 42, 82], [83, 43, 98, 99], [100, 98, 43, 47], [101, 87, 44, 90], [82, 45, 93, 97], [95, 102, 103, 46], [104, 47, 46, 105], [47, 106, 107, 100], [61, 108, 109, 48], [105, 49, 48, 104], [49, 110, 111, 52], [51, 111, 110, 50], [112, 53, 50, 113], [114, 51, 60, 115], [116, 61, 52, 117], [53, 118, 119, 60], [60, 70, 66, 53], [55, 67, 120, 121], [121, 122, 123, 55], [113, 56, 55, 112], [56, 103, 102, 96], [69, 124, 125, 57], [115, 58, 57, 114], [58, 126, 127, 128], [128, 128, 69, 58], [66, 129, 130, 62], [117, 63, 62, 116], [63, 125, 124, 70], [65, 109, 108, 64], [131, 71, 64, 132], [133, 65, 86, 134], [135, 66, 70, 136], [68, 130, 129, 67], [137, 120, 67, 138], [132, 68, 73, 131], [139, 69, 128, 140], [71, 141, 142, 86], [86, 143, 144, 71], [145, 72, 75, 146], [147, 75, 72, 144], [73, 145, 148, 120], [120, 149, 150, 73], [74, 151, 152, 94], [94, 153, 146, 74], [76, 147, 154, 77], [77, 155, 156, 76], [157, 78, 85, 158], [143, 85, 78, 154], [155, 79, 88, 159], [160, 88, 79, 161], [151, 80, 92, 162], [163, 92, 80, 156], [81, 157, 164, 165], [165, 166, 161, 81], [99, 107, 106, 83], [134, 84, 83, 133], [84, 167, 168, 169], [169, 170, 158, 84], [87, 171, 172, 93], [93, 163, 159, 87], [89, 160, 173, 174], [174, 175, 176, 89], [90, 90, 89, 101], [91, 177, 178, 98], [98, 179, 162, 91], [180, 95, 100, 181], [179, 100, 95, 152], [153, 96, 121, 148], [182, 121, 96, 183], [177, 97, 165, 184], [185, 165, 97, 172], [186, 99, 169, 187], [188, 169, 99, 178], [171, 101, 174, 189], [190, 174, 101, 176], [102, 180, 191, 192], [192, 193, 183, 102], [103, 113, 194, 195], [195, 196, 105, 103], [106, 104, 197, 198], [199, 197, 104, 109], [110, 105, 196, 200], [198, 201, 133, 106], [107, 186, 202, 203], [203, 204, 181, 107], [108, 116, 205, 206], [206, 207, 132, 108], [109, 133, 201, 199], [200, 194, 113, 110], [111, 114, 208, 209], [209, 210, 117, 111], [118, 112, 211, 212], [213, 211, 112, 123], [214, 208, 114, 125], [126, 115, 215, 216], [217, 215, 115, 119], [218, 205, 116, 130], [125, 117, 210, 214], [212, 219, 220, 118], [136, 119, 118, 135], [119, 221, 222, 217], [122, 182, 223, 224], [224, 225, 226, 122], [138, 123, 122, 137], [123, 220, 219, 213], [124, 139, 227, 228], [228, 229, 136, 124], [216, 222, 221, 126], [140, 127, 126, 139], [127, 230, 231, 232], [232, 233, 140, 127], [129, 135, 234, 235], [235, 236, 138, 129], [130, 132, 207, 218], [141, 131, 237, 238], [239, 237, 131, 150], [167, 134, 240, 241], [242, 240, 134, 142], [243, 234, 135, 220], [221, 136, 229, 244], [149, 137, 245, 246], [247, 245, 137, 226], [220, 138, 236, 243], [244, 227, 139, 221], [230, 140, 233, 248], [238, 249, 250, 141], [251, 142, 141, 252], [142, 253, 254, 242], [154, 255, 256, 143], [252, 144, 143, 251], [144, 257, 258, 147], [146, 258, 257, 145], [259, 148, 145, 260], [261, 146, 153, 262], [263, 154, 147, 264], [148, 265, 266, 153], [246, 267, 268, 149], [260, 150, 149, 259], [150, 250, 249, 239], [162, 269, 270, 151], [262, 152, 151, 261], [152, 271, 272, 179], [159, 273, 274, 155], [264, 156, 155, 263], [156, 270, 269, 163], [158, 256, 255, 157], [275, 164, 157, 276], [277, 158, 170, 278], [279, 159, 163, 280], [161, 274, 273, 160], [281, 173, 160, 282], [276, 161, 166, 275], [283, 162, 179, 284], [164, 285, 286, 170], [170, 188, 184, 164], [166, 185, 189, 173], [173, 287, 288, 166], [241, 254, 253, 167], [278, 168, 167, 277], [168, 289, 290, 291], [291, 292, 187, 168], [189, 293, 294, 171], [280, 172, 171, 279], [172, 295, 296, 185], [175, 190, 297, 297], [297, 298, 299, 175], [282, 176, 175, 281], [176, 294, 293, 190], [184, 296, 295, 177], [284, 178, 177, 283], [178, 300, 301, 188], [181, 272, 271, 180], [302, 191, 180, 303], [304, 181, 204, 305], [183, 266, 265, 182], [306, 223, 182, 307], [303, 183, 193, 302], [308, 184, 188, 309], [310, 189, 185, 311], [187, 301, 300, 186], [305, 202, 186, 304], [312, 187, 292, 313], [314, 297, 190, 315], [191, 316, 317, 204], [204, 318, 319, 191], [320, 192, 195, 321], [322, 195, 192, 319], [193, 320, 323, 223], [223, 324, 325, 193], [194, 326, 327, 211], [211, 328, 321, 194], [196, 322, 329, 197], [197, 330, 331, 196], [332, 198, 203, 333], [318, 203, 198, 329], [330, 199, 206, 334], [335, 206, 199, 336], [326, 200, 209, 337], [338, 209, 200, 331], [201, 332, 339, 240], [240, 340, 336, 201], [202, 341, 342, 292], [292, 343, 333, 202], [205, 344, 345, 210], [210, 338, 334, 205], [207, 335, 346, 237], [237, 347, 348, 207], [208, 349, 350, 215], [215, 351, 337, 208], [352, 212, 217, 353], [351, 217, 212, 327], [328, 213, 224, 323], [354, 224, 213, 355], [349, 214, 228, 356], [357, 228, 214, 345], [358, 216, 232, 359], [360, 232, 216, 350], [344, 218, 235, 361], [362, 235, 218, 348], [219, 352, 363, 364], [364, 365, 355, 219], [222, 358, 366, 367], [367, 368, 353, 222], [225, 354, 369, 370], [370, 371, 372, 225], [307, 226, 225, 306], [226, 268, 267, 247], [227, 373, 374, 233], [233, 360, 356, 227], [229, 357, 361, 234], [234, 375, 376, 229], [248, 231, 230, 230], [231, 377, 378, 379], [379, 380, 359, 231], [236, 362, 381, 245], [245, 382, 383, 236], [384, 238, 242, 385], [340, 242, 238, 346], [347, 239, 246, 381], [386, 246, 239, 387], [388, 241, 291, 389], [343, 291, 241, 339], [375, 243, 364, 390], [391, 364, 243, 383], [373, 244, 367, 392], [393, 367, 244, 376], [382, 247, 370, 394], [395, 370, 247, 396], [377, 248, 379, 397], [398, 379, 248, 374], [249, 384, 399, 400], [400, 401, 387, 249], [250, 260, 402, 403], [403, 404, 252, 250], [253, 251, 405, 406], [407, 405, 251, 256], [257, 252, 404, 408], [406, 409, 277, 253], [254, 388, 410, 411], [411, 412, 385, 254], [255, 263, 413, 414], [414, 415, 276, 255], [256, 277, 409, 407], [408, 402, 260, 257], [258, 261, 416, 417], [417, 418, 264, 258], [265, 259, 419, 420], [421, 419, 259, 268], [422, 416, 261, 270], [271, 262, 423, 424], [425, 423, 262, 266], [426, 413, 263, 274], [270, 264, 418, 422], [420, 427, 307, 265], [266, 303, 428, 425], [267, 386, 429, 430], [430, 431, 396, 267], [268, 307, 427, 421], [269, 283, 432, 433], [433, 434, 280, 269], [424, 428, 303, 271], [272, 304, 435, 436], [436, 437, 284, 272], [273, 279, 438, 439], [439, 440, 282, 273], [274, 276, 415, 426], [285, 275, 441, 442], [443, 441, 275, 288], [289, 278, 444, 445], [446, 444, 278, 286], [447, 438, 279, 294], [295, 280, 434, 448], [287, 281, 449, 450], [451, 449, 281, 299], [294, 282, 440, 447], [448, 432, 283, 295], [300, 284, 437, 452], [442, 453, 454, 285], [309, 286, 285, 308], [286, 455, 456, 446], [450, 457, 458, 287], [311, 288, 287, 310], [288, 454, 453, 443], [445, 456, 455, 289], [313, 290, 289, 312], [290, 459, 460, 461], [461, 462, 389, 290], [293, 310, 463, 464], [464, 465, 315, 293], [296, 308, 466, 467], [467, 468, 311, 296], [298, 314, 469, 470], [470, 471, 472, 298], [315, 299, 298, 314], [299, 458, 457, 451], [452, 435, 304, 300], [301, 312, 473, 474], [474, 475, 309, 301], [316, 302, 476, 477], [478, 476, 302, 325], [341, 305, 479, 480], [481, 479, 305, 317], [324, 306, 482, 483], [484, 482, 306, 372], [485, 466, 308, 454], [455, 309, 475, 486], [487, 463, 310, 458], [454, 311, 468, 485], [486, 473, 312, 455], [459, 313, 488, 489], [490, 488, 313, 342], [491, 469, 314, 472], [458, 315, 465, 487], [477, 492, 485, 316], [463, 317, 316, 468], [317, 487, 493, 481], [329, 447, 464, 318], [468, 319, 318, 463], [319, 467, 448, 322], [321, 448, 467, 320], [475, 323, 320, 466], [432, 321, 328, 437], [438, 329, 322, 434], [323, 474, 452, 328], [483, 494, 486, 324], [466, 325, 324, 475], [325, 485, 492, 478], [337, 422, 433, 326], [437, 327, 326, 432], [327, 436, 424, 351], [334, 426, 439, 330], [434, 331, 330, 438], [331, 433, 422, 338], [333, 464, 447, 332], [449, 339, 332, 440], [465, 333, 343, 469], [413, 334, 338, 418], [336, 439, 426, 335], [441, 346, 335, 415], [440, 336, 340, 449], [416, 337, 351, 423], [339, 451, 470, 343], [346, 443, 450, 340], [480, 493, 487, 341], [469, 342, 341, 465], [342, 491, 495, 490], [361, 407, 414, 344], [418, 345, 344, 413], [345, 417, 408, 357], [381, 446, 442, 347], [415, 348, 347, 441], [348, 414, 407, 362], [356, 408, 417, 349], [423, 350, 349, 416], [350, 425, 420, 360], [353, 424, 436, 352], [479, 363, 352, 435], [428, 353, 368, 476], [355, 452, 474, 354], [488, 369, 354, 473], [435, 355, 365, 479], [402, 356, 360, 419], [405, 361, 357, 404], [359, 420, 425, 358], [476, 366, 358, 428], [427, 359, 380, 482], [444, 381, 362, 409], [363, 481, 477, 368], [368, 393, 390, 363], [365, 391, 394, 369], [369, 490, 480, 365], [366, 478, 483, 380], [380, 398, 392, 366], [371, 395, 496, 497], [497, 498, 489, 371], [473, 372, 371, 488], [372, 486, 494, 484], [392, 400, 403, 373], [419, 374, 373, 402], [374, 421, 430, 398], [390, 411, 406, 375], [404, 376, 375, 405], [376, 403, 400, 393], [397, 430, 421, 377], [482, 378, 377, 427], [378, 484, 497, 499], [499, 499, 397, 378], [394, 461, 445, 382], [409, 383, 382, 444], [383, 406, 411, 391], [385, 450, 443, 384], [492, 399, 384, 453], [457, 385, 412, 493], [387, 442, 446, 386], [494, 429, 386, 456], [453, 387, 401, 492], [389, 470, 451, 388], [493, 410, 388, 457], [471, 389, 462, 495], [412, 390, 393, 399], [462, 394, 391, 410], [401, 392, 398, 429], [396, 445, 461, 395], [498, 496, 395, 460], [456, 396, 431, 494], [431, 397, 499, 496], [399, 477, 481, 412], [429, 483, 478, 401], [410, 480, 490, 462], [496, 497, 484, 431], [489, 495, 491, 459], [495, 460, 459, 471], [460, 489, 498, 498], [472, 472, 471, 491]] C_r.table == table3 C_c.table == table3 # Group denoted by B₂,₄ from [2] Pg. 474 F, a, b = free_group("a, b") B_2_4 = FpGroup(F, [a**4, b**4, (a*b)**4, (a**-1*b)**4, (a**2*b)**4, \ (a*b**2)**4, (a**2*b**2)**4, (a**-1*b*a*b)**4, (a*b**-1*a*b)**4]) C_r = coset_enumeration_r(B_2_4, [a]) C_c = coset_enumeration_c(B_2_4, [a]) index_r = 0 for i in range(len(C_r.p)): if C_r.p[i] == i: index_r += 1 assert index_r == 1024 index_c = 0 for i in range(len(C_c.p)): if C_c.p[i] == i: index_c += 1 assert index_c == 1024 # trivial Macdonald group G(2,2) from [2] Pg. 480 M = FpGroup(F, [ b**-1 * a**-1 * b * a * b**-1 * a * b * a**-2, a**-1 * b**-1 * a * b * a**-1 * b * a * b**-2 ]) C_r = coset_enumeration_r(M, [a]) C_r.compress() C_r.standardize() C_c = coset_enumeration_c(M, [a]) C_c.compress() C_c.standardize() table4 = [[0, 0, 0, 0]] assert C_r.table == table4 assert C_c.table == table4