// Magma Functions related to the article // // Hyperbolic generalized triangle groups, property (T) and finite simple quotients // by Pierre-Emmanuel Caprace, Marston Conder, Marek Kaluba, Stefan Witzel // // The functions and procedures in this file were written by Pierre-Emmanuel Caprace and Stefan Witzel // // The file is working magma code except for the two lines definint hyp_words_a and hyp_words_c that need to be replaced using hyperbolic_words.py // It does not contain (all) the code that was used to create the tables but it is suited to reconstruct the tables. SetColumns(0); SetAutoColumns(false); SetVerbose("KBMAG",1); max_quotient_order:=5*10^7; // Procedure testing whether a trivalent generalized triangle group of half girth type (3,3,3) ("type A") or half girth type (2,4,4) ("type C") contains a copy of Z^2 generated by short elements. // // The arguments are an automatic group representing a generalized triangle group and the list hyp_words_a or hyp_words_c depening on type (these lists are the only part specific to trivalent triangle groups). // // The prints generators of a copy of Z^2 f one is found (so the group is not hyperbolic). If none is found the group may or may not be hyperbolic. find_flat := procedure(GA, ~hyp_words) printf "Commuting pair: "; for s in [1..#hyp_words] do for i in [1..s] do for x in hyp_words[i] do for y in hyp_words[i] do // Do x and y commute? if (x, y) ne GA!1 then continue; end if; // If so, do they span a cyclic group? num := GreatestCommonDivisor(#x,#y); ex := Round(#y/num); ey := Round(#x/num); if x^ex eq y^ey or x^ex eq y^(-ey) then continue; end if; // If not they span a copy of Z^2 printf "%o, %o;\t", x, y; return; end for; end for; end for; end for; printf "\n"; end procedure; // Auxiliary function determining the name of a simple quotient identify := function(Qs) succ, res := SimpleGroupName(Image(Qs[1])); if succ then return [*res,Order(Image(Qs[1])), #Qs*]; else return [* [*<0,0,0>*], Order(Image(Qs[1])),#Qs*]; end if; end function; // Procedure collecting information around the hyperbolicity of a generalized triangle group of half girth type (3,3,3) (type A) or (2,4,4) (type C). // // Arguments are a generalized triangle group (as a finitely presented group) and "A" or "C" describing the type. // // It will first try to find an automatic structure and prints whether it has found one (this should never fail). // Based on the automatic struture, it tries to prove the group hyperbolic and prints whether it manged. // If the group could not be verified to be hyperbolic, the procedure tries to find a copy of Z^2 and print, whether it has found one. // // Of course, if a group is expected to contain Z^2, it is reasonable to call find_flat before calling IsHyperbolic. hyperbolic := procedure(G, type) isa, GA := IsAutomaticGroup(G); printf "automatic: %o\n", isa; if not isa then return; end if; ish, GH := IsHyperbolic(GA: MaxTries := 20); printf "hyperbolic: %o\n", ish; if ish then return; end if; a := Generators(GA)[1]; b := Generators(GA)[2]; c := Generators(GA)[3]; if type eq "A" then hyp_words_a := [ False ]; find_flat(GA, ~hyp_words_a); elif type eq "C" then hyp_words_c := [ False ]; find_flat(GA, ~hyp_words_c); end if; end procedure; // Procedure collecting information abound finite simple quotients of a finitely presented group // // Arguments are a finitely presented group and a bound on the order of quotients (such as max_quotient_order) // // Prints the abelianization, the L2 quotients, and the finite simple quotients that are not L2 quotients up to the given order. quotients := procedure(G,n) Q, mor := AbelianQuotient(G);; printf "rk(H_1): %o\n", #Generators(AbelianQuotient(G)); printf "l2-quotients: %o\n", L2Quotients(G); printf "quotients: %o, %o\n", [identify(Qs) : Qs in SimpleQuotients(G,n:Family:="notPSL2",Limit:=0)], n; end procedure; // Function testing whether a generalized triangle group given in triangular presentation is virtually torsion free (VTF) // // Returns "true" if group is certified to be virtually torsion-free. The outpue "false" is inconclusive. // // The input is a quadruple consisting of the group presentation, followed by the triple of the orders of the vertex links, respectively corresponding to , , VTF:=function(g, n1, n2, n3) o1:=n1*3/2; // Order group vx group generated by a, b o2:=n2*3/2; // Order group vx group generated by b, c o3:=n3*3/2; // Order group vx group generated by c, a // Test whether vertex groups inject in simple quotients t:=false; quot:=SimpleQuotientProcess(g, 6, 10^3, 1, 5*10^7:Limit:=1); while not t and not IsEmptySimpleQuotientProcess(quot) do f:=SimpleEpimorphisms(quot)[1]; Im:=Parent(f(g.1)); o_im_1:=#sub; o_im_2:=#sub; o_im_3:=#sub; t:=o1 eq o_im_1 and o2 eq o_im_2 and o3 eq o_im_3; NextSimpleQuotient(~quot); end while; return t; end function;