############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Bettina Eick. ## ## Copyright of GAP belongs to its developers, whose names are too numerous ## to list here. Please refer to the COPYRIGHT file for details. ## ## SPDX-License-Identifier: GPL-2.0-or-later ## ## This file contains some functions to convert a pc group into an ## fp group and vice versa. ##
############################################################################# ## #F PcGroupFpGroup( F ) #F PcGroupFpGroupNC( F ) ##
InstallGlobalFunction( PcGroupFpGroup, function( F )
return PolycyclicFactorGroup(
FreeGroupOfFpGroup( F ),
RelatorsOfFpGroup( F ) ); end );
InstallGlobalFunction( PcGroupFpGroupNC, function( F )
return PolycyclicFactorGroupNC(
FreeGroupOfFpGroup( F ),
RelatorsOfFpGroup( F ) ); end );
############################################################################# ## #F IsomorphismFpGroupByPcgs( pcgs, str ) ##
InstallGlobalFunction( IsomorphismFpGroupByPcgs, function( pcgs, str )
local n, F, gens, rels, i, pis, exp, t, h, rel, comm, j, H, phi;
n:=Length(pcgs); if n=0then
phi:=GroupHomomorphismByImagesNC(GroupOfPcgs(pcgs),
TRIVIAL_FP_GROUP,[],[]);
SetIsBijective( phi, true );
return phi; fi;
F := FreeGroup( n, str );
gens := GeneratorsOfGroup( F );
pis := RelativeOrders( pcgs );
rels := [ ]; for i in [1..n] do
# the power
exp := ExponentsOfRelativePower( pcgs, i ){[i+1..n]};
t := One( F ); for h in [i+1..n] do
t := t * gens[h]^exp[h-i];
od;
rel := gens[i]^pis[i] / t;
Add( rels, rel );
# the commutators for j in [i+1..n] do
comm := Comm( pcgs[j], pcgs[i] );
exp := ExponentsOfPcElement( pcgs, comm ){[i+1..n]};
t := One( F ); for h in [i+1..n] do
t := t * gens[h]^exp[h-i];
od;
rel := Comm( gens[j], gens[i] ) / t;
Add( rels, rel );
od;
od;
H := F / rels;
SetSize(H,Product(RelativeOrders(pcgs)));
phi :=
GroupHomomorphismByImagesNC( GroupOfPcgs(pcgs), H, AsList( pcgs ),
GeneratorsOfGroup( H ) );
############################################################################# ## #O IsomorphismFpGroup( G ) ##
InstallOtherMethod( IsomorphismFpGroup, "pc groups",
true, [IsGroup and CanEasilyComputePcgs,IsString], 0, function( G,nam )
return IsomorphismFpGroupByPcgs( Pcgs( G ), nam); end );
############################################################################# ## #O IsomorphismFpGroupByGeneratorsNC( G ) ##
InstallMethod(IsomorphismFpGroupByGeneratorsNC,"pcgs",
IsFamFamX,[IsGroup,IsPcgs,IsString],0, function( G,p,nam ) # this test now is obsolete but extremely cheap. if Product(RelativeOrders(p))<Size(G) then
Error("pcgs does not generate the group"); fi;
return IsomorphismFpGroupByPcgs( p, nam); end );
############################################################################# ## #F InitEpimorphismSQ( F ) ##
InstallGlobalFunction( InitEpimorphismSQ, function( F )
local g, gens, r, rels, ng, nr, pf, pn, pp, D, M, Q, I, A, G, min,
gensA, relsA, gensG, imgs, prei, i, j, k, l, norm, index, diag, n,genu;
if IsFpGroup(F) then
gens := GeneratorsOfGroup( FreeGroupOfFpGroup( F ) );
ng := Length( gens );
genu:=List(gens,i->GeneratorSyllable(i,1));
genu:=List([1..Maximum(genu)],i->Position(genu,i));
rels := RelatorsOfFpGroup( F );
nr := Length( rels );
# build the relation matrix for the commutator quotient group
M := []; for i in [ 1..Maximum( nr, ng ) ] do
M[i] := List( [ 1..ng ], i->0 ); if i <= nr then
r := rels[i]; for j in [1..NrSyllables(r)] do
g := GeneratorSyllable(r,j);
k:=genu[g];
M[i][k] := M[i][k] + ExponentSyllable(r,j);
od; fi;
od;
# compute normal form
norm := NormalFormIntMat( M,15 );
D := norm.normal;
Q := norm.coltrans;
I := Q^-1;
min := Minimum( Length(D), Length(D[1]) );
diag := List( [1..min], x -> D[x][x] ); if ForAny( diag, x -> x = 0 ) then
Info(InfoSQ,1,"solvable quotient is infinite");
return false; fi;
# compute pc presentation for the finite quotient
n := Filtered( diag, x -> x <> 1 );
n := Length( Flat( List( n, x -> Factors(Integers, x ) ) ) );
A := FreeGroup(IsSyllableWordsFamily, n );
gensA := GeneratorsOfGroup( A );
index := [];
relsA := [];
g := 1;
pf := []; for i in [ 1..ng ] do if D[i][i] <> 1then
index[i] := g;
pf[i] := TransposedMat( Collected( Factors(Integers, D[i][i] ) ) );
pf[i] := rec( factors := pf[i][1],
powers := pf[i][2] ); for j in [ 1..Length( pf[i].factors ) ] do
pn := pf[i].factors[j];
pp := pf[i].powers [j]; for k in [ 1..pp ] do
relsA[g] := [];
relsA[g][g] := gensA[g]^pn; for l in [ 1..g-1 ] do
relsA[g][l] := gensA[g]^gensA[l]/gensA[g];
od; if j <> 1 or k <> 1then
relsA[g-1][g-1] := relsA[g-1][g-1]/gensA[g]; fi;
g := g + 1;
od;
od; fi;
od;
relsA := Flat( relsA );
A := A / relsA;
# compute corresponding pc group
G := PcGroupFpGroup( A );
gensG := Pcgs( G );
# set up epimorphism F -> A -> G
imgs := []; for i in [ 1..ng ] do
imgs[i] := One( G ); for j in [ 1..ng ] do if Q[i][j] <> 0 and D[j][j] <> 1then
imgs[i] := imgs[i] * gensG[index[j]]^( Q[i][j] mod D[j][j] ); fi;
od;
od;
# compute preimages
prei := []; for i in [ 1..ng ] do if D[i][i] <> 1then
r := One( FreeGroupOfFpGroup( F ) ); for j in [ 1..ng ] do if imgs[j] <> One( G ) then
r := r * gens[j] ^ ( I[i][j] mod Order( imgs[j] ) ); fi;
od;
g := index[i]; for j in [ 1..Length( pf[i].factors ) ] do
pn := pf[i].factors[j];
pp := pf[i].powers [j]; for k in [ 1..pp ] do
prei[g] := r;
g := g + 1;
r := r ^ pn;
od;
od; fi;
od;
return rec( source := F,
image := G,
imgs := imgs,
prei := prei ); elif IsMapping(F) then if IsSurjective(F) and IsWholeFamily(Range(F)) then
return rec(source:=Source(F),
image:=Parent(Image(F)), # parent will replace full group # with other gens.
imgs:=List(GeneratorsOfGroup(Source(F)),
i->Image(F,i))); else # ensure the image group is the whole family
gensG:=Pcgs(Image(F));
G:=GroupByPcgs(gensG);
return rec(source:=Source(F),
image:=G,
imgs:=List(GeneratorsOfGroup(Source(F)),
i->PcElementByExponentsNC(FamilyPcgs(G),
ExponentsOfPcElement(gensG,Image(F,i))))); fi; fi;
Error("Syntax!"); end );
############################################################################# ## #F LiftEpimorphismSQ( epi, M, c ) ##
InstallGlobalFunction( LiftEpimorphismSQ, function( epi, M, c )
local F, G, pcgsG, n, H, pcgsH, d, gensf, pcgsN, htil, gtil, mtil,mtilinv,
w, e, g, m, i, A, V, rel, l, v, mats, j, mat, k, elms, imgs,
lift, null, vec, new, U, sol, sub, elm, r,tval,tvalp,
ex,pos,i1,genid,rels,reln,stopi;
F := epi.source;
gensf := GeneratorsOfGroup( FreeGroupOfFpGroup( F ) );
r := Length( gensf );
genid:=[]; for i in [1..r] do
genid[GeneratorSyllable(gensf[i],1)]:=i;
od;
d := M.dimension;
G := epi.image;
pcgsG := Pcgs( G );
n := Length( pcgsG );
H := ExtensionNC( G, M, c );
pcgsH := Pcgs( H );
pcgsN := InducedPcgsByPcSequence( pcgsH, pcgsH{[n+1..n+d]} );
htil := pcgsH{[1..n]};
gtil := [];
mtil := [];
mtilinv:=[]; for w in epi.imgs do
e := ExponentsOfPcElement( pcgsG, w );
g := PcElementByExponentsNC( pcgsH, htil, e );
Add( gtil, g );
m := ImmutableMatrix(M.field, IdentityMat( d, M.field ) ); for i in [1..n] do
m := m * M.generators[i]^e[i];
od;
Add( mtil,m); #Add( mtilinv, ImmutableMatrix(M.field,m^-1 ));
od;
mtilinv:=List(mtil,i->i^-1);
# set up inhom eq
A := List( [1..r*d], x -> [] );
V := [];
# for each relator of G add
rels:=RelatorsOfFpGroup(F);
stopi:=[4,8,15,30,200];
AddSet(stopi,Length(rels)); for reln in [1..Length(rels)] do if IsInt(reln/100) then
Info(InfoSQ,2,reln); fi;
rel:=rels[reln];
l := NrSyllables( rel );
# right hand side # was: v := MappedWord( rel, gensf, gtil );
v:=One(gtil[1]); for i in [1..l] do
j := genid[GeneratorSyllable(rel,i)];
ex:=ExponentSyllable(rel,i); if ex<0then
v:=v/gtil[j]^(-ex); else
v:=v*gtil[j]^ex; fi;
od;
v := ExponentsOfPcElement( pcgsN, v ) * One( M.field );
Append( V, v );
# left hand side
mats := ListWithIdenticalEntries( r,
Immutable( NullMat( d, d, M.field ) ) );
# ahulpke, 28-feb-00: it seems to be much more clever, to run # through this loop backwards. Then `MappedWord' can be replaced by # a multiplication # Similarly the iterated calls to `Subword' are very expensive - better # use the internal syllable indexing
# tval is the product from position i on, tvalp the product from # position i+1 on (the tval of the last round)
tval:=One(mats[1]);
for i in [l,l-1..1] do
j := genid[GeneratorSyllable(rel,i)];
ex:=ExponentSyllable(rel,i); if ex<0then
pos:=false;
ex:=-ex; else
pos:=true; fi; for i1 in [1..ex] do
tvalp:=tval; if pos then
tval:=mtil[j]*tval;
mat:=tvalp;
mats[j] := mats[j] + mat; else
tval:=mtilinv[j]*tval;
mat := tval;
mats[j] := mats[j] - mat; fi;
od;
od;
for i in [1..r] do for j in [1..d] do
k := d * (i-1) + j;
Append( A[k], mats[i][j] );
od;
od;
# do these tests several times earlier to speed up if reln in stopi then
sol := SolutionMat( A, V ); # if there is no solution, then there is no lift if sol=fail then #T return value should be fail? if reln<Length(rels) then
Info(InfoSQ,3,"early break:",reln); fi;
return false; fi; fi;
od;
# create lift
elms := []; for i in [1..r] do
sub := - sol{[d*(i-1)+1..d*i]};
elm := PcElementByExponentsNC( pcgsN, sub );
Add( elms, elm );
od;
imgs := List( [1..r], x -> gtil[x] * elms[x] ) ;
lift := rec( source := F,
image := H,
imgs := imgs );
# in non-split case this is it if IsRowVector( c ) then return lift; fi;
# otherwise check
U := Subgroup( H, imgs ); if Size( U ) = Size( H )
and c=0then# c=0 is the ordinary case
return lift; else
lift:=false; # indicate the lift is no good fi;
# this is not optimal - see Plesken
null := NullspaceMat( A );
Info(InfoSQ,2,"nullspace dimension:",Length(null)); for vec in null do
new := vec + sol;
elms := []; for i in [1..r] do
sub := new{[d*(i-1)+1..d*i]};
elm := PcElementByExponentsNC( pcgsN, sub );
Add( elms, elm );
od;
imgs := List( [1..r], x -> gtil[x] * elms[x] );
U := Subgroup( H, imgs ); if Size( U ) = Size( H ) then if lift<>false then
Info(InfoSQ,2,"found one");
lift:=SubdirProdPcGroups(H,imgs,
lift.image,lift.imgs);
H:=lift[1];
imgs:=lift[2]; fi;
lift := rec( source := F,
image := H,
imgs := imgs ); if c=0then
return lift; fi; fi;
od;
# give up
return lift; # if c=0 this is automatically false end );
############################################################################# ## #F BlowUpCocycleSQ( v, K, F ) ##
InstallGlobalFunction( BlowUpCocycleSQ, function( v, K, F )
local Q, B, vectors, hlp, i, k;
if F = K then return v; fi;
Q := AsField( K, F );
B := Basis( Q );
vectors:= BasisVectors( B );
hlp := []; for i in [ 1..Length( v ) ] do for k in [ 1..Length( vectors ) ] do
Add( hlp, Coefficients( B, v[i] * vectors[k] )[1] );
od;
od;
return hlp; end );
############################################################################# ## #F TryModuleSQ( epi, M ) ##
InstallGlobalFunction( TryModuleSQ, function( epi, M )
local C, lift, co, cb, cc, r, q, ccpos, ccnum, l, v, qi, c;
# first try a split extension
lift := LiftEpimorphismSQ( epi, M, 0 ); if not IsBool( lift ) then return lift; fi;
# get collector
C := CollectorSQ( epi.image, M.absolutelyIrreducible, true );
# compute the two cocycles
co := TwoCocyclesSQ( C, epi.image, M.absolutelyIrreducible );
# if there is one non split extension, try all mod coboundaries if0 < Length(co) then
cb := TwoCoboundariesSQ( C, epi.image, M.absolutelyIrreducible );
# use only those coboundaries which lie in <co> if0 < Length(C.avoid) then
cb := SumIntersectionMat( co, cb )[2]; fi;
# convert them into row spaces if0 < Length(cb) then
cc := BaseSteinitzVectors( co, cb ).factorspace; else
cc := co; fi;
# try all non split extensions if0 < Length(cc) then
r := PrimitiveRoot( M.absolutelyIrreducible.field );
q := Size( M.absolutelyIrreducible.field );
# loop over all vectors of <cc> for ccpos in [ 1 .. Length(cc) ] do for ccnum in [ 0 .. q^(Length(cc)-ccpos)-1 ] do
v := cc[Length(cc)-ccpos+1]; for l in [ 1 .. Length(cc)-ccpos ] do
qi := QuoInt( ccnum, q^(l-1) ); if qi mod q <> q-1then
v := v + r^(qi mod q) * cc[l]; fi;
od;
# blow cocycle up
c := BlowUpCocycleSQ( v, M.field,
M.absolutelyIrreducible.field );
# try to lift epimorphism
lift := LiftEpimorphismSQ( epi, M, c);
# return if we have found a lift if not IsBool( lift ) then return lift; fi;
od;
od; fi; fi;
# give up
return false; end );
############################################################################# ## #F AllModulesSQ( epi, M ) ##
InstallGlobalFunction( AllModulesSQ, function( epi, M,onlyact )
local C, lift, co, cb, cc, r, q, ccpos, ccnum, l, v, qi,
c,all,cnt,total,i,j,iter,sel,dim;
iter:=onlyact<Length(Pcgs(epi.image)); # are we running in iteration?
all:=epi;
if not iter then # first try a split extension # the -1 indicates we want *all* sdps
lift := LiftEpimorphismSQ( epi, M, -1 ); if not IsBool( lift ) then all:=lift;
Info(InfoSQ,2,"semidirect ",Size(all.image)/Size(epi.image)," found"); fi; fi;
# get collector
dim:=M.absolutelyIrreducible.dimension;
C := CollectorSQ( epi.image, M.absolutelyIrreducible, true );
# compute the two cocycles
co := TwoCocyclesSQ( C, epi.image, M.absolutelyIrreducible );
# if there is one non split extension, try all mod coboundaries if0 < Length(co) then
cb := TwoCoboundariesSQ( C, epi.image, M.absolutelyIrreducible );
q:=false; if iter and Length(cb)>0then # we only want those cocycles, which are trivial for the extra # generators # find those indices which can have nontrivial cocycles
r:=Length(Pcgs(epi.image));
v:=[1..dim];
sel:=[]; for i in [1..r] do for j in [1..Minimum(i,onlyact)] do
UniteSet(sel,((i^2-i)/2+j-1)*dim+v);
od;
od;
v:=IdentityMat(Length(co[1]),M.absolutelyIrreducible.field){sel};
v:=ImmutableMatrix(M.absolutelyIrreducible.field,v);
r:=SumIntersectionMat(v,co)[2]; if Length(r)<Length(co) then
Info(InfoSQ,1,"don't need all cocycles/reduced cohomology");
co:=r;
q:=true; # use as flag whether it got changed fi; fi;
# use only those coboundaries which lie in <co> if0 < Length(C.avoid) or q then
cb := SumIntersectionMat( co, cb )[2]; fi;
# representatives for basis for the 2-cohomology if0 < Length(cb) then
cc := BaseSteinitzVectors( co, cb ).factorspace; else
cc := co; fi;
# try all non split extensions if0 < Length(cc) then
r := PrimitiveRoot( M.absolutelyIrreducible.field );
q := Size( M.absolutelyIrreducible.field );
total:=Int(q^Length(cc)/(q-1)); # approximately
cnt:=0; # loop over all vectors of <cc> for ccpos in [ 1 .. Length(cc) ] do for ccnum in [ 0 .. q^(Length(cc)-ccpos)-1 ] do
cnt:=cnt+1; if cnt mod 10 =0then
CompletionBar(InfoSQ,2,"cocycle loop: ",cnt/total); fi;
v := cc[Length(cc)-ccpos+1]; for l in [ 1 .. Length(cc)-ccpos ] do
qi := QuoInt( ccnum, q^(l-1) ); if qi mod q <> q-1then
v := v + r^(qi mod q) * cc[l]; fi;
od;
# blow cocycle up
c := BlowUpCocycleSQ( v, M.field,
M.absolutelyIrreducible.field );
# try to lift epimorphism
lift := LiftEpimorphismSQ( epi, M, c);
# return if we have found a lift if not IsBool( lift ) then
lift:=SubdirProdPcGroups(all.image,all.imgs,
lift.image,lift.imgs); all:=rec(source:=epi.source,
image:=lift[1],
imgs:=lift[2]);
Info(InfoSQ,2,"locally ",Size(all.image)/Size(epi.image), " found"); fi;
# compute modules for prime
field := GF(layer[1]);
dim := layer[2];
reps := IrreducibleModules( epi.image, field, dim );
reps:=reps[2]; # the actual modules
# loop over the representations for rep in reps do
lift := TryModuleSQ( epi, rep ); if not IsBool( lift ) then if not layer[3] or rep.dimension = dim then
return lift; fi; fi;
od;
# give up
return false; end );
############################################################################# ## #F EAPrimeLayerSQ( epi, prime ) ##
InstallGlobalFunction( EAPrimeLayerSQ, function( epi, prime )
local field, dim, rep, lift,all,dims,allmo,mo,start,found,genum,genepi;
# compute modules for prime
field := GF(prime);
start:=epi;
dims:=List(CharacterDegrees(epi.image,prime),i->i[1]);
genum:=Length(Pcgs(epi.image)); # number of generators of the starting # group. (We need to consider nontrivial # cocycles only for those elements, as we # only want to get one layer.) # build all modules
allmo:=[]; for dim in dims do
rep := IrreducibleModules( epi.image, field, dim );
rep:=rep[2]; # the actual modules
rep:=Filtered(rep,i->i.dimension=dim);
Info(InfoSQ,1,"Dimension ",dim,", ",Length(rep)," modules");
allmo[dim]:=rep;
od;
repeat # extend as long as possible all:=epi;
genepi:=Length(Pcgs(epi.image));
found:=false; for dim in dims do # loop over the representations for rep in [1..Length(allmo[dim])] do
Info(InfoSQ,2,"Module representative ",dim," #",rep);
mo:=allmo[dim][rep];
# inflate to extra generators if genum<genepi then
mo:=GModuleByMats(Concatenation(mo.generators,
List([1..genepi-genum],
i->One(mo.generators[1]))),field); if allmo[dim][rep].absolutelyIrreducible=allmo[dim][rep] then
mo.absolutelyIrreducible:=mo; else
mo.absolutelyIrreducible:=GModuleByMats(
Concatenation(allmo[dim][rep].absolutelyIrreducible.generators,
List([1..genepi-genum],
i->One(allmo[dim][rep].absolutelyIrreducible.generators[1]))),
allmo[dim][rep].absolutelyIrreducible.field); fi; fi;
lift := AllModulesSQ( epi, mo,genum); if Size(lift.image)>Size(epi.image) then
found:=true;
lift:=SubdirProdPcGroups(all.image,all.imgs,
lift.image,lift.imgs); all:=rec(source:=epi.source,
image:=lift[1],
imgs:=lift[2]);
Info(InfoSQ,1,"globally ",Size(all.image)/Size(start.image)," found"); fi;
od;
# initialise epimorphism
epi := InitEpimorphismSQ(F); if epi=false then if0 in AbelianInvariants(F) then
Error("Group has infinite abelian quotient"); else
Error("initialization failed"); fi; fi;
iso := IsomorphismSpecialPcGroup( epi.image );
epi.image := Image( iso );
epi.imgs := List( epi.imgs, x -> Image( iso, x ) );
G := epi.image;
Info(InfoSQ,1,"init done, quotient has size ",Size(G));
# if the commutator factor group is trivial return if Size( G ) = 1then return epi; fi;
# if <primes> is a list of tuples, it denotes a chief series if IsList( primes ) and IsList( primes[1] ) then
Info(InfoSQ,2,"have chief series given"); for tup in primes{[2..Length(primes)]} do
Info(InfoSQ,1,"trying ", tup);
tup[3] := true;
lift := TryLayerSQ( epi, tup ); if IsBool( lift ) then
return epi; else
epi := ShallowCopy( lift );
iso := IsomorphismSpecialPcGroup( epi.image );
epi.image := Image( iso );
epi.imgs := List( epi.imgs, x -> Image( iso, x ) );
G := epi.image; fi;
Info(InfoSQ,1,"found quotient of size ", Size(G));
od;
# if <primes> is a list of primes, we have to use try and error elif IsList( primes ) and IsInt( primes[1] ) then
found := true;
i := 1; while found and i <= Length( primes ) do
p := primes[i];
tup := [p, 0, false];
Info(InfoSQ,1,"trying ", tup);
lift := TryLayerSQ( epi, tup ); if not IsBool( lift ) then
epi := ShallowCopy( lift );
iso := IsomorphismSpecialPcGroup( epi.image );
epi.image := Image( iso );
epi.imgs := List( epi.imgs, x -> Image( iso, x ) );
G := epi.image;
found := true;
i := 1; else
i := i + 1; fi;
Info(InfoSQ,1,"found quotient of size ", Size(G));
od;
# if <primes> is an integer it is size we want elif IsInt(primes) then if not IsInt(primes/Size(G)) then
i:=Lcm(primes,Size(G));
Info(InfoWarning,1,"Added extra factor ",i/primes, " to allow for G/G'");
primes:=i; fi;
i := primes / Size( G );
found := true; while i > 1 and found do
fac := Collected( Factors(Integers, i ) );
found := false;
j := 1; while not found and j <= Length( fac ) do
fac[j][3] := false;
Info(InfoSQ,1,"trying ", fac[j]);
lift := TryLayerSQ( epi, fac[j] ); if not IsBool( lift ) then
epi := ShallowCopy( lift );
iso := IsomorphismSpecialPcGroup( epi.image );
epi.image := Image( iso );
epi.imgs := List( epi.imgs, x -> Image( iso, x ) );
G := epi.image;
found := true;
i := primes / Size( G ); else
j := j + 1; fi;
Info(InfoSQ,1,"found quotient of size ", Size(G));
od;
od; else
Error("<primes> must be either an integer, a list of integers, or a list of integer lists"); fi;
# this is the result - should be G only with set epimorphism
return epi; end );
InstallGlobalFunction(EpimorphismSolvableQuotient,function(arg)
local g, sq, hom;
g:=arg[1];
sq:=CallFuncList(SQ,arg);
hom:=GroupHomomorphismByImages(g,sq.image,GeneratorsOfGroup(g),sq.imgs);
SetIsSurjective( hom, true ); if HasSize(g) then
SetIsInjective(hom, Size(g)=Size(sq.image)); fi;
return hom; end);
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.28 Sekunden
(vorverarbeitet am 2026-10-13)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.