Spracherkennung für: .g vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
DeclareGlobalFunction("NSM");
ScalarMap := function(F)
# Returns a function that extracts mat[1][1] and returns it as an element in the multiplicative group of the field
local q,C,x,z,Sclfunc,i,mat;
q := Size(F);
C := CyclicGroup(q-1);
if q > 2 then
x := C.1;
else
x:= Identity(C);
fi;
z := PrimitiveRoot(F);
Sclfunc := function(mat)
if not IsScalar(mat) then return false; fi;
i := LogFFE(mat[1][1],z);
return x^i;
end;
return Sclfunc;
end;
AlmostSimpleMaps := function(G, ri)
# Construct a sequence of maps for the almost simple group G
local L,name,H,d,F,z,G1,H1,C,alpha,I,beta,q,gcd,k1,z1,k2,
k,Scls,SclMap,gamma,divs,i,y,ZH,IPc,ItoPc,alpha1,SclsPC,e1,e2,f1,f2, cp1;
if IsBound(ri.ASName) then
name:=ri.ASName;
else
L := IdentifySimple(G);
if L[1]=false then return false; fi;
if not IsString(L[2]) then name := L[2][1];
else
name := L[2];
fi;
fi;
# Compute the stable derivative
H := StableDerivative(G);
# Reduce the number of generators of H
# Take 2 none similar elts and spin up with some conjugates -
e1 := PseudoRandom(H);
cp1:= CharacteristicPolynomial(e1);
repeat
e2 := PseudoRandom(H);
until cp1 <> CharacteristicPolynomial(e2);
H := GroupWithGenerators([e1,e1^PseudoRandom(G),e1^PseudoRandom(G),e2,e2^PseudoRandom(G),e2^PseudoRandom(G)]);
# Throw in all scalars
d := DimensionOfMatrixGroup(G);
F := FieldOfMatrixGroup(G);
z := PrimitiveElement(F) * One(G);
L := ShallowCopy(GeneratorsOfGroup(G));
Add(L,z);
G1 := GroupWithGenerators(L);
L := ShallowCopy(GeneratorsOfGroup(H));
Add(L,z);
H1 := GroupWithGenerators(L);
# Construct the cosets of H1 in G1 using projective order
C := ConstructCosets(G1, H1, true);
alpha := GroupHomomorphismByFunction(G,SymmetricGroup(Size(C)),g -> ImageInQuotient(G1,H1,C,g,true));
I := Image(alpha);
ItoPc := IsomorphismPcGroup(I);
IPc := Image(ItoPc);
alpha1 := GroupHomomorphismByFunction(G,IPc,g->ImageElm(ItoPc,ImageElm(alpha,g)));
# Find the centre of H
q := Size(F);
gcd := GcdInt(q-1,d);
k1 := (q-1)/gcd;
z1 := z^k1;
divs := DivisorsInt(gcd);
for i in divs do
if ElementInNormalSubgroup(H1,H,z1^i,false)=true then y:=z1^i; k2:=i; break; fi;
od;
k := k1*k2;
ZH := GroupWithGenerators([z^k]);
# Construct ismorphism (modulo scalars) from H1 -> H
beta := GroupHomomorphismByFunction(H1,H,g->ImageInPerfectGroup(H1,H,g,z,k));
Scls := GroupWithGenerators([z]);
SclMap := ScalarMap(F);
SclsPC := GroupWithGenerators([SclMap(z)]);
gamma := GroupHomomorphismByFunction(Scls,SclsPC,g->SclMap(g));
# Pass all the information to the record
ri!.Maps := [alpha1,beta,gamma];
ri!.MapImages := [IPc,H,SclsPC];
ri!.Class := "AlmostSimple";
ri!.COB := One(G);
ri!.Names := [Size(I),[name,1],q-1];
ri!.Scalars := [0,ZH,0];
ri!.TFlevels := [2,3,5];
return true;
end;
ReducibleCOB := function(M,F,B)
# Constructs the matrix that conjugates G into a form that exhibits the composition series of the module M
local mat,i,V,W,L,v;
mat := [];
for i in [1..Size(B[2])] do
Add(mat,B[2][i]);
od;
for i in [2..(Size(B)-1)] do
V := VectorSpace(F,B[i]);
W := VectorSpace(F,B[i+1]);
for v in Basis(W) do
if (v in V)=false then
L := List(Basis(V));
Add(L,v);
V := VectorSpace(F,L);
Add(mat,v);
fi;
if Size(mat)=Dimension(W) then break; fi;
od;
od;
return mat^-1;
end;
ExtractBlockMap := function(g,t,d,c)
# extracts the block of g^t from (d,d) -> (d+c,d+c)
local x,m;
x := g^t;
m := x{[d..(d+c-1)]}{[d..(d+c-1)]};
return m;
end;
ReducibleMaps := function(G,ri)
# Computes a sequence of maps for a reducible group G
local gens,F,M,isirred,B,dims,t,psi,c,l,mapdata,i,j,A,Ari,x,g,
D,injs,maptoD,ims;
gens:=GeneratorsOfGroup(G);
F:=FieldOfMatrixGroup(G);
M := GModuleByMats(gens,F);
isirred := MTX.IsIrreducible(M);
if isirred then return false; fi;
#Construct change of basis matrix
B := MTX.BasesCompositionSeries(M);
dims := List(B,x->Size(x));
t := ReducibleCOB(M,F,B);
ri!.Class := "Reducible";
ri!.COB := t;
# Construct maps onto blocks
psi := List([1..(Size(dims)-1)],i->GroupHomomorphismByFunction(G,GL(dims[i+1]-dims[i],F),g -> ExtractBlockMap(g,t,dims[i]+1,dims[i+1]-dims[i])));
# Sort psi by dimension but remember the origional ordering
c := List([1..(Size(dims)-1)],i->dims[i+1]-dims[i]);
psi := Permuted(psi,Sortex(c));
# recurse in images
A := List([1..Size(c)],i->Image(psi[i]));
Ari := List([1..Size(c)],i->NSM(A[i]));
# Glue the maps together
l := List([1..Size(c)],x->1);
mapdata := [];
for i in [1..4] do
for j in [1..Size(c)] do
while Size(Ari[j].Maps) >= l[j] and Ari[j].TFlevels[l[j]]=i do
Add(mapdata, [j,l[j]]);
l[j]:=l[j]+1;
od;
od;
od;
ri!.Maps := List(mapdata,x->GroupHomomorphismByFunction(G,Ari[x[1]].MapImages[x[2]],g->ImageElm(Ari[x[1]].Maps[x[2]],ImageElm(psi[x[1]],g))));
# This should work but it doesn't!
# ri!.Maps := List(mapdata,x->psi[x[1]]*Ari[x[1]].Maps[x[2]]);
ri!.Names := List(mapdata,x->Ari[x[1]].Names[x[2]]);
ri!.TFlevels := List(mapdata,x->Ari[x[1]].TFlevels[x[2]]);
ri!.Scalars := List(mapdata,x->Ari[x[1]].Scalars[x[2]]);
ri!.MapImages := List(mapdata,x->Ari[x[1]].MapImages[x[2]]);
# Do last map containing all scalars in the domain
D := DirectProduct(List([1..Size(c)],i->Ari[i].MapImages[l[i]]));
injs := List([1..Size(c)],i->Embedding(D,i));
maptoD := function(g)
ims := List([1..Size(c)],i->ImageElm(injs[i],ImageElm(Ari[i].Maps[l[i]],ImageElm(psi[i],g))));
return Product(ims);
end;
Add(ri.Maps,GroupHomomorphismByFunction(G,D,g->maptoD(g)));
Add(ri.Scalars,0);
Add(ri.TFlevels,5);
Add(ri.MapImages,D);
Add(ri.Names,Product(List([1..Size(c)],i->Ari[i].Names[l[i]])));
return true;
end;
UnipotentMaps:=function(G,ri)
# Is G unipotent?
local F,gens,M,f,CompFacs,x,B,t;
F := FieldOfMatrixGroup(G);
gens := GeneratorsOfGroup(G);
M := GModuleByMats (gens,F);
CompFacs := MTX.CompositionFactors(M);
for f in CompFacs do
if f.dimension > 1 then return false; fi;
if not First(f.generators,x-> not x=One(GL(1,F)))=fail then return false; fi;
od;
B := MTX.BasesCompositionSeries(M);
t := ReducibleCOB(M,F,B);
ri!.Class := "Unipotent";
ri!.COB := t;
ri!.Maps := [];
ri!.Names := [];
ri!.Scalars := [];
ri!.TFlevels := [];
ri!.MapImages := [];
return true;
end;
IsScalarMatrix := function(x)
# Is x a scalar matrix?
local d,i;
if not IsDiagonalMat(x) then return false; fi;
d := Size(x[1]);
for i in [2..d] do
if x[i][i] <> x[1][1] then return false; fi;
od;
return true;
end;
IsScalarGroup := function(G)
# Is G a group of scalars?
local g;
for g in GeneratorsOfGroup(G) do
if not IsScalarMatrix(g) then return false; fi;
od;
return true;
end;
ScalarGroupMaps := function(G,ri)
local F,z,gamma,I;
if not IsScalarGroup(G) then return false; fi;
F := FieldOfMatrixGroup(G);
z := PrimitiveElement(F)*One(G);
gamma := ScalarMap(F);
I := GroupWithGenerators([gamma(z)]);
ri!.Maps := [GroupHomomorphismByFunction(G,I,gamma)];
ri!.MapImages := [I];
ri!.Names := [Size(I)];
ri!.Scalars := [0];
ri!.TFlevels := [5];
ri!.Class := "Scalars";
return true;
end;
# Give a list of non-(quasi)simple classical groups
IsNonSimpleClassical := function(name)
local v1,v2,v3,type,n,q;
v1 := SplitString(name,"_");
type := v1[1];
v2 := SplitString(v1[2],"(");
n := Int(v2[1]);
v3 := SplitString(v2[2],")");
q := Int(v3[1]);
if (type="L" and n=2 and q=2) or (type="L" and n=2 and q=3) or (type="U" and n=3 and q=2) or (type="S" and n=4 and q=2) or (type="O" and n=3 and q=3) or (type="O" and n=3 and q=2) or (type="O" and n=5 and q=2) or (type="O^+" and n=4) then return true;
fi;
return false;
end;
ClassicalNametoStandardName := function(G,name)
local n,q,stdname;
n := DimensionOfMatrixGroup(G);
q := Size(FieldOfMatrixGroup(G));
if name="linear" then
stdname:=Concatenation("L_",String(n),"(",String(q),")");
elif name="symplectic" then
stdname:=Concatenation("S_",String(n),"(",String(q),")");
elif name="orthogonalcircle" then
stdname:=Concatenation("O_",String(n),"(",String(q),")");
elif name="orthogonalplus" then
stdname:=Concatenation("O^+_",String(n),"(",String(q),")");
elif name="orthogonalminus" then
stdname:=Concatenation("O^- _",String(n),"(",String(q),")");
elif name="unitary" then
stdname:=Concatenation("U^- _",String(n),"(",String(Sqrt(q)),")");
else
Error("Error in Classical Names");
fi;
return stdname;
end;
IsGroupClassical := function(G,classicalrec)
# Looks in the classicalrec for what I want!
if classicalrec.isSLContained=true then
return ClassicalNametoStandardName(G,"linear");
elif classicalrec.isSpContained=true then
return ClassicalNametoStandardName(G,"symplectic");
elif classicalrec.isSUContained=true then
return ClassicalNametoStandardName(G,"unitary");
elif classicalrec.isSOContained=true then
return ClassicalNametoStandardName(G,classicalrec.ClassicalForms[1]);
else
return false;
fi;
end;
LowIndexMaps := function(G,ri)
# Computes a sequence of maps for G when G has a small homomorphic image
local F,rho,P,rhoinv,Pri,kgens,kims,s1gens,G1,G1toA,A,Ari,m,e,i,I,D,injs
,homfunc,alpha,ims,hom,_,maxnmrblks,x;
ri!.Class := "LowIndex";
F := FieldOfMatrixGroup(G);
rho := ri.Firsthom;
P := Image(rho);
Pri := rec( Group:=P );
# recurse in P
_:=PermGrpMaps(P,Pri);
rhoinv := GroupHomomorphismByImagesNC(P,G,GeneratorsOfGroup(P),GeneratorsOfGroup(G));
# Find some generators of the kernel
kgens := List([1..15],i->PseudoRandom(G));
kims := List(kgens,x->ImageElm(rho,x));
kgens := List([1..15],i->kgens[i]*ImageElm(rhoinv,kims[i])^-1);
kgens := FastNormalClosure(Grp(ri),kgens,3);
# Compute the stabilizer of 1 in P
s1gens := List(GeneratorsOfGroup(Stabiliser(P,1)),x->ImageElm(rhoinv,x));
G1 := GroupWithGenerators(Concatenation(kgens,s1gens));
# Extract A
G1toA := GroupHomomorphismByFunction(G1,GL(ri.blockdim,F),g->ImageElm(ri.ActionOnFirstSubspace,g));
A := Image(G1toA);
# recurse in A
Ari := NSM(A);
m := NrMovedPoints(P);
maxnmrblks := Minimum(QuotientRemainder(DimensionOfMatrixGroup(G),2)[1],m);
e := List([1..m],i-> ImageElm(rhoinv,RepresentativeAction(P,i,1)));
# Glue together
ri!.MapImages := Concatenation(Pri.MapImages, List([1..Size(Ari.Maps)],i->
DirectProduct(List([1..m],j->Ari.MapImages[i]))));
ri!.Maps := Concatenation(
List([1..Size(Pri!.Maps)],i->GroupHomomorphismByFunction(G,ri.MapImages[i],g->ImageElm(Pri!.Maps[i],ImageElm(rho,g)))),
List([1..Size(Ari.Maps)],i->
GroupHomomorphismByFunction(G,ri!.MapImages[Length(Pri.MapImages)+i],
function(g)
local D,injs,ims;
D := ri!.MapImages[Length(Pri.MapImages)+i];
injs := List([1..m],j->Embedding(D,j));
ims := List([1..m],j->ImageElm(Ari.Maps[i],ImageElm(G1toA,g^e[j])));
return Product(List([1..m],j->ImageElm(injs[j],ims[j])));
end)));
ri!.Scalars := Concatenation(Pri.Scalars,Ari.Scalars);
ri!.Names := Pri.Names;
ri!.TFlevels := List([1..Size(Pri.Maps)],i->1);
ri!.Scalars := Pri.Scalars;
for i in [1..Size(Ari.Maps)] do
Add(ri!.Scalars,Ari.Scalars[i]);
Add(ri!.TFlevels,Ari.TFlevels[i]);
if IsInt(Ari.Names[i]) then
Add(ri!.Names,(Ari.Names[i])^maxnmrblks);
else
Add(ri!.Names,[Ari.Names[i][1],maxnmrblks*Ari.Names[i][2]]);
fi;
od;
return true;
end;
MaptoEAGroup := function(r,q,A,list,g)
# Function used for C6 groups
# Works for normalisers of extraspecial groups and of 2-groups of symplectic type
# Map from EZ_G to E/Z_E
local z,x,j,i,c;
z := Z(q)^((q-1)/r);
x := GeneratorsOfGroup(A);
j := [];
for i in [1..Size(x)] do
c := Comm(g,list[i]);
# c=z^j[i] for some j[i]
if not IsScalar(c) then return false; fi;
j[i] := LogFFE(c[1][1],z);
od;
return Product(List([1..Size(x)],i->x[i]^j[i]));
end;
C6Maps := function (G, ri, re)
# Computes a sequence of maps for a C6 group G
# re is the record from RECOG.New2RecogniseC6(G)
local hom,H,r,n,q,data,Hri,list,A,homtoEA,z,Scls,SclMap,
SclsPC,gamma,F,x;
# 1st get the map into the symplectic group
hom := GroupHomByFuncWithData(G,GroupWithGenerators(re.igens),
RECOG.HomFuncrewriteones,
rec(r := re.r,n := re.n,q := re.q,data := re.basis.basis));
H := Image(hom);
# recurse in H
Hri :=NSM(H);
# Can't make this construction work!!
# ri!.Maps := List(Hri!.Maps,x->hom*x);
ri!.Maps := List([1..Size(Hri!.Maps)],i->GroupHomomorphismByFunction(G,Hri!.MapImages[i],g->ImageElm(Hri!.Maps[i],ImageElm(hom,g))));
ri!.MapImages := Hri!.MapImages;
ri!.Scalars := Hri!.Scalars;
ri!.Names := Hri!.Names;
ri!.Class := "C6";
ri!.TFlevels := Hri!.TFlevels;
#Scalars of H do not correspond to scalars of G
ri.TFlevels[Size(ri.TFlevels)] := 4;
# map onto Elementary Abelian group
list := re.basis.basis.sympl;
A := ElementaryAbelianGroup(re.r^Size(list));
homtoEA := GroupHomomorphismByFunction(G,A,g->MaptoEAGroup(re.r,re.q,A,list,g));
Add(ri.Maps,homtoEA);
Add(ri.Scalars,0);
Add(ri.TFlevels,4);
Add(ri.MapImages,A);
Add(ri.Names,Size(A));
# Now the scalar map
F := FieldOfMatrixGroup(G);
z := PrimitiveElement(F)*One(G);
Scls := GroupWithGenerators([z]);
SclMap := ScalarMap(F);
SclsPC := GroupWithGenerators([SclMap(z)]);
gamma := GroupHomomorphismByFunction(Scls,SclsPC,g->SclMap(g));
Add(ri.Maps,gamma);
Add(ri.Scalars,0);
Add(ri.TFlevels,5);
Add(ri.MapImages,SclsPC);
Add(ri.Names,Size(F)-1);
return true;
end;
TensorMaps := function(G,ri)
# Trys to find maps in the tensor case
local d,F,N,r,conjgensG,gens1,gens2,list,z,A,GtoA,c,l,
mapdata,i,j,D,injs,maptoD,ims,Ari,g,c1;
d := DimensionOfMatrixGroup(G);
if IsPrime(d) then
return false;
fi;
F := FieldOfMatrixGroup(G);
# Now assume a tensor factorization exists:
N := RECOG.FindTensorKernel(G,true);
r := RECOG.FindTensorDecomposition(G,N);
if r = fail then
return fail;
fi;
# Construct the two tensor factors
conjgensG := List(GeneratorsOfGroup(G),x->r.basis * x * r.basisi);
gens1 := [];
gens2 := [];
for g in conjgensG do
list:=RECOG.IsKroneckerProduct(g,r.blocksize);
if list[1]=false then return fail; fi;
Add(gens1,ShallowCopy(list[2])); Add(gens2,ShallowCopy(list[3]));
od;
z := PrimitiveElement(F);
A := []; GtoA := [];
A[1] := GroupWithGenerators(Concatenation(gens1,[z*One(GL(Length(gens1[1]),F))]));
GtoA[1] := GroupHomomorphismByFunction(G,A[1],g->RECOG.IsKroneckerProduct(r.basis * g * r.basisi,r.blocksize)[2]);
A[2] := GroupWithGenerators(Concatenation(gens2,[z*One(GL(Length(gens2[1]),F))]));
GtoA[2] := GroupHomomorphismByFunction(G,A[2],g->RECOG.IsKroneckerProduct(r.basis * g * r.basisi,r.blocksize)[3]);
# Order by increasing dimension
c := List([1..2],i->DimensionOfMatrixGroup(A[i]));
c1 := StructuralCopy(c);
A := Permuted(A,Sortex(c));
GtoA := Permuted(GtoA,Sortex(c1));
# Recurse
Ari := List(A,x->NSM(x));
# Glue the maps together
l := List([1..2],x->1);
mapdata := [];
for i in [1..4] do
for j in [1..2] do
while Size(Ari[j].Maps) >= l[j] and Ari[j].TFlevels[l[j]]=i do
Add(mapdata, [j,l[j]]);
l[j]:=l[j]+1;
od;
od;
od;
ri!.Maps := List(mapdata,x->GroupHomomorphismByFunction(G,Ari[x[1]].MapImages[x[2]],g->ImageElm(Ari[x[1]].Maps[x[2]],ImageElm(GtoA[x[1]],g))));
# ri!.Maps := List(mapdata,x->GtoA(x[1])*Ari[x[1]].Maps[x[2]]);
ri!.Names := List(mapdata,x->Ari[x[1]].Names[x[2]]);
ri!.TFlevels := List(mapdata,x->Ari[x[1]].TFlevels[x[2]]);
ri!.Scalars := List(mapdata,x->Ari[x[1]].Scalars[x[2]]);
ri!.MapImages := List(mapdata,x->Ari[x[1]].MapImages[x[2]]);
# Do last map containing all scalars in the domain
D := DirectProduct(List([1..Size(c)],i->Ari[i].MapImages[l[i]]));
injs := List([1..Size(c)],i->Embedding(D,i));
maptoD := function(g)
ims := List([1..Size(c)],i->ImageElm(injs[i],ImageElm(Ari[i].Maps[l[i]],ImageElm(GtoA[i],g))));
return Product(ims);
end;
Add(ri.Maps,GroupHomomorphismByFunction(G,D,g->maptoD(g)));
Add(ri.Scalars,0);
Add(ri.TFlevels,5);
Add(ri.MapImages,D);
Add(ri.Names,Product(List([1..Size(c)],i->Ari[i].Names[l[i]])));
return true;
end;
#this is the main worker function for the first stage of constructing the tree, it
#computes a sequence of maps for a normal series of G
InstallGlobalFunction(NSM,
function(G)
# the return value is a record, containing some of the following fields:
# Group - the input group
# Class - the first Aschbacher class that G was found to lie in
# COB - if G is reducible, a change of basis matrix that displays G in block lower triangular
# form
# Maps - the list of maps
# Names - list of group names of composition factors
# TFLevels - no idea.
# Scalars - a list of scalar matrices at various levels of the decomposition. haven't yet
# fully understood this.
# MapImages - a list of groups that are the images of the maps
# Firsthom - the homomorphism from G to mapimages[1] created by lowindex or C6 routines
# Blockdim - returned by low index, gives dimension of subspace being permuted
# maybe a few more fields.
local ri,F,classicalrec,name,flag,C6rec,subdim,subtemp,
sub,subbasis,LowIndexri,test;
# Initialise the record
ri := rec();
ri!.Group := G;
F := FieldOfMatrixGroup(G);
# Go through the classes in turn
flag := ScalarGroupMaps(G,ri);
if flag=true then return ri; fi;
Info(ChiefTreeInfo, 2, "testing for reducibility");
if UnipotentMaps(G,ri)=true then return ri; fi;
if ReducibleMaps(G,ri)=true then return ri; fi;
Info(ChiefTreeInfo, 2, "irreducible");
# Is G a C8 group - i.e. Is G a classical group
Info(ChiefTreeInfo, 2, "testing for classical group");
classicalrec := RecogniseClassical(G);
name := IsGroupClassical(G,classicalrec);
if name <> false and not IsNonSimpleClassical(name) then
# We have a classical group in its natural representation
# What is it's standard name?
ri!.ASName:=name;
flag:=AlmostSimpleMaps(G,ri);
return ri;
fi;
Info(ChiefTreeInfo, 2, "not a classical group");
# Now C6 - may recognise a C6 group or find a block system
Info(ChiefTreeInfo, 2, "Looking for C6 or a block system");
C6rec := RECOG.New2RecogniseC6(G);
if not (C6rec=fail or C6rec=false) then
#second condition added 3/10/06 by CMRD as was crashing when igens was trivial.
if C6rec.basis.basis = rec() and not GroupWithGenerators(C6rec.igens) = Group(()) then
# Have found a block system, G imprimitive - deal with using same #ideas as low index
ri!.Firsthom := GroupHomByFuncWithData(G,GroupWithGenerators(C6rec.igens),
RECOG.HomFuncActionOnBlocks,
rec(r := C6rec.r,n := C6rec.n,q := C6rec.q,blks := C6rec.basis.blocks));
# Get the maps that extract the action on the first subspaces
subdim := DimensionOfMatrixGroup(G) / C6rec.basis.blocks.ell;
subtemp := List([1..subdim],j->C6rec.basis.blocks.blocks[j]);
sub := VectorSpace(F,subtemp);
subbasis := Basis(sub);
ri!.blockdim := subdim;
ri!.ActionOnFirstSubspace := GroupHomomorphismByFunction(G,GL(subdim,F),g->MyActionOnSubspace(StructuralCopy(subbasis),g));
#bug here.
flag := LowIndexMaps(G,ri);
if flag=true then return ri; fi;
elif not C6rec.basis.basis = rec() then
# G normalises an extra special group or 2-group of symplectic type
flag := C6Maps(G, ri, C6rec);
if flag=true then return ri; fi;
fi;
fi;
Info(ChiefTreeInfo, 2, "Failed to find C6 or a block system");
# Now trying LowIndex
Info(ChiefTreeInfo, 2, "Trying the low index routine");
LowIndexri := RECOG.SmallHomomorphicImageMatrixGroup(G);
if LowIndexri <> false and LowIndexri <> fail then
# Similar to imprimitive case
Info(ChiefTreeInfo, 3, "Small homomorphic image matrix group worked");
ri!.Firsthom := LowIndexri[1].hom;
subdim := Size(LowIndexri[1].orb[1]);
sub := VectorSpace(F,LowIndexri[1].orb[1]);
subbasis := Basis(sub);
ri!.blockdim := subdim;
ri!.ActionOnFirstSubspace := GroupHomomorphismByFunction(G,GL(subdim,F),g->MyActionOnSubspace(StructuralCopy(subbasis),g));
flag := LowIndexMaps(G,ri);
if flag=true then return ri; fi;
fi;
Info(ChiefTreeInfo, 2, "Low index found nothing");
# Is the group tensor?
Info(ChiefTreeInfo, 2, "Testing for a tensor product");
flag := TensorMaps(G,ri);
if flag=true then return ri; fi;
Info(ChiefTreeInfo, 2, "Failed to find a tensor product");
# Group is probably now almost simple
Info(ChiefTreeInfo, 2, "Testing AlmostSimple");
flag := AlmostSimpleMaps(G,ri);
if flag then return ri; fi;
Error("Failed to find any maps");
end
);
#