Free Groups#
Free groups and finitely presented groups are implemented as a wrapper over the corresponding GAP objects.
A free group can be created by giving the number of generators, or their names. It is also possible to create indexed generators:
sage: G.<x,y,z> = FreeGroup();  G
Free Group on generators {x, y, z}
sage: FreeGroup(3)
Free Group on generators {x0, x1, x2}
sage: FreeGroup('a,b,c')
Free Group on generators {a, b, c}
sage: FreeGroup(3,'t')
Free Group on generators {t0, t1, t2}
The elements can be created by operating with the generators, or by passing a list with the indices of the letters to the group:
EXAMPLES:
sage: G.<a,b,c> = FreeGroup()
sage: a*b*c*a
a*b*c*a
sage: G([1,2,3,1])
a*b*c*a
sage: a * b / c * b^2
a*b*c^-1*b^2
sage: G([1,1,2,-1,-3,2])
a^2*b*a^-1*c^-1*b
You can use call syntax to replace the generators with a set of arbitrary ring elements:
sage: g =  a * b / c * b^2
sage: g(1,2,3)
8/3
sage: M1 = identity_matrix(2)
sage: M2 = matrix([[1,1],[0,1]])
sage: M3 = matrix([[0,1],[1,0]])
sage: g([M1, M2, M3])
[1 3]
[1 2]
AUTHORS:
- Miguel Angel Marco Buzunariz 
- Volker Braun 
- sage.groups.free_group.FreeGroup(n=None, names='x', index_set=None, abelian=False, **kwds)#
- Construct a Free Group. - INPUT: - n– integer or- None(default). The number of generators. If not specified the- namesare counted.
- names– string or list/tuple/iterable of strings (default:- 'x'). The generator names or name prefix.
- index_set– (optional) an index set for the generators; if specified then the optional keyword- abeliancan be used
- abelian– (default:- False) whether to construct a free abelian group or a free group
 - Note - If you want to create a free group, it is currently preferential to use - Groups().free(...)as that does not load GAP.- EXAMPLES: - sage: G.<a,b> = FreeGroup(); G Free Group on generators {a, b} sage: H = FreeGroup('a, b') sage: G is H True sage: FreeGroup(0) Free Group on generators {} - The entry can be either a string with the names of the generators, or the number of generators and the prefix of the names to be given. The default prefix is - 'x'- sage: FreeGroup(3) Free Group on generators {x0, x1, x2} sage: FreeGroup(3, 'g') Free Group on generators {g0, g1, g2} sage: FreeGroup() Free Group on generators {x} - We give two examples using the - index_setoption:- sage: FreeGroup(index_set=ZZ) Free group indexed by Integer Ring sage: FreeGroup(index_set=ZZ, abelian=True) Free abelian group indexed by Integer Ring 
- class sage.groups.free_group.FreeGroupElement(parent, x)#
- Bases: - ElementLibGAP- A wrapper of GAP’s Free Group elements. - INPUT: - x– something that determines the group element. Either a- GapElementor the Tietze list (see- Tietze()) of the group element.
- parent– the parent- FreeGroup.
 - EXAMPLES: - sage: G = FreeGroup('a, b') sage: x = G([1, 2, -1, -2]) sage: x a*b*a^-1*b^-1 sage: y = G([2, 2, 2, 1, -2, -2, -2]) sage: y b^3*a*b^-3 sage: x*y a*b*a^-1*b^2*a*b^-3 sage: y*x b^3*a*b^-3*a*b*a^-1*b^-1 sage: x^(-1) b*a*b^-1*a^-1 sage: x == x*y*y^(-1) True - Tietze()#
- Return the Tietze list of the element. - The Tietze list of a word is a list of integers that represent the letters in the word. A positive integer - OUTPUT: - A tuple of integers. - EXAMPLES: - sage: G.<a,b> = FreeGroup() sage: a.Tietze() (1,) sage: x = a^2 * b^(-3) * a^(-2) sage: x.Tietze() (1, 1, -2, -2, -2, -1, -1) 
 - fox_derivative(gen, im_gens=None, ring=None)#
- Return the Fox derivative of - selfwith respect to a given generator- genof the free group.- Let - and - This map - The most well-known case is when - INPUT: - gen– the generator with respect to which the derivative will be computed. If this is- im_gens(optional) – the images of the generators (given as a list or iterable). This is the list- ring(optional) – the ring in which the elements of the list
 - OUTPUT: - The fox derivative of - selfwith respect to- gen(induced by- im_gens). By default, it is an element of the group algebra with integer coefficients. If- im_gensare provided, the result lives in the algebra where- im_genslive.- EXAMPLES: - sage: G = FreeGroup(5) sage: G.inject_variables() Defining x0, x1, x2, x3, x4 sage: (~x0*x1*x0*x2*~x0).fox_derivative(x0) -x0^-1 + x0^-1*x1 - x0^-1*x1*x0*x2*x0^-1 sage: (~x0*x1*x0*x2*~x0).fox_derivative(x1) x0^-1 sage: (~x0*x1*x0*x2*~x0).fox_derivative(x2) x0^-1*x1*x0 sage: (~x0*x1*x0*x2*~x0).fox_derivative(x3) 0 - If - im_gensis given, the images of the generators are mapped to them:- sage: F = FreeGroup(3) sage: a = F([2,1,3,-1,2]) sage: a.fox_derivative(F([1])) x1 - x1*x0*x2*x0^-1 sage: R.<t> = LaurentPolynomialRing(ZZ) sage: a.fox_derivative(F([1]),[t,t,t]) t - t^2 sage: S.<t1,t2,t3> = LaurentPolynomialRing(ZZ) sage: a.fox_derivative(F([1]),[t1,t2,t3]) -t2*t3 + t2 sage: R.<x,y,z> = QQ[] sage: a.fox_derivative(F([1]),[x,y,z]) -y*z + y sage: a.inverse().fox_derivative(F([1]),[x,y,z]) (z - 1)/(y*z) - The optional parameter - ringdetermines the ring- sage: u = a.fox_derivative(F([1]), [1,2,3], ring=QQ) sage: u -4 sage: parent(u) Rational Field sage: u = a.fox_derivative(F([1]), [1,2,3], ring=R) sage: u -4 sage: parent(u) Multivariate Polynomial Ring in x, y, z over Rational Field 
 - syllables()#
- Return the syllables of the word. - Consider a free group element - OUTPUT: - The tuple of syllables. Each syllable is given as a pair - EXAMPLES: - sage: G.<a,b> = FreeGroup() sage: w = a^2 * b^-1 * a^3 sage: w.syllables() ((a, 2), (b, -1), (a, 3)) 
 
- class sage.groups.free_group.FreeGroup_class(generator_names, libgap_free_group=None)#
- Bases: - UniqueRepresentation,- Group,- ParentLibGAP- A class that wraps GAP’s FreeGroup - See - FreeGroup()for details.- Element#
- alias of - FreeGroupElement
 - abelian_invariants()#
- Return the Abelian invariants of - self.- The Abelian invariants are given by a list of integers - EXAMPLES: - sage: F.<a,b> = FreeGroup() sage: F.abelian_invariants() (0, 0) 
 - quotient(relations, **kwds)#
- Return the quotient of - selfby the normal subgroup generated by the given elements.- This quotient is a finitely presented groups with the same generators as - self, and relations given by the elements of- relations.- INPUT: - relations– A list/tuple/iterable with the elements of the free group.
- further named arguments, that are passed to the constructor of a finitely presented group. 
 - OUTPUT: - A finitely presented group, with generators corresponding to the generators of the free group, and relations corresponding to the elements in - relations.- EXAMPLES: - sage: F.<a,b> = FreeGroup() sage: F.quotient([a*b^2*a, b^3]) Finitely presented group < a, b | a*b^2*a, b^3 > - Division is shorthand for - quotient()- sage: F / [a*b^2*a, b^3] Finitely presented group < a, b | a*b^2*a, b^3 > - Relations are converted to the free group, even if they are not elements of it (if possible) - sage: F1.<a,b,c,d> = FreeGroup() sage: F2.<a,b> = FreeGroup() sage: r = a*b/a sage: r.parent() Free Group on generators {a, b} sage: F1/[r] Finitely presented group < a, b, c, d | a*b*a^-1 > 
 - rank()#
- Return the number of generators of self. - Alias for - ngens().- OUTPUT: - Integer. - EXAMPLES: - sage: G = FreeGroup('a, b'); G Free Group on generators {a, b} sage: G.rank() 2 sage: H = FreeGroup(3, 'x') sage: H Free Group on generators {x0, x1, x2} sage: H.rank() 3 
 
- sage.groups.free_group.is_FreeGroup(x)#
- Test whether - xis a- FreeGroup_class.- INPUT: - x– anything.
 - OUTPUT: - Boolean. - EXAMPLES: - sage: from sage.groups.free_group import is_FreeGroup sage: is_FreeGroup('a string') False sage: is_FreeGroup(FreeGroup(0)) True sage: is_FreeGroup(FreeGroup(index_set=ZZ)) True 
- sage.groups.free_group.wrap_FreeGroup(libgap_free_group)#
- Wrap a LibGAP free group. - This function changes the comparison method of - libgap_free_groupto comparison by Python- id. If you want to put the LibGAP free group into a container (set, dict) then you should understand the implications of- _set_compare_by_id(). To be safe, it is recommended that you just work with the resulting Sage- FreeGroup_class.- INPUT: - libgap_free_group– a LibGAP free group.
 - OUTPUT: - A Sage - FreeGroup_class.- EXAMPLES: - First construct a LibGAP free group: - sage: F = libgap.FreeGroup(['a', 'b']) sage: type(F) <class 'sage.libs.gap.element.GapElement'> - Now wrap it: - sage: from sage.groups.free_group import wrap_FreeGroup sage: wrap_FreeGroup(F) Free Group on generators {a, b}