From ed4c9a88952ad130ac80e7d4a8d125c667d2b469 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 20 May 2026 09:13:46 +0100 Subject: [PATCH 01/50] re-edited library files, adding NC --- lib/algebra.gi | 2 +- lib/algfp.gi | 2 +- lib/alghom.gi | 16 ++--- lib/alglie.gi | 26 ++++---- lib/algrep.gi | 8 +-- lib/autsr.gi | 42 ++++++------ lib/clas.gi | 2 +- lib/clashom.gi | 48 +++++++------- lib/csetgrp.gi | 4 +- lib/ctblfuns.gi | 4 +- lib/ctblgrp.gi | 4 +- lib/ctblsolv.gi | 28 ++++---- lib/field.gi | 13 ++-- lib/fitfree.gi | 24 +++---- lib/fldabnum.gi | 12 ++-- lib/ghom.gi | 20 +++--- lib/ghomfp.gi | 16 ++--- lib/ghompcgs.gi | 8 +-- lib/ghomperm.gi | 32 +++++----- lib/gpfpiso.gi | 72 ++++++++++----------- lib/gpprmsya.gi | 2 +- lib/gprd.gi | 16 ++--- lib/gprdmat.gi | 12 ++-- lib/gprdpc.gi | 2 +- lib/gprdperm.gi | 26 ++++---- lib/grp.gi | 24 +++---- lib/grpcompl.gi | 6 +- lib/grpfp.gi | 18 +++--- lib/grplatt.gi | 6 +- lib/grpmat.gi | 10 +-- lib/grpnames.gi | 2 +- lib/grpnice.gd | 14 ++-- lib/grpnice.gi | 26 ++++---- lib/grppc.gi | 12 ++-- lib/grppcaut.gi | 20 +++--- lib/grppccom.gi | 4 +- lib/grppcext.gi | 44 ++++++------- lib/grppclat.gi | 6 +- lib/grpperm.gi | 6 +- lib/grpprmcs.gi | 16 ++--- lib/liefam.gi | 2 +- lib/mapphomo.gi | 46 +++++++------- lib/mapping.gd | 51 ++++++++++++--- lib/mapping.gi | 166 +++++++++++++++++++++++++++++++++++++++++++----- lib/mapprep.gi | 106 +++++++++++++++---------------- lib/maxsub.gi | 22 +++---- lib/mgmring.gi | 8 +-- lib/morpheus.gi | 28 ++++---- lib/norad.gi | 8 +-- lib/onecohom.gi | 10 +-- lib/oprt.gi | 14 ++-- lib/oprtglat.gi | 2 +- lib/oprtperm.gi | 2 +- lib/pcgsnice.gi | 2 +- lib/permdeco.gi | 10 +-- lib/relation.gi | 30 ++++----- lib/ringhom.gi | 4 +- lib/schur.gi | 22 +++---- lib/semirel.gi | 2 +- lib/stbcbckt.gi | 2 +- lib/twocohom.gi | 18 +++--- lib/vspchom.gi | 8 +-- 62 files changed, 693 insertions(+), 525 deletions(-) diff --git a/lib/algebra.gi b/lib/algebra.gi index e8457b37e1..df6d32f75f 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3647,7 +3647,7 @@ InstallMethod( CentralIdempotentsOfAlgebra, until k>Length(ideals); - id:= List( ids, e -> PreImagesRepresentative( hom, e ) ); + id:= List( ids, e -> PreImagesRepresentativeNC( hom, e ) ); # Now we lift the idempotents to the big algebra `A'. The # first idempotent is lifted as follows: diff --git a/lib/algfp.gi b/lib/algfp.gi index c65a8ec796..51adff0b6d 100644 --- a/lib/algfp.gi +++ b/lib/algfp.gi @@ -705,7 +705,7 @@ InstallHandlingByNiceBasis( "IsFpAlgebraElementsSpace", rec( if hom = fail then TryNextMethod(); fi; - return PreImagesRepresentative( hom, r ); + return PreImagesRepresentativeNC( hom, r ); end ) ); diff --git a/lib/alghom.gi b/lib/alghom.gi index 8dc79c6efd..550ac43fd6 100644 --- a/lib/alghom.gi +++ b/lib/alghom.gi @@ -576,16 +576,16 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . for algebra g.m.b.i. +#M PreImagesRepresentativeNC( , ) . . . . . . for algebra g.m.b.i. ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for algebra g.m.b.i., and element", FamRangeEqFamElm, [ IsGeneralMapping and IsAlgebraGeneralMappingByImagesDefaultRep, IsObject ], function( map, elm ) - return PreImagesRepresentative( AsLeftModuleGeneralMappingByImages(map), - elm ); + return PreImagesRepresentativeNC( + AsLeftModuleGeneralMappingByImages(map), elm ); end ); @@ -902,7 +902,7 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) +#M PreImagesRepresentativeNC( , ) ## BindGlobal( "PreImagesRepresentativeOperationAlgebraHomomorphism", function( ophom, mat ) if not IsBound( ophom!.basisImage ) then @@ -915,7 +915,7 @@ BindGlobal( "PreImagesRepresentativeOperationAlgebraHomomorphism", function( oph return mat; end ); -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for an operation algebra homomorphism, and an element", FamRangeEqFamElm, [ IsOperationAlgebraHomomorphismDefaultRep, IsMatrix ], @@ -1076,9 +1076,9 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) +#M PreImagesRepresentativeNC( , ) ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for an alg. hom. from f. p. algebra, and an element", FamRangeEqFamElm, [ IsAlgebraHomomorphismFromFpRep, IsMatrix ], diff --git a/lib/alglie.gi b/lib/alglie.gi index 322e003d6d..d3343f8fc4 100644 --- a/lib/alglie.gi +++ b/lib/alglie.gi @@ -34,7 +34,7 @@ InstallMethod( LieUpperCentralSeries, # under the natural homomorphism. Add( S, C ); hom:= NaturalHomomorphismByIdeal( L, C ); - C:= PreImages( hom, LieCentre( Range( hom ) ) ); + C:= PreImagesNC( hom, LieCentre( Range( hom ) ) ); #T we would like to get ideals! #T is it possible to teach the hom. that the preimage of an ideal is an ideal? @@ -1706,7 +1706,7 @@ InstallMethod( LieSolvableRadical, quo:= ImagesSource( hom ); r1:= LieSolvableRadical( quo ); B:= BasisVectors( Basis( r1 ) ); - B:= List( B, x -> PreImagesRepresentative( hom, x ) ); + B:= List( B, x -> PreImagesRepresentativeNC( hom, x ) ); Append( B, BasisVectors( Basis( n ) ) ); fi; @@ -2092,7 +2092,7 @@ InstallMethod( DirectSumDecomposition, SetRadicalOfAlgebra( Q, Subalgebra( Q, [ Zero( Q ) ] ) ); id:= List( CentralIdempotentsOfAlgebra( Q ), - x->PreImagesRepresentative(hom,x)); + x->PreImagesRepresentativeNC(hom,x)); # Now we lift the idempotents to the big algebra `A'. The # first idempotent is lifted as follows: @@ -4017,9 +4017,9 @@ InstallMethod( ImagesRepresentative, ########################################################################### ## -#M PreImagesRepresentative( f, x ) +#M PreImagesRepresentativeNC( f, x ) ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for Fp to SCA mapping, and element", FamRangeEqFamElm, [ IsFptoSCAMorphism, IsSCAlgebraObj ], 0, @@ -5592,8 +5592,8 @@ InstallMethod( JenningsLieAlgebra, T:= EmptySCTable( dim , Zero(F) , "antisymmetric" ); pimgs := []; for i in [1..dim] do - a:= PreImagesRepresentative( Homs[pos[i]] , - PreImagesRepresentative( hom_pcg[pos[i]], gens[i] ) ); + a:= PreImagesRepresentativeNC( Homs[pos[i]] , + PreImagesRepresentativeNC( hom_pcg[pos[i]], gens[i] ) ); # calculate the p-th power image of `a': @@ -5610,8 +5610,8 @@ InstallMethod( JenningsLieAlgebra, # Calculate the commutator [a,b], and map the result into # the correct homogeneous component. - b:= PreImagesRepresentative( Homs[pos[j]], - PreImagesRepresentative( hom_pcg[pos[j]], gens[j] )); + b:= PreImagesRepresentativeNC( Homs[pos[j]], + PreImagesRepresentativeNC( hom_pcg[pos[j]], gens[j] )); c:= Image( hom_pcg[pos[i] + pos[j]], Image(Homs[pos[i] + pos[j]], a^-1*b^-1*a*b) ); e:= ExtRepOfObj(c); @@ -5788,8 +5788,8 @@ InstallMethod( PCentralLieAlgebra, T:= EmptySCTable( dim , Zero(F) , "antisymmetric" ); pimgs := []; for i in [1..dim] do - a:= PreImagesRepresentative( Homs[pos[i]] , - PreImagesRepresentative( hom_pcg[pos[i]], gens[i] ) ); + a:= PreImagesRepresentativeNC( Homs[pos[i]] , + PreImagesRepresentativeNC( hom_pcg[pos[i]], gens[i] ) ); # calculate the p-th power image of `a': @@ -5807,8 +5807,8 @@ InstallMethod( PCentralLieAlgebra, # Calculate the commutator [a,b], and map the result into # the correct homogeneous component. - b:= PreImagesRepresentative( Homs[pos[j]], - PreImagesRepresentative( hom_pcg[pos[j]], gens[j] )); + b:= PreImagesRepresentativeNC( Homs[pos[j]], + PreImagesRepresentativeNC( hom_pcg[pos[j]], gens[j] )); c:= Image( hom_pcg[pos[i] + pos[j]], Image(Homs[pos[i] + pos[j]], a^-1*b^-1*a*b) ); e:= ExtRepOfObj(c); diff --git a/lib/algrep.gi b/lib/algrep.gi index 8d331feee2..7607190b94 100644 --- a/lib/algrep.gi +++ b/lib/algrep.gi @@ -1212,24 +1212,24 @@ InstallMethod( NaturalHomomorphismBySubAlgebraModule, if IsLeftAlgebraModuleElementCollection( V ) then if IsRightAlgebraModuleElementCollection( V ) then left_op:= function( x, v ) - return ImagesRepresentative( f, x^PreImagesRepresentative( f, v ) ); + return ImagesRepresentative( f, x^PreImagesRepresentativeNC( f, v ) ); end; right_op:= function( v, x ) - return ImagesRepresentative( f, PreImagesRepresentative( f, v )^x ); + return ImagesRepresentative( f, PreImagesRepresentativeNC( f, v )^x ); end; qmod:= BiAlgebraModule( LeftActingAlgebra( V ), RightActingAlgebra( V ), left_op, right_op, quot ); else left_op:= function( x, v ) - return ImagesRepresentative( f, x^PreImagesRepresentative( f, v ) ); + return ImagesRepresentative( f, x^PreImagesRepresentativeNC( f, v ) ); end; qmod:= LeftAlgebraModule( LeftActingAlgebra( V ), left_op, quot); fi; else right_op:= function( v, x ) - return ImagesRepresentative( f, PreImagesRepresentative( f, v )^x ); + return ImagesRepresentative( f, PreImagesRepresentativeNC( f, v )^x ); end; qmod:= RightAlgebraModule( RightActingAlgebra( V ), right_op, quot ); diff --git a/lib/autsr.gi b/lib/autsr.gi index 241cc84115..704f9093dc 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -118,7 +118,7 @@ local C,M,p,all,gens,sub,q,hom,fp,rels,new,pre,i,free,cnt; rels:=Filtered(RelatorsOfFpGroup(fp),x->ForAll(ExponentSums(x),x->x mod p=0)); rels:=List(rels,x->ElementOfFpGroup(FamilyObj(One(fp)),x)); new:=RestrictedMapping(nat,C)*hom; - pre:=List(rels,x->PreImagesRepresentative(new,x)); + pre:=List(rels,x->PreImagesRepresentativeNC(new,x)); for i in [1..Length(rels)] do if not pre[i] in sub then Add(all,MappedWord(rels[i], @@ -141,7 +141,7 @@ local ocr,fphom,fpg,free,len,dim,tmp,L0,R,rels,mat,r,RS,i,g,v,cnt; fpg:=FreeGeneratorsOfFpGroup(Range(fphom)); ocr.factorpres:=[fpg,RelatorsOfFpGroup(Range(fphom))]; ocr.generators:=List(GeneratorsOfGroup(Range(fphom)), - i->PreImagesRepresentative(fphom,i)); + i->PreImagesRepresentativeNC(fphom,i)); OCAddMatrices(ocr,ocr.generators); OCAddRelations(ocr,ocr.generators); OCAddSumMatrices(ocr,ocr.generators); @@ -274,8 +274,8 @@ BindGlobal("AGSRAutomLift",function(ocr,nat,fhom,miso) # allow to deduce corresponding module aut. t:=ocr.trickrels; phom:=IdentityMapping(ocr.moduleauts); - s:=List(t.gens,x->PreImagesRepresentative(nat,x)); - l:=List(t.gens,x->PreImagesRepresentative(nat,ImagesRepresentative(fhom,x))); + s:=List(t.gens,x->PreImagesRepresentativeNC(nat,x)); + l:=List(t.gens,x->PreImagesRepresentativeNC(nat,ImagesRepresentative(fhom,x))); s:=List(t.rels,x->MappedWord(x,GeneratorsOfGroup(t.free),s)); l:=List(t.rels,x->MappedWord(x,GeneratorsOfGroup(t.free),l)); @@ -294,7 +294,7 @@ BindGlobal("AGSRAutomLift",function(ocr,nat,fhom,miso) Size(Image(phom))); fi; for ep in enum do - e:=PreImagesRepresentative(phom,ep); + e:=PreImagesRepresentativeNC(phom,ep); psim:=e*miso; psim:=psim^-1; w:=-List(v,i->i*psim); @@ -486,7 +486,7 @@ local S,c,hom,q,a,b,i,t,have,ups,new,u,good,abort,clim,worked,pp, cnt:=0; for b in t do - new:=PreImagesRepresentative(hom,b); + new:=PreImagesRepresentativeNC(hom,b); if (pp=false or new^pp in S) and locond(new) then S:=ClosureGroup(S,new); have:=true; @@ -1028,7 +1028,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, b:=MTX.BasisRadical(mo); fratsim:=Length(b)=0; if not fratsim then - b:=List(b,x->PreImagesRepresentative(hom,PcElementByExponents(MPcgs,x))); + b:=List(b,x->PreImagesRepresentativeNC(hom,PcElementByExponents(MPcgs,x))); for j in b do N:=ClosureSubgroup(N,b); od; @@ -1129,8 +1129,8 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, if perm in Aperm then return true; fi; - aut:=PreImagesRepresentative(AQiso,perm); - newgens:=List(gens,x->PreImagesRepresentative(comiso, + aut:=PreImagesRepresentativeNC(AQiso,perm); + newgens:=List(gens,x->PreImagesRepresentativeNC(comiso, ImagesRepresentative(aut,ImagesRepresentative(comiso,x)))); mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); @@ -1163,9 +1163,9 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, if perm in Aperm then return true; fi; - aut:=PreImagesRepresentative(AQiso,perm); + aut:=PreImagesRepresentativeNC(AQiso,perm); newgens:=List(GeneratorsOfGroup(Q), - x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); + x->PreImagesRepresentativeNC(q,Image(aut,ImagesRepresentative(q,x)))); mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); return MTX.IsomorphismModules(mo,mo2)<>fail; end; @@ -1175,9 +1175,9 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, if perm in Aperm then return true; fi; - aut:=PreImagesRepresentative(AQiso,perm); + aut:=PreImagesRepresentativeNC(AQiso,perm); newgens:=List(GeneratorsOfGroup(Q), - x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); + x->PreImagesRepresentativeNC(q,Image(aut,ImagesRepresentative(q,x)))); mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); iso:=MTX.IsomorphismModules(mo,mo2); if iso=fail then @@ -1234,12 +1234,12 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, # stabilize class k:=SmallGeneratingSet(sub); ac:=OrbitStabilizerAlgorithm(sub,false,false, - k,List(k,x->PreImagesRepresentative(AQiso,x)), + k,List(k,x->PreImagesRepresentativeNC(AQiso,x)), rec(pnt:=j, act:= function(set,phi) #local phi; - #phi:=PreImagesRepresentative(AQiso,perm); + #phi:=PreImagesRepresentativeNC(AQiso,perm); return Set(List(set,x->Image(phi,x))); end, onlystab:=true)); @@ -1367,7 +1367,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, GeneratorsOfGroup(rf), List(GeneratorsOfGroup(rf), y->ImagesRepresentative(hom,ImagesRepresentative(j, - PreImagesRepresentative(hom,y))))); + PreImagesRepresentativeNC(hom,y))))); Assert(2,IsBijective(k)); Add(ind,k); od; @@ -1390,7 +1390,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, proj:=GroupHomomorphismByImagesNC(AQP,Image(resperm), B[2],List(GeneratorsOfGroup(res),x->ImagesRepresentative(resperm,x))); C:=PreImage(proj,Image(resperm,ind)); - C:=List(SmallGeneratingSet(C),x->PreImagesRepresentative(AQiso,x)); + C:=List(SmallGeneratingSet(C),x->PreImagesRepresentativeNC(AQiso,x)); AQ:=Group(C); SetIsFinite(AQ,true); SetIsGroupOfAutomorphismsFiniteGroup(AQ,true); @@ -1416,7 +1416,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, C:=MappingGeneratorsImages(AQiso); if C[2]<>GeneratorsOfGroup(AQP) then C:=[List(GeneratorsOfGroup(AQP), - x->PreImagesRepresentative(AQiso,x)), + x->PreImagesRepresentativeNC(AQiso,x)), GeneratorsOfGroup(AQP)]; fi; for j in u do @@ -1450,7 +1450,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, substb:=SmallGeneratingSet(substb); AQP:=Group(substb); SetSize(AQP,B); - C:=[List(substb,x->PreImagesRepresentative(AQiso,x)),substb]; + C:=[List(substb,x->PreImagesRepresentativeNC(AQiso,x)),substb]; fi; od; @@ -1883,7 +1883,7 @@ local d,a,map,cG,nG,nH,i,j,u,v,asAutomorphism,K,L,conj,e1,e2, else gens:=SmallGeneratingSet(api); fi; - pre:=List(gens,x->PreImagesRepresentative(iso,x)); + pre:=List(gens,x->PreImagesRepresentativeNC(iso,x)); map:=RepresentativeAction(SubgroupNC(a,pre),u,v,asAutomorphism); if map=fail then return fail; @@ -1904,6 +1904,6 @@ local d,a,map,cG,nG,nH,i,j,u,v,asAutomorphism,K,L,conj,e1,e2, fi; return GroupHomomorphismByImagesNC(G,H,GeneratorsOfGroup(G), - List(GeneratorsOfGroup(G),x->PreImagesRepresentative(e2, + List(GeneratorsOfGroup(G),x->PreImagesRepresentativeNC(e2, Image(conj,Image(e1,x))))); end); diff --git a/lib/clas.gi b/lib/clas.gi index b933b7d50b..2a27e3cbba 100644 --- a/lib/clas.gi +++ b/lib/clas.gi @@ -395,7 +395,7 @@ local H,cl,a,c; H:=Image(hom,G); cl:=[]; for c in ConjugacyClasses(H) do - a:=ConjugacyClass(G,PreImagesRepresentative(hom,Representative(c))); + a:=ConjugacyClass(G,PreImagesRepresentativeNC(hom,Representative(c))); if HasStabilizerOfExternalSet(c) then SetStabilizerOfExternalSet(a,PreImage(hom,StabilizerOfExternalSet(c))); fi; diff --git a/lib/clashom.gi b/lib/clashom.gi index 201b2cd9b7..16c7c4f9c3 100644 --- a/lib/clashom.gi +++ b/lib/clashom.gi @@ -499,7 +499,7 @@ local clT, # classes T for k in clop do Info(InfoHomClass,1,"lifting class ",Representative(k)); - r:=PreImagesRepresentative(ophom,Representative(k)); + r:=PreImagesRepresentativeNC(ophom,Representative(k)); # try to make r of small order rp:=r^Order(Representative(k)); rp:=RepresentativeAction(M,Concatenation(components), @@ -564,7 +564,7 @@ local clT, # classes T orb:=[]; for p in [1..Length(clTR)] do - repres:=PreImagesRepresentative(projections[i],clTR[p]); + repres:=PreImagesRepresentativeNC(projections[i],clTR[p]); if i=1 or isdirprod or reps[j]*RestrictedPermNC(repres,components[i]) in Mproj[i] then @@ -586,8 +586,8 @@ local clT, # classes T #was: #clTR:=List(clTR,i->ConjugacyClass(localcent_r,i)); - #clTR:=List(clTR,j->[PreImagesRepresentative(projections[i], - # Representative(j)), + #clTR:=List(clTR,j->[PreImagesRepresentativeNC(projections[i], + # Representative(j)), # PreImage(centrhom,Centralizer(j)), # j]); @@ -706,7 +706,7 @@ local clT, # classes T #change the transversal element to map to the representative con:=trans[orpo]*gen; limg:=opfun(repres,con); - con:=con*PreImagesRepresentative(centrhom, + con:=con*PreImagesRepresentativeNC(centrhom, RepresentativeAction(localcent_r, Image(projections[i],limg), Representative(clTR[p][3]))); @@ -798,7 +798,7 @@ local clT, # classes T # centralizers_r-conjugation.) con:=trans[orpo]*gen; limg:=opfun(repres,con); - con:=con*PreImagesRepresentative(centrhom, + con:=con*PreImagesRepresentativeNC(centrhom, RepresentativeAction(localcent_r, Image(projections[i],limg), Representative(orb[p][3]))); @@ -870,7 +870,7 @@ local clT, # classes T # remember the element to try trymap:=[p,(cengen[genpos2]* - PreImagesRepresentative( + PreImagesRepresentativeNC( RestrictedMapping(projections[i], centralizers[j]), RepresentativeAction( @@ -1140,7 +1140,7 @@ local cs, # chief series of G # compute the classes of the simple nonabelian factor by random search hom:=NaturalHomomorphismByNormalSubgroupNC(G,lastM); cl:=ConjugacyClasses(Image(hom)); - cl:=List(cl,i->[PreImagesRepresentative(hom,Representative(i)), + cl:=List(cl,i->[PreImagesRepresentativeNC(hom,Representative(i)), PreImage(hom,StabilizerOfExternalSet(i))]); cs:=Concatenation([G],Filtered(cs,x->IsSubset(lastM,x))); fi; @@ -1207,7 +1207,7 @@ local cs, # chief series of G autos:=List(GeneratorsOfGroup(G), i->GroupHomomorphismByImagesNC(T1,T1,GeneratorsOfGroup(T1), List(GeneratorsOfGroup(T1), - j->Image(Thom,PreImagesRepresentative(Thom,j)^i)))); + j->Image(Thom,PreImagesRepresentativeNC(Thom,j)^i)))); # find (probably another) permutation rep for T1 for which all # automorphisms can be represented by permutations @@ -1268,7 +1268,7 @@ local cs, # chief series of G autos:=List(GeneratorsOfGroup(S), i->GroupHomomorphismByImagesNC(T1,T1,GeneratorsOfGroup(T1), List(GeneratorsOfGroup(T1), - j->Image(Thom,PreImagesRepresentative(Thom,j)^i)))); + j->Image(Thom,PreImagesRepresentativeNC(Thom,j)^i)))); # find (probably another) permutation rep for T1 for which all # automorphisms can be represented by permutations @@ -1288,7 +1288,7 @@ local cs, # chief series of G # define isomorphisms between the components reps:=List([1..n],i-> - PreImagesRepresentative(Qhom,RepresentativeAction(Q,1,i))); + PreImagesRepresentativeNC(Qhom,RepresentativeAction(Q,1,i))); genimages:=[]; for j in GeneratorsOfGroup(G) do @@ -1345,7 +1345,7 @@ local cs, # chief series of G SetSize(F,Size(G)); FM:=GroupHomomorphismByImagesNC(G,F,GeneratorsOfGroup(G),FM); clF:=ConjugacyClassesFittingFreeGroup(F); - clF:=List(clF,x->[PreImagesRepresentative(FM,x[1]),PreImage(FM,x[2])]); + clF:=List(clF,x->[PreImagesRepresentativeNC(FM,x[1]),PreImage(FM,x[2])]); return clF; fi; #fi; @@ -1374,9 +1374,9 @@ local cs, # chief series of G Info(InfoHomClass,1, "homomorphism is faithful for relevant factor, take preimages"); if Size(N)=1 and onlysizes=true then - cl:=List(clF,i->[PreImagesRepresentative(Fhom,i[1]),Size(i[2])]); + cl:=List(clF,i->[PreImagesRepresentativeNC(Fhom,i[1]),Size(i[2])]); else - cl:=List(clF,i->[PreImagesRepresentative(Fhom,i[1]), + cl:=List(clF,i->[PreImagesRepresentativeNC(Fhom,i[1]), PreImage(Fhom,i[2])]); fi; else @@ -1391,7 +1391,7 @@ local cs, # chief series of G for k in clF do # modify the representative with a kernel elm. to project # correctly on the second component - elm:=j[1]*PreImagesRepresentative(FMhom, + elm:=j[1]*PreImagesRepresentativeNC(FMhom, LeftQuotient(Image(Fhom,j[1]),k[1])); zentr:=Intersection(j[2],PreImage(Fhom,k[2])); Assert(3,ForAll(GeneratorsOfGroup(zentr), @@ -1449,7 +1449,7 @@ local cs, # chief series of G if Image(Qhom,elm)=jim then # modify the representative with a kernel elm. to project # correctly on the second component - elm:=l[1]*PreImagesRepresentative(FMhom, + elm:=l[1]*PreImagesRepresentativeNC(FMhom, LeftQuotient(Image(Fhom,l[1]),elm)); zentr:=PreImage(Fhom,k[2]^l1); zentr:=Intersection(zentr,l[2]); @@ -1957,7 +1957,7 @@ local classes, # classes to be constructed, the result c := [h * PcElementByExponentsNC( Npcgs,w*com.factorspace), stabrad,stabfacgens,stabfacimg,subsz,stabrsubsz]; #if reduce<>fail then - # Add(classes,[PreImagesRepresentative(reduce,c[1]), + # Add(classes,[PreImagesRepresentativeNC(reduce,c[1]), # PreImage(reduce,c[2])]); # else @@ -2022,7 +2022,7 @@ BindGlobal("LiftClassesEATrivRep", nsfgens:=NormalIntersection(fants[usent],Group(cl[4])); fasize:=Size(nsfgens); nsfgens:=SmallGeneratingSet(nsfgens); - nsgens:=List(nsfgens,x->PreImagesRepresentative(hom,x)); + nsgens:=List(nsfgens,x->PreImagesRepresentativeNC(hom,x)); nsimgs:=List(Concatenation(pcgs,nsgens),npcgsact); mo:=GModuleByMats(nsimgs,field); if not MTX.IsIrreducible(mo) then @@ -2338,7 +2338,7 @@ local r, #radical if IsPermGroup(Range(hom)) and not IsPermGroup(Source(hom)) then f:=Image(hom,G); cl:=ConjugacyClassesFittingFreeGroup(f:onlysizes:=false); - cl:=List(cl,x->[PreImagesRepresentative(hom,x[1]), + cl:=List(cl,x->[PreImagesRepresentativeNC(hom,x[1]), PreImage(hom,x[2])]); else cl:=ConjugacyClassesFittingFreeGroup(G:onlysizes:=false); @@ -2398,12 +2398,12 @@ local r, #radical if ntrihom then ncl:=[]; for i in cl do - new:=[PreImagesRepresentative(hom,i[1])]; + new:=[PreImagesRepresentativeNC(hom,i[1])]; if not IsInt(i[2]) then Add(new,[]); # no generators in radical yet gens:=SmallGeneratingSet(i[2]); Add(new, - List(gens,x->PreImagesRepresentative(hom,x))); + List(gens,x->PreImagesRepresentativeNC(hom,x))); Add(new,gens); #TODO: PreImage groups? #Add(new,PreImage(hom,i[2])); @@ -2886,10 +2886,10 @@ local r, #radical fi; prereps:=f!.classpreimgs; if not IsBound(prereps[j]) then - prereps[j]:=PreImagesRepresentative(hom,Representative(cl[j])); + prereps[j]:=PreImagesRepresentativeNC(hom,Representative(cl[j])); fi; - r:=PreImagesRepresentative(hom,conj); + r:=PreImagesRepresentativeNC(hom,conj); d:=GeneratorsOfGroup(Centralizer(cl[j])); # Format for cl is: @@ -2897,7 +2897,7 @@ local r, #radical # in factor, 4:conjugator, 5:cenpcgs, # 6:cenfac, 7:cenfacimgs, 8:censize, 9:cenfacsize Add(nreps,[i,i^r,prereps[j],r,[], - List(d,x->PreImagesRepresentative(hom,x)),d, + List(d,x->PreImagesRepresentativeNC(hom,x)),d, radsize*Size(Centralizer(cl[j])), Size(Centralizer(cl[j]))]); od; reps:=nreps; diff --git a/lib/csetgrp.gi b/lib/csetgrp.gi index 9c5955a8f3..c2d37bfba8 100644 --- a/lib/csetgrp.gi +++ b/lib/csetgrp.gi @@ -199,7 +199,7 @@ local cla,clb,i,j,k,bd,r,rep,b2,dc, r:=SmallerDegreePermutationRepresentation(b:cheap); k:=Image(r,b); gens:=MorFindGeneratingSystem(k,MorMaxFusClasses(MorRatClasses(k))); - gens:=List(gens,x->PreImagesRepresentative(r,x)); + gens:=List(gens,x->PreImagesRepresentativeNC(r,x)); else gens:=MorFindGeneratingSystem(b,MorMaxFusClasses(MorRatClasses(b))); fi; @@ -1064,7 +1064,7 @@ local c, flip, maxidx, cano, tryfct, p, r, t, Assert(2,Size(a2)*Size(tra)=Size(b)); SetKernelOfMultiplicativeGeneralMapping(r,a2); - dcs:=List(dcs,x->[PreImagesRepresentative(quot,x[1]),Size(a1)*x[2], + dcs:=List(dcs,x->[PreImagesRepresentativeNC(quot,x[1]),Size(a1)*x[2], PreImage(r,x[3])]); r:=List(dcs,x->x[1]); stabs:=List(dcs,x->x[3]); diff --git a/lib/ctblfuns.gi b/lib/ctblfuns.gi index c648c9401f..eec04e92e4 100644 --- a/lib/ctblfuns.gi +++ b/lib/ctblfuns.gi @@ -2049,8 +2049,8 @@ InstallMethod( InertiaSubgroup, if stab = permgrp then return G; else - return PreImagesSet( GroupHomomorphismByImages( G, permgrp, - GeneratorsOfGroup( G ), perms ), + return PreImagesSetNC( GroupHomomorphismByImages( G, permgrp, + GeneratorsOfGroup( G ), perms ), stab ); fi; end ); diff --git a/lib/ctblgrp.gi b/lib/ctblgrp.gi index 3b41dbb5be..914845923f 100644 --- a/lib/ctblgrp.gi +++ b/lib/ctblgrp.gi @@ -1606,7 +1606,7 @@ local tm,tme,piso,gpcgs,gals,ord,l,l2,f,fgens,rws,pow,pos,i,j,k,gen, # not easily transfer to mod p. k:=Image(piso,TrivialSubgroup(D.galMorphisms)); gpcgs:=Pcgs(k); - gals:=List(gpcgs,i->PreImagesRepresentative(piso,i)); + gals:=List(gpcgs,i->PreImagesRepresentativeNC(piso,i)); ord:=List(gpcgs,i->RelativeOrderOfPcElement(gpcgs,i)); l:=Length(gpcgs); @@ -1827,7 +1827,7 @@ local often,trans,e,neu,i,inv,cent,l,s,s1,x,dom; if dom=fail then x:=D.classreps[inv]; - l:=List(s,i->[x^PreImagesRepresentative(e, + l:=List(s,i->[x^PreImagesRepresentativeNC(e, RepresentativeAction(Image(e),1,i[1])),Size(cent)*Length(i)]); else l:=List(s,i->[dom[i[1]],Size(cent)*Length(i)]); diff --git a/lib/ctblsolv.gi b/lib/ctblsolv.gi index d18f10f6d7..fc787a2bb6 100644 --- a/lib/ctblsolv.gi +++ b/lib/ctblsolv.gi @@ -176,7 +176,7 @@ InstallGlobalFunction( ProjectiveCharDeg, function( G, z, q ) # `N' is a normal subgroup such that `N/' is a chief factor of `G' # of order `i' which is a power of `p'. - N:= PreImagesSet( h, N ); + N:= PreImagesSetNC( h, N ); i:= Size( N ) / oz; p:= Factors( i )[1]; @@ -184,7 +184,7 @@ InstallGlobalFunction( ProjectiveCharDeg, function( G, z, q ) # `c' is a list of complement classes of `N' modulo `z' c:= List( ComplementClassesRepresentatives( ImagesSource( h ), ImagesSet( h, N ) ), - x -> PreImagesSet( h, x ) ); + x -> PreImagesSetNC( h, x ) ); r:= Centralizer( G, N ); for L in c do if IsSubset( L, r ) then @@ -563,7 +563,7 @@ InstallGlobalFunction( CoveringTriplesCharacters, function( G, z ) N:= ChiefSeriesUnderAction( img, N ); N:= N[ Length( N ) - 1 ]; fi; - N:= PreImagesSet( h, N ); + N:= PreImagesSetNC( h, N ); if not IsAbelian( N ) then Info( InfoCharacterTable, 2, @@ -582,9 +582,9 @@ InstallGlobalFunction( CoveringTriplesCharacters, function( G, z ) h:= NaturalHomomorphismByNormalSubgroupNC( G, P ); r:= List( CoveringTriplesCharacters( ImagesSource( h ), ImageElm( h, z ) ), - x -> [ PreImagesSet( h, x[1] ), - PreImagesSet( h, x[2] ), - PreImagesRepresentative( h, x[3] ) ] ); + x -> [ PreImagesSetNC( h, x[1] ), + PreImagesSetNC( h, x[2] ), + PreImagesRepresentativeNC( h, x[3] ) ] ); if p = i then @@ -622,9 +622,9 @@ InstallGlobalFunction( CoveringTriplesCharacters, function( G, z ) c:= Stabilizer( img, zn ); fi; Append( r, List( CoveringTriplesCharacters( c, zn ), - x -> [ PreImagesSet( h, x[1] ), - PreImagesSet( h, x[2] ), - PreImagesRepresentative( h, x[3] ) ] ) ); + x -> [ PreImagesSetNC( h, x[1] ), + PreImagesSetNC( h, x[2] ), + PreImagesRepresentativeNC( h, x[3] ) ] ) ); od; return r; @@ -663,9 +663,9 @@ InstallGlobalFunction( CoveringTriplesCharacters, function( G, z ) img:= ImagesSource( h ); Append( r, List( CoveringTriplesCharacters( img, ImageElm( h, z ) ), - x -> [ PreImagesSet( h, x[1] ), - PreImagesSet( h, x[2] ), - PreImagesRepresentative( h, x[3] ) ] ) ); + x -> [ PreImagesSetNC( h, x[1] ), + PreImagesSetNC( h, x[2] ), + PreImagesRepresentativeNC( h, x[3] ) ] ) ); fi; od; return r; @@ -1067,7 +1067,7 @@ InstallMethod( BaumClausenInfo, for i in [ 2 .. Length( ssr.ds ) ] do j:= NaturalHomomorphismByNormalSubgroupNC( ssr.ds[ i-1 ], ssr.ds[i] ); Append( pcgs, List( SpecialPcgs( ImagesSource( j ) ), - x -> PreImagesRepresentative( j, x ) ) ); + x -> PreImagesRepresentativeNC( j, x ) ) ); od; Append( pcgs, SpecialPcgs( Last(ssr.ds) ) ); G:= ImagesSource( hom ); @@ -1911,7 +1911,7 @@ InstallMethod( BaumClausenInfo, k:= Pcgs( kernel ); pcgs:= PcgsByPcSequence( ElementsFamily( FamilyObj( kernel ) ), Concatenation( List( pcgs, - x -> PreImagesRepresentative( hom, x ) ), + x -> PreImagesRepresentativeNC( hom, x ) ), k ) ); k:= ListWithIdenticalEntries( Length( k ), 0 ); diff --git a/lib/field.gi b/lib/field.gi index f5eadb8ede..a65dd50266 100644 --- a/lib/field.gi +++ b/lib/field.gi @@ -1315,15 +1315,15 @@ InstallMethod( ImagesSet, ############################################################################# ## -#M PreImagesElm( , ) . . . . . . . . . . . . preimage of an elm +#M PreImagesElmNC( , ) . . . . . . . . . . . . preimage of an elm ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for field homomorphism and element", FamRangeEqFamElm, [ IsFieldHomomorphism, IsObject ], function ( hom, elm ) if IsInjective( hom ) = 1 then - return [ PreImagesRepresentative( hom, elm ) ]; + return [ PreImagesRepresentativeNC( hom, elm ) ]; elif IsZero( elm ) then return Source( hom ); else @@ -1334,15 +1334,14 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . . . . . . preimage of a set -## -InstallMethod( PreImagesSet, +#M PreImagesSetNC +InstallMethod( PreImagesSetNC, "for field homomorphism and field", CollFamRangeEqFamElms, [ IsFieldHomomorphism, IsField ], function ( hom, elms ) elms:= FieldByGenerators( List( GeneratorsOfField( elms ), - gen -> PreImagesRepresentative( hom, gen ) ) ); + gen -> PreImagesRepresentativeNC( hom, gen ) ) ); UseSubsetRelation( Source( hom ), elms ); return elms; end ); diff --git a/lib/fitfree.gi b/lib/fitfree.gi index d68681ea93..a683e7964c 100644 --- a/lib/fitfree.gi +++ b/lib/fitfree.gi @@ -81,7 +81,7 @@ local ffs,pcisom,rest,kpc,k,x,ker,r,pool,i,xx,pregens,iso; else iso:=IsomorphismFpGroup(Image(rest,U)); pregens:=List(GeneratorsOfGroup(Range(iso)),x-> - PreImagesRepresentative(rest,PreImagesRepresentative(iso,x))); + PreImagesRepresentativeNC(rest,PreImagesRepresentativeNC(iso,x))); # evaluate relators pool:=List(RelatorsOfFpGroup(Range(iso)), x->MappedWord(x,FreeGeneratorsOfFpGroup(Range(iso)),pregens)); @@ -91,7 +91,7 @@ local ffs,pcisom,rest,kpc,k,x,ker,r,pool,i,xx,pregens,iso; iso:=IsomorphismFpGroup(Image(rest,U)); pregens:=List(GeneratorsOfGroup(Range(iso)),x-> - PreImagesRepresentative(rest,PreImagesRepresentative(iso,x))); + PreImagesRepresentativeNC(rest,PreImagesRepresentativeNC(iso,x))); # evaluate relators pool:=List(RelatorsOfFpGroup(Range(iso)), x->MappedWord(x,FreeGeneratorsOfFpGroup(Range(iso)),pregens)); @@ -135,7 +135,7 @@ local ffs,pcisom,rest,kpc,k,x,ker,r,pool,i,xx,pregens,iso; # od; SetSize(U,Size(Image(rest))*Size(kpc)); k:=InducedPcgs(FamilyPcgs(Image(pcisom)),kpc); - k:=List(k,x->PreImagesRepresentative(pcisom,x)); + k:=List(k,x->PreImagesRepresentativeNC(pcisom,x)); k:=InducedPcgsByPcSequenceNC(ffs.pcgs,k); ker:=SubgroupNC(G,k); SetSize(ker,Size(kpc)); @@ -257,7 +257,7 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom,subsz,pcimgs; pcimgs:=List(ipcgs,x->ImagesRepresentative(ffs.pcisom,x)); ker:=SubgroupNC(G,List(MinimalGeneratingSet(Group(pcimgs,One(Range(ffs.pcisom)))), - x->PreImagesRepresentative(ffs.pcisom,x))); + x->PreImagesRepresentativeNC(ffs.pcisom,x))); SetPcgs(ker,ipcgs); if Length(ipcgs)=0 then SetSize(ker,1); @@ -916,8 +916,9 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs,gens; s:=SylowSubgroup(Image(hom),prime); fphom:=IsomorphismFpGroup(s); fp:=Image(fphom); - sf:=List(GeneratorsOfGroup(Image(fphom)),x->PreImagesRepresentative(fphom,x)); - sg:=List(sf,x->PreImagesRepresentative(hom,x)); + sf:=List(GeneratorsOfGroup(Image(fphom)), + x->PreImagesRepresentativeNC(fphom,x)); + sg:=List(sf,x->PreImagesRepresentativeNC(hom,x)); sp:=[]; RUN_IN_GGMBI:=true; # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(Group(sg,One(G)),fp,sg, @@ -1194,7 +1195,7 @@ local s,d,c,act,o,i,j,h,p,hf,img,n,k,ns,all,hl,hcomp, norm:=n); for j in [2..Length(i)] do c[i[j]]:=rec(orbit:=i,orbitpos:=j, - rep:=PreImagesRepresentative(act, + rep:=PreImagesRepresentativeNC(act, RepresentativeAction(Image(act),i[1],i[j])), component:=d[i[j]],hall:=h, norm:=n); od; @@ -1232,7 +1233,7 @@ local s,d,c,act,o,i,j,h,p,hf,img,n,k,ns,all,hl,hcomp, fp:=Range(fphom); gens:=MappingGeneratorsImages(fphom); imgs:=gens[2];gens:=gens[1]; - gens:=List(gens,x->PreImagesRepresentative(act,x)); + gens:=List(gens,x->PreImagesRepresentativeNC(act,x)); # adapt to normalize B gens:=List(gens,x->x/RepresentativeAction(t,b^x,b)); @@ -1280,7 +1281,7 @@ local s,d,c,act,o,i,j,h,p,hf,img,n,k,ns,all,hl,hcomp, fp:=Image(fphom); gens:=MappingGeneratorsImages(fphom); imgs:=gens[2];gens:=gens[1]; - gens:=List(gens,x->PreImagesRepresentative(hom,x)); + gens:=List(gens,x->PreImagesRepresentativeNC(hom,x)); fi; # now run through the candidates for Hall in S @@ -1408,8 +1409,9 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs, for s in HallsFittingFree(Image(hom),pi) do fphom:=IsomorphismFpGroup(s); fp:=Image(fphom); - sf:=List(GeneratorsOfGroup(Image(fphom)),x->PreImagesRepresentative(fphom,x)); - sg:=List(sf,x->PreImagesRepresentative(hom,x)); + sf:=List(GeneratorsOfGroup(Image(fphom)), + x->PreImagesRepresentativeNC(fphom,x)); + sg:=List(sf,x->PreImagesRepresentativeNC(hom,x)); sp:=[]; RUN_IN_GGMBI:=true; # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(Group(sg,One(G)),fp,sg, diff --git a/lib/fldabnum.gi b/lib/fldabnum.gi index 5902772c5e..6fb312be2d 100644 --- a/lib/fldabnum.gi +++ b/lib/fldabnum.gi @@ -1918,9 +1918,9 @@ InstallMethod( PreImageElm, ############################################################################# ## -#M PreImagesElm( , ) . . . . . . for autom. of ab. number fields +#M PreImagesElmNC( , ) . . . . . . for autom. of ab. number fields ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for ANF automorphism and scalar", FamRangeEqFamElm, [ IsFieldHomomorphism and IsANFAutomorphismRep, IsScalar ], @@ -1932,9 +1932,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . . . . . for autom. of ab. number fields +#M PreImagesSetNC( , ) . . . . . for autom. of ab. number fields ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for ANF automorphism and scalar", CollFamRangeEqFamElms, [ IsFieldHomomorphism and IsANFAutomorphismRep, IsField ], @@ -1945,9 +1945,9 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) . for autom. of ab. number fields +#M PreImagesRepresentativeNC( , ) for autom. of ab. number fields ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for ANF automorphism and scalar", FamRangeEqFamElm, [ IsFieldHomomorphism and IsANFAutomorphismRep, IsScalar ], diff --git a/lib/ghom.gi b/lib/ghom.gi index bc217f1e32..8047a39206 100644 --- a/lib/ghom.gi +++ b/lib/ghom.gi @@ -253,9 +253,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . via images -## -InstallMethod( PreImagesRepresentative, "for PBG-Hom", FamRangeEqFamElm, +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . via images + +InstallMethod( PreImagesRepresentativeNC, "for PBG-Hom", FamRangeEqFamElm, [ IsPreimagesByAsGroupGeneralMappingByImages, IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) @@ -264,7 +264,7 @@ function( hom, elm ) # group return ImagesRepresentative( RestrictedInverseGeneralMapping( hom ), elm ); else - return PreImagesRepresentative( AsGroupGeneralMappingByImages( hom ), elm ); + return PreImagesRepresentativeNC( AsGroupGeneralMappingByImages( hom ), elm ); fi; end ); @@ -875,9 +875,9 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . . for GHBI +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . . . for GHBI ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for GHBI and mult.-elm.-with-inverse", FamRangeEqFamElm, [ IsGroupGeneralMappingByImages, @@ -1225,9 +1225,9 @@ InstallMethod( ImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . for conjugator isomorphism +#M PreImagesRepresentativeNC( , ) . . . . for conjugator isomorphism ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for conjugator isomorphism", FamRangeEqFamElm, [ IsConjugatorIsomorphism, IsMultiplicativeElementWithInverse ], 0, @@ -1238,9 +1238,9 @@ InstallMethod( PreImagesRepresentative, ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . . for conjugator isomorphism +#M PreImagesSetNC( , ) . . . . . . . . . for conjugator isomorphism ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for conjugator isomorphism, and group", CollFamRangeEqFamElms, [ IsConjugatorIsomorphism, IsGroup ], 0, diff --git a/lib/ghomfp.gi b/lib/ghomfp.gi index fcc83630d9..fb2ce5f073 100644 --- a/lib/ghomfp.gi +++ b/lib/ghomfp.gi @@ -441,7 +441,7 @@ local q,r,tg,dtg,pemb,ugens,g,gi,d,o,gens,genims,i,gr,img,l,mapi; #better: orbit algo #r:=ShallowCopy(RightTransversal(q,qu)); #Sort(r,function(a,b) return 1^a<1^b;end); - #r:=List(r,i->PreImagesRepresentative(beta,i)); + #r:=List(r,i->PreImagesRepresentativeNC(beta,i)); # compute transversal with short words from orbit algorithm on points o:=[1]; @@ -527,9 +527,9 @@ end); ############################################################################# ## -#M PreImagesSet( , ) +#M PreImagesSetNC( , ) ## -InstallMethod( PreImagesSet, "map from (sub)group of fp group", +InstallMethod( PreImagesSetNC, "map from (sub)group of fp group", CollFamRangeEqFamElms, [ IsFromFpGroupHomomorphism,IsGroup ],0, function(hom,u) @@ -718,9 +718,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative +#M PreImagesRepresentativeNC ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "hom. to standard generators of fp group, using 'MappedWord'", FamRangeEqFamElm, [IsToFpGroupHomomorphismByImages,IsMultiplicativeElementWithInverse], @@ -1282,7 +1282,7 @@ local v,aiu,aiv,G,primes,irrel,ma,mau,a,k,gens,imgs,q,dec,deco,piv,co; fi; gens:=SmallGeneratingSet(a); - imgs:=List(gens,x->Image(mau,Image(hom,PreImagesRepresentative(ma,x)))); + imgs:=List(gens,x->Image(mau,Image(hom,PreImagesRepresentativeNC(ma,x)))); q:=GroupHomomorphismByImages(a,Image(mau),gens,imgs); k:=KernelOfMultiplicativeGeneralMapping(q); @@ -1293,7 +1293,7 @@ local v,aiu,aiv,G,primes,irrel,ma,mau,a,k,gens,imgs,q,dec,deco,piv,co; dec:=EpimorphismFromFreeGroup(Group(gens)); deco:=function(x) local i; - x:=ExponentSums(PreImagesRepresentative(dec,x)); + x:=ExponentSums(PreImagesRepresentativeNC(dec,x)); for i in [1..Length(aiv)] do x[i]:=x[i] mod aiv[i]; od; @@ -1330,7 +1330,7 @@ local hom,pcgs,impcgs; impcgs:=FamilyPcgs(Image(hom,M)); pcgs:=PcgsByPcSequenceCons(IsPcgsDefaultRep,IsModuloPcgsFpGroupRep, ElementsFamily(FamilyObj(M)), - List(impcgs,i->PreImagesRepresentative(hom,i)), + List(impcgs,i->PreImagesRepresentativeNC(hom,i)), [] ); pcgs!.hom:=hom; diff --git a/lib/ghompcgs.gi b/lib/ghompcgs.gi index f17db8b36c..78ba75b339 100644 --- a/lib/ghompcgs.gi +++ b/lib/ghompcgs.gi @@ -503,9 +503,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . via images +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . via images ## -InstallMethod( PreImagesRepresentative, "method for pcgs hom", +InstallMethod( PreImagesRepresentativeNC, "method for pcgs hom", FamRangeEqFamElm, [ IsToPcGroupHomomorphismByImages,IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) @@ -627,9 +627,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . via depth map +#M PreImagesRepresentativeNC( , ) . . . . . . . . . via depth map ## -InstallMethod( PreImagesRepresentative, FamRangeEqFamElm, +InstallMethod( PreImagesRepresentativeNC, FamRangeEqFamElm, [ IsPcgsToPcgsHomomorphism,IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) local exp; diff --git a/lib/ghomperm.gi b/lib/ghomperm.gi index 2f103a6a37..7bf4a40a70 100644 --- a/lib/ghomperm.gi +++ b/lib/ghomperm.gi @@ -11,9 +11,9 @@ ############################################################################# ## -#M PreImagesSet( , ) . for s.p. gen. mapping resp. mult. & inv. +#M PreImagesSetNC( , ) . for s.p. gen. mapping resp. mult. & inv. ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for permgroup homs", CollFamRangeEqFamElms, [ IsPermGroupHomomorphism, IsGroup ], @@ -22,7 +22,7 @@ local genpreimages, pre,kg,sz,ol,orb,pos,dom,one; genpreimages:=GeneratorsOfMagmaWithInverses( elms ); genpreimages:= List(genpreimages, - gen -> PreImagesRepresentative( map, gen ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; @@ -1152,7 +1152,7 @@ local r, fgens, gens, kg; fi; fgens:=ShallowCopy(GeneratorsOfGroup(r)); gens:=List(fgens, - i->PreImagesRepresentative(hom2,PreImagesRepresentative(hom1,i))); + i->PreImagesRepresentativeNC(hom2,PreImagesRepresentativeNC(hom1,i))); kg:=GeneratorsOfGroup(KernelOfMultiplicativeGeneralMapping(hom2)); Append(gens,kg); Append(fgens,List(kg,i->One(r))); @@ -1162,9 +1162,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . for perm group range +#M PreImagesRepresentativeNC( , ) . . . . . for perm group range ## -InstallMethod( PreImagesRepresentative, FamRangeEqFamElm, +InstallMethod( PreImagesRepresentativeNC, FamRangeEqFamElm, [ IsToPermGroupGeneralMappingByImages, IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) @@ -1562,9 +1562,9 @@ InstallMethod( ImagesSource,"constituent homomorphism",true, ############################################################################# ## -#M PreImagesRepresentative( , ) +#M PreImagesRepresentativeNC( , ) ## -InstallMethod( PreImagesRepresentative,"constituent homomorphism", +InstallMethod( PreImagesRepresentativeNC,"constituent homomorphism", FamRangeEqFamElm,[IsConstituentHomomorphism,IsPerm], 0, function( hom, elm ) local D,DP; @@ -1579,9 +1579,9 @@ end); ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . . . . . . . . . for const hom +#M PreImagesSetNC( , ) . . . . . . . . . . . . . . . for const hom ## -InstallMethod( PreImagesSet, "constituent homomorphism",CollFamRangeEqFamElms, +InstallMethod( PreImagesSetNC, "constituent homomorphism",CollFamRangeEqFamElms, [ IsConstituentHomomorphism, IsPermGroup ], 0, function( hom, I ) local H, # preimage of , result @@ -1594,7 +1594,7 @@ InstallMethod( PreImagesSet, "constituent homomorphism",CollFamRangeEqFamElms, # create the preimage group H := EmptyStabChain( [ ], One( Source( hom ) ) ); S := ConjugateStabChain( StabChainMutable( I ), H, x -> - PreImagesRepresentative( hom, x ), hom!.conperm ^ -1 ); + PreImagesRepresentativeNC( hom, x ), hom!.conperm ^ -1 ); T := H; while IsBound( T.stabilizer ) do AddGeneratorsExtendSchreierTree( T, GeneratorsOfGroup( K ) ); @@ -1817,9 +1817,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . for blocks hom +#M PreImagesRepresentativeNC( , ) . . . . . . . . for blocks hom ## -InstallMethod( PreImagesRepresentative, "blocks homomorphism", +InstallMethod( PreImagesRepresentativeNC, "blocks homomorphism", FamRangeEqFamElm, [ IsBlocksHomomorphism, IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) @@ -1869,9 +1869,9 @@ end) ; ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . . . . . . . . for blocks hom +#M PreImagesSetNC( , ) . . . . . . . . . . . . . . for blocks hom ## -InstallMethod( PreImagesSet, CollFamRangeEqFamElms, +InstallMethod( PreImagesSetNC, CollFamRangeEqFamElms, [ IsBlocksHomomorphism, IsPermGroup ], 0, function( hom, I ) local H; # preimage of under , result @@ -1905,7 +1905,7 @@ InstallGlobalFunction( PreImageSetStabBlocksHomomorphism, function( hom, I ) H := PreImageSetStabBlocksHomomorphism( hom, I.stabilizer ); ChangeStabChain( H, [ pnt ], false ); for gen in I.generators do - pre := PreImagesRepresentative( hom, gen ); + pre := PreImagesRepresentativeNC( hom, gen ); if not IsBound( H.translabels[ pnt ^ pre ] ) then AddGeneratorsExtendSchreierTree( H, [ pre ] ); fi; diff --git a/lib/gpfpiso.gi b/lib/gpfpiso.gi index 202d9419a7..8095dd5be1 100644 --- a/lib/gpfpiso.gi +++ b/lib/gpfpiso.gi @@ -91,7 +91,7 @@ local l,iso,fp,stbc,gens; fp:=IsomorphismFpGroup(l); iso:=GroupHomomorphismByImagesNC(G,Range(fp), List(MappingGeneratorsImages(fp)[1], - i->PreImagesRepresentative(iso,i)), + i->PreImagesRepresentativeNC(iso,i)), MappingGeneratorsImages(fp)[2]); SetIsBijective(iso,true); return iso; @@ -171,8 +171,8 @@ function( G, str ) IsNaturalAlternatingGroup(H); new:=IsomorphismFpGroup(H,"@"); gensH:=List(GeneratorsOfGroup(Image(new)), - i->PreImagesRepresentative(new,i)); - preiH := List( gensH, x -> PreImagesRepresentative( hom, x ) ); + i->PreImagesRepresentativeNC(new,i)); + preiH := List( gensH, x -> PreImagesRepresentativeNC( hom, x ) ); c := Length( gensH ); @@ -190,7 +190,7 @@ function( G, str ) w := MappedWord( rel, gensT, gensE{[1..c]} ); t := MappedWord( rel, gensT, imgsE{[1..c]} ); if not t = One( G ) then - t := PreImagesRepresentative( free, t ); + t := PreImagesRepresentativeNC( free, t ); t := MappedWord( t, gensF, gensE{[c+1..n+c]} ); else t := One( E ); @@ -204,7 +204,7 @@ function( G, str ) w := Comm( gensE[c+j], gensE[i] ); t := Comm( imgsE[c+j], imgsE[i] ); if not t = One( G ) then - t := PreImagesRepresentative( free, t ); + t := PreImagesRepresentativeNC( free, t ); t := MappedWord( t, gensF, gensE{[c+1..n+c]} ); else t := One( E ); @@ -293,7 +293,7 @@ function(g,str,N) gens:=Union(gens,Union(List(ser,SmallGeneratingSet))); fi; if f<>g then - gens:=List(gens,x->PreImagesRepresentative(hom,x)); + gens:=List(gens,x->PreImagesRepresentativeNC(hom,x)); ser:=List(ser,x->PreImage(hom,x)); fi; # change generators to make split @@ -397,7 +397,8 @@ function(g,str,N) fgens:=GeneratorsOfGroup(f); auts:=List(GeneratorsOfGroup(g),i-> GroupHomomorphismByImagesNC(f,f,fgens, - List(fgens,j->Image(hom,PreImagesRepresentative(hom,j)^i)):noassert)); + List(fgens, + j->Image(hom,PreImagesRepresentativeNC(hom,j)^i)):noassert)); for j in auts do SetIsBijective(j,true); od; @@ -426,7 +427,7 @@ function(g,str,N) else a:=IsomorphismFpGroup(sf:noassert); fi; - ad:=List(GeneratorsOfGroup(Range(a)),i->PreImagesRepresentative(a,i)); + ad:=List(GeneratorsOfGroup(Range(a)),i->PreImagesRepresentativeNC(a,i)); lad:=Length(ad); n:=Length(orb); @@ -461,7 +462,7 @@ function(g,str,N) fp:=fg/rels; a:=GroupHomomorphismByImagesNC(f,fp,fgens,GeneratorsOfGroup(fp):noassert); fi; - Append(gens,List(fgens,i->PreImagesRepresentative(hom,i))); + Append(gens,List(fgens,i->PreImagesRepresentativeNC(hom,i))); # here we really want a composed homomorphism, to avoid extra work for # a new stabilizer chain @@ -640,7 +641,7 @@ local fpq, qgens, qreps, fpqg, rels, pcgs, p, f, qimg, idx, nimg, decomp, ngen, fp, hom2, di, source, dih, dec, i, j; fpq:=Range(hom); qgens:=GeneratorsOfGroup(fpq); - qreps:=List(qgens,i->PreImagesRepresentative(hom,i)); + qreps:=List(qgens,i->PreImagesRepresentativeNC(hom,i)); fpqg:=FreeGeneratorsOfFpGroup(fpq); rels:=[]; if IsModuloPcgs(mnsf) then @@ -694,7 +695,7 @@ local fpq, qgens, qreps, fpqg, rels, pcgs, p, f, qimg, idx, nimg, decomp, ngen:=FreeGeneratorsOfFpGroup(p); # This is not really a pcgs, but treated as layer generators the same # way, thus use the same variable name - pcgs:=List(GeneratorsOfGroup(p),i->PreImagesRepresentative(mnsf,i)); + pcgs:=List(GeneratorsOfGroup(p),i->PreImagesRepresentativeNC(mnsf,i)); f:=FreeGroup(Length(fpqg)+Length(pcgs)); qimg:=GeneratorsOfGroup(f){[1..Length(fpqg)]}; idx:=[Length(fpqg)+1..Length(fpqg)+Length(pcgs)]; @@ -966,7 +967,7 @@ function( G, series, str ) gensH := GeneratorsOfGroup( H ); gensH := Filtered( gensH, x -> x <> One(H) ); - preiH := List( gensH, x -> PreImagesRepresentative( hom, x ) ); + preiH := List( gensH, x -> PreImagesRepresentativeNC( hom, x ) ); c := Length( gensH ); # compute presentation of H @@ -989,7 +990,7 @@ function( G, series, str ) w := MappedWord( rel, gensT, gensE{[1..c]} ); t := MappedWord( rel, gensT, imgsE{[1..c]} ); if not t = One( G ) then - t := PreImagesRepresentative( free, t ); + t := PreImagesRepresentativeNC( free, t ); t := MappedWord( t, gensF, gensE{[c+1..n+c]} ); else t := One( E ); @@ -1003,7 +1004,7 @@ function( G, series, str ) w := Comm( gensE[c+j], gensE[i] ); t := Comm( imgsE[c+j], imgsE[i] ); if not t = One( G ) then - t := PreImagesRepresentative( free, t ); + t := PreImagesRepresentativeNC( free, t ); t := MappedWord( t, gensF, gensE{[c+1..n+c]} ); else t := One( E ); @@ -1228,8 +1229,8 @@ local iso,fp,dec,homs,mos,i,j,ffp,imo,m,k,gens,fm,mgens,rules, for r in Rules(k) do left:=MappedWord(r[1],FreeGeneratorsOfFpMonoid(m),monreps); right:=MappedWord(r[2],FreeGeneratorsOfFpMonoid(m),monreps); - diff:=LeftQuotient(PreImagesRepresentative(iso,right), - PreImagesRepresentative(iso,left)); + diff:=LeftQuotient(PreImagesRepresentativeNC(iso,right), + PreImagesRepresentativeNC(iso,left)); diff:=ImagesRepresentative(iso,diff); left:=MappedWord(r[1],FreeGeneratorsOfFpMonoid(m),monreal); @@ -1248,7 +1249,7 @@ local iso,fp,dec,homs,mos,i,j,ffp,imo,m,k,gens,fm,mgens,rules, if reduce(mgens[k])=mgens[k] then right:=fmgens[j]^-1*fmgens[k]*fmgens[j]; #collect - right:=ImagesRepresentative(iso,PreImagesRepresentative(iso,right)); + right:=ImagesRepresentative(iso,PreImagesRepresentativeNC(iso,right)); right:=Product(List(LetterRepAssocWord(UnderlyingElement(right)), x->mgens[Position(nums,x)])); right:=reduce(mgens[j]*right); @@ -1320,7 +1321,7 @@ local pcgs,iso,fp,i,j,gens,numi,ord,fm,fam,mword,k,r,addrule,a,e,m; pcgs:=Pcgs(G); iso:=IsomorphismFpGroup(G); fp:=Range(iso); - if List(GeneratorsOfGroup(fp),x->PreImagesRepresentative(iso,x))<>pcgs then + if List(GeneratorsOfGroup(fp),x->PreImagesRepresentativeNC(iso,x))<>pcgs then Error("pcgs"); fi; gens:=[]; @@ -1520,7 +1521,7 @@ local iso,n,fn,sz,bigcount,tryweyl; iso:=IsomorphismGroups(G,P); if iso<>fail then P:=List(GeneratorsOfGroup(H), - x->PreImagesRepresentative(iso,ImagesRepresentative(isp,x))); + x->PreImagesRepresentativeNC(iso,ImagesRepresentative(isp,x))); iso:=GroupHomomorphismByImagesNC(G,H,P,GeneratorsOfGroup(H)); fi; return iso; @@ -1728,13 +1729,13 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, # force going to pc group, as this will give better ordering isob:=GroupHomomorphismByFunction(borel,Range(cb.fphom), x->ImagesRepresentative(cb.fphom,ImagesRepresentative(pciso,x)), - x->PreImagesRepresentative(pciso,PreImagesRepresentative(cb.fphom,x))); + x->PreImagesRepresentativeNC(pciso,PreImagesRepresentativeNC(cb.fphom,x))); b:=Range(isob); wgens:=GeneratorsOfGroup(weyl); - bgens:=List(GeneratorsOfGroup(b),x->PreImagesRepresentative(isob,x)); + bgens:=List(GeneratorsOfGroup(b),x->PreImagesRepresentativeNC(isob,x)); if newstyle and bgens<>GeneratorsOfGroup(borel) then Error("gens");fi; bpairs:=Concatenation(List(bgens,x->[x,x^-1])); @@ -1879,7 +1880,7 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, x:=UnderlyingElement(ImagesRepresentative(cb.monhom,x)); x:=reduce(x,RelationsOfFpMonoid(monoid),mdag,fail); x:=ElementOfFpMonoid(FamilyObj(One(monoid)),x); - return PreImagesRepresentative(cb.monhom,x); + return PreImagesRepresentativeNC(cb.monhom,x); end; mdag:=EmptyKBDAG(Union(List(FreeGeneratorsOfFpMonoid(monoid), @@ -1924,7 +1925,7 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, x:=UnderlyingElement(ImagesRepresentative(cs.monhom,x)); x:=reduce(x,RelationsOfFpMonoid(Range(cs.monhom)),wdag,fail); x:=ElementOfFpMonoid(FamilyObj(One(Range(cs.monhom))),x); - return PreImagesRepresentative(cs.monhom,x); + return PreImagesRepresentativeNC(cs.monhom,x); end; wdag:=EmptyKBDAG(Union(List(FreeGeneratorsOfFpMonoid(Range(cs.monhom)), @@ -1966,7 +1967,7 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, a:=Group(SmallGeneratingSet(group)); # so nothing stores csetperm:=List(GeneratorsOfGroup(a),x->Permutation(x,rt,OnRight)); iso:=EpimorphismFromFreeGroup(a); - csetperm:=List(bgens,x->MappedWord(PreImagesRepresentative(iso,x), + csetperm:=List(bgens,x->MappedWord(PreImagesRepresentativeNC(iso,x), MappingGeneratorsImages(iso)[1],csetperm)); act:=Group(csetperm,()); @@ -2014,7 +2015,7 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, a:=PositionCanonical(rt,elm); b:=rti[a]; rep:=RepresentativeAction(Image(bhom),a,dcnums[b][1]); - rep:=PreImagesRepresentative(bhom,rep); + rep:=PreImagesRepresentativeNC(bhom,rep); if single then a:=[CanonicalRightCosetElement(ac[1],rt[dcnums[b][1]]),rep]; else @@ -2074,9 +2075,8 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, # a:=Group(SmallGeneratingSet(group)); # so nothing stores # csetperm:=List(GeneratorsOfGroup(a),x->Permutation(x,rt,OnRight)); # iso:=EpimorphismFromFreeGroup(a); -# csetperm:=List(bgens,x->MappedWord(PreImagesRepresentative(iso,x),MappingGeneratorsImages(iso)[1],csetperm)); -# act:=Group(csetperm,()); -# +# csetperm:=List(bgens,x->MappedWord(PreImagesRepresentativeNC(iso,x), +# MappingGeneratorsImages(iso)[1],csetperm)); act:=Group(csetperm,()); # bhom:=GroupHomomorphismByImagesNC(borel,act,bgens,csetperm); # #Assert(0,bhom<>fail); # @@ -2119,7 +2119,7 @@ local isob,isos,iso,gens,a,rels,l,i,j,bgens,cb,cs,b,f,k,w,monoid, # pos:=rti[PositionCanonical(rt,elm)]; # #rep:=RepresentativeAction(borel,PositionCanonical(rt,elm), # # PositionCanonical(rt,dcreps[pos]),bgens,csetperm,OnPoints); -# rep:=PreImagesRepresentative(bhom, +# rep:=PreImagesRepresentativeNC(bhom, # RepresentativeAction(Range(bhom),PositionCanonical(rt,elm), # PositionCanonical(rt,dcreps[pos]))); # rep:=[elm*rep/dcreps[pos],dcreps[pos],rep^-1]; @@ -2441,7 +2441,7 @@ if rule[1]=rule[2] then return;fi; else # BN-style reductions - pcgs:=List(GeneratorsOfGroup(b),x->PreImagesRepresentative(isob,x)); + pcgs:=List(GeneratorsOfGroup(b),x->PreImagesRepresentativeNC(isob,x)); # remove powers pcgs:=pcgs{ Filtered([1..Length(pcgs)],i->not ForAny([1..i-1], @@ -2455,7 +2455,7 @@ if rule[1]=rule[2] then return;fi; # which elements b*i can we write as i*\tilde b. Then b^i=\tilde b, that # is b\in B\cvap B^(i^-1) - pri:=PreImagesRepresentative(isos,i); + pri:=PreImagesRepresentativeNC(isos,i); stb:=Intersection(borel,borel^(pri^-1)); Info(InfoFpGroup,2,i," ",Size(stb)); @@ -2511,14 +2511,14 @@ if rule[1]=rule[2] then return;fi; Info(InfoFpGroup,3,"borelrun ",Position(wo,i)," of ",Length(wo)); # rewrite i*b*j as \tilde b*k*\hat b. - pri:=PreImagesRepresentative(isos,i); + pri:=PreImagesRepresentativeNC(isos,i); stb:=Intersection(borel^pri,borel); for j in wo do Info(InfoFpGroup,2,"DC:",i,", ",j," from ",Length(rels)); for k in borelelm do #RightTransversal(borel,stb) do - a:=PreImagesRepresentative(isos,i)*k* - PreImagesRepresentative(isos,j); + a:=PreImagesRepresentativeNC(isos,i)*k* + PreImagesRepresentativeNC(isos,j); a:=decomp(a); a:=[nofob(ImagesRepresentative(isob,a[1])), nofow(ImagesRepresentative(isos,a[2])), @@ -2684,7 +2684,7 @@ end); # if List(mg,x->LetterRepAssocWord(UnderlyingElement(x)))<> # List([1..Length(mg)],x->[x]) then Error("gens!"); fi; # pre:=List(mg,x->LetterRepAssocWord(UnderlyingElement( -# PreImagesRepresentative(miso,x)))); +# PreImagesRepresentativeNC(miso,x)))); # if ForAny(pre,x->Length(x)<>1) then Error("double");fi; # Add(l,Concatenation(pre)); # if IsBound(m!.rewritingSystem) then @@ -2896,7 +2896,7 @@ local d,f,group,act,g,sy,b,c,borel,weyl,a,i,iso,ucs,gens,gl; fi; c:=c[1]; a:=SubgroupNC(group,List(GeneratorsOfGroup(weyl), - x->PreImagesRepresentative(c,x))); + x->PreImagesRepresentativeNC(c,x))); Size(a); a!.epiweyl:=weyl; weyl:=a; diff --git a/lib/gpprmsya.gi b/lib/gpprmsya.gi index a88508a2bb..d0af65692e 100644 --- a/lib/gpprmsya.gi +++ b/lib/gpprmsya.gi @@ -1265,7 +1265,7 @@ syll, act, typ, sel, bas, wdom, comp, lperm, other, away, i, j,b0,opg,bp; w:=AutomorphismGroup(b); opg:=NaturalHomomorphismByNormalSubgroupNC(w, InnerAutomorphismsAutomorphismGroup(w)); - ll:=List(AsSSortedList(Image(opg)),x->PreImagesRepresentative(opg,x)); + ll:=List(AsSSortedList(Image(opg)),x->PreImagesRepresentativeNC(opg,x)); ll:=Filtered(ll,IsConjugatorAutomorphism); ll:=List(ll,ConjugatorInnerAutomorphism); pg:=b; diff --git a/lib/gprd.gi b/lib/gprd.gi index e32bf13af7..49b091d983 100644 --- a/lib/gprd.gi +++ b/lib/gprd.gi @@ -715,7 +715,7 @@ InstallGlobalFunction(InnerSubdirectProducts2,function( D, U, V ) # and obtain double coset reps reps := List( DoubleCosets( P, autU, autV ), Representative ); - reps := List( reps, x -> PreImagesRepresentative( gamma, x ) ); + reps := List( reps, x -> PreImagesRepresentativeNC( gamma, x ) ); # loop over automorphisms for rep in reps do @@ -724,9 +724,9 @@ InstallGlobalFunction(InnerSubdirectProducts2,function( D, U, V ) gens := Concatenation( GeneratorsOfGroup( N ), GeneratorsOfGroup( M ) ); for r in GeneratorsOfGroup( UN ) do - g := PreImagesRepresentative( pair[1], r ); + g := PreImagesRepresentativeNC( pair[1], r ); h := Image( iso, Image( rep, r ) ); - h := PreImagesRepresentative( pair[2], h ); + h := PreImagesRepresentativeNC( pair[2], h ); Add( gens, g * h ); od; S := SubgroupNC( D, gens ); @@ -1094,7 +1094,7 @@ local info,map,U,mapfun,P; function(elm) elm:=elm![n]; if n>info.degI then - elm:=PreImagesRepresentative(info.alpha,elm); + elm:=PreImagesRepresentativeNC(info.alpha,elm); fi; return elm; end); @@ -1118,7 +1118,7 @@ local info,map,np; map:=GroupHomomorphismByFunction(G,info.groups[2], function(elm) - return PreImagesRepresentative(info.alpha,elm![np]); + return PreImagesRepresentativeNC(info.alpha,elm![np]); end, false, # not bijective function(elm) @@ -1179,7 +1179,7 @@ local giso,niso,P,gens,a,Go,No,i; N:=Image(niso,N); gens:=[]; for i in GeneratorsOfGroup(G) do - i:=Image(aut,PreImagesRepresentative(giso,i)); + i:=Image(aut,PreImagesRepresentativeNC(giso,i)); i:=InducedAutomorphism(niso,i); Add(gens,i); od; @@ -1220,9 +1220,9 @@ local Go,No,giso,niso,FG,GP,FN,NP,F,GI,NI,rels,i,j,P; N:=Image(niso,N); FG:=FreeGeneratorsOfFpGroup(G); - GP:=List(GeneratorsOfGroup(G),x->PreImagesRepresentative(giso,x)); + GP:=List(GeneratorsOfGroup(G),x->PreImagesRepresentativeNC(giso,x)); FN:=FreeGeneratorsOfFpGroup(N); - NP:=List(GeneratorsOfGroup(N),x->PreImagesRepresentative(niso,x)); + NP:=List(GeneratorsOfGroup(N),x->PreImagesRepresentativeNC(niso,x)); F:=FreeGroup(List(Concatenation(FG,FN),String)); GI:=GeneratorsOfGroup(F){[1..Length(FG)]}; diff --git a/lib/gprdmat.gi b/lib/gprdmat.gi index 2480d861d1..c582173350 100644 --- a/lib/gprdmat.gi +++ b/lib/gprdmat.gi @@ -143,9 +143,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative(,) . . . . . . . . . . . of embedding +#M PreImagesRepresentativeNC(,) . . . . . . . . . . . of embedding ## -InstallMethod(PreImagesRepresentative,"matrix direct product embedding", +InstallMethod(PreImagesRepresentativeNC,"matrix direct product embedding", FamRangeEqFamElm, [ IsEmbeddingDirectProductMatrixGroup, IsMultiplicativeElementWithInverse ], @@ -206,9 +206,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative(,) . . . . . . . . . . . of projection +#M PreImagesRepresentativeNC(,) . . . . . . . . . . . of projection ## -InstallMethod(PreImagesRepresentative,"matrix direct product projection", +InstallMethod(PreImagesRepresentativeNC,"matrix direct product projection", FamRangeEqFamElm, [ IsProjectionDirectProductMatrixGroup, IsMultiplicativeElementWithInverse ],0, @@ -382,9 +382,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . of embedding +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . of embedding ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "imprim matrix wreath product embedding", FamRangeEqFamElm, [ IsEmbeddingImprimitiveWreathProductMatrixGroup, IsMultiplicativeElementWithInverse ], 0, diff --git a/lib/gprdpc.gi b/lib/gprdpc.gi index 6994897c39..a17e46436a 100644 --- a/lib/gprdpc.gi +++ b/lib/gprdpc.gi @@ -421,7 +421,7 @@ local pg,ph,kg,kh,ig,ih,mg,mh,S,info; ig:=InducedPcgs(pg,kg); ih:=InducedPcgs(ph,kh); mg:=pg mod ig; - mh:=List(mg,i->PreImagesRepresentative(hh,Image(gh,i))); + mh:=List(mg,i->PreImagesRepresentativeNC(hh,Image(gh,i))); pg:=Concatenation(mg,ig,List(ih,i->One(G))); ph:=Concatenation(mh,List(ig,i->One(H)),ih); S:=SubdirProdPcGroups(G,pg,H,ph); diff --git a/lib/gprdperm.gi b/lib/gprdperm.gi index 327f812adc..36973b6b46 100644 --- a/lib/gprdperm.gi +++ b/lib/gprdperm.gi @@ -169,9 +169,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . of embedding +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . of embedding ## -InstallMethod( PreImagesRepresentative, "perm direct product embedding", +InstallMethod( PreImagesRepresentativeNC, "perm direct product embedding", FamRangeEqFamElm, [ IsEmbeddingDirectProductPermGroup, IsMultiplicativeElementWithInverse ], @@ -292,9 +292,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . of projection +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . of projection ## -InstallMethod( PreImagesRepresentative,"perm direct product projection", +InstallMethod( PreImagesRepresentativeNC,"perm direct product projection", FamRangeEqFamElm, [ IsProjectionDirectProductPermGroup, IsMultiplicativeElementWithInverse ], 0, @@ -388,7 +388,7 @@ InstallMethod( SubdirectProductOp,"permgroup", true, # over the generators of the kernel of $phi_2$. gens := []; for gen in GeneratorsOfGroup( G1 ) do - Add( gens, gen^emb1 * PreImagesRepresentative(phi2,gen^phi1)^emb2 ); + Add( gens, gen^emb1 * PreImagesRepresentativeNC(phi2,gen^phi1)^emb2 ); od; for gen in GeneratorsOfGroup( KernelOfMultiplicativeGeneralMapping( phi2 ) ) do @@ -466,9 +466,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . of projection +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . of projection ## -InstallMethod( PreImagesRepresentative,"perm subdirect product projection", +InstallMethod( PreImagesRepresentativeNC,"perm subdirect product projection", FamRangeEqFamElm, [ IsProjectionSubdirectProductPermGroup, IsMultiplicativeElementWithInverse ], 0, @@ -487,11 +487,11 @@ InstallMethod( PreImagesRepresentative,"perm subdirect product projection", # compute the preimage if 1 = prj!.component then - elm := img ^ info.perms[1] - * PreImagesRepresentative(phi2,img^phi1) ^ info.perms[2]; + elm := img ^ info.perms[1] + * PreImagesRepresentativeNC(phi2,img^phi1) ^ info.perms[2]; else - elm := img ^ info.perms[2] - * PreImagesRepresentative(phi1,img^phi2) ^ info.perms[1]; + elm := img ^ info.perms[2] + * PreImagesRepresentativeNC(phi1,img^phi2) ^ info.perms[1]; fi; # return the preimage @@ -799,9 +799,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . of embedding +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . of embedding ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "imprim perm wreath product embedding", FamRangeEqFamElm, [ IsEmbeddingImprimitiveWreathProductPermGroup, IsMultiplicativeElementWithInverse ], 0, diff --git a/lib/grp.gi b/lib/grp.gi index e46a66da6f..27f3644271 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -515,12 +515,12 @@ local p, hom, reps, as, a, b, ap, bp, ab, ap_bp, ab_p, g, h, H, N; reps := ConjugacyClasses(Image(hom)); reps := List(reps, Representative); reps := Filtered(reps, g -> not IsOne(g)); - reps := List(reps, g -> PreImagesRepresentative(hom, g)); + reps := List(reps, g -> PreImagesRepresentativeNC(hom, g)); as := List(reps, a -> [a,a^p]); for b in Image(hom) do - b := PreImagesRepresentative(hom, b); + b := PreImagesRepresentativeNC(hom, b); bp := b^p; for a in as do ap := a[2]; a := a[1]; @@ -1793,7 +1793,7 @@ local hom,gens; fi; hom:=IsomorphismPermGroup(G); gens:=IndependentGeneratorsOfAbelianGroup(Image(hom,G)); - return List(gens,i->PreImagesRepresentative(hom,i)); + return List(gens,i->PreImagesRepresentativeNC(hom,i)); end); @@ -2090,8 +2090,8 @@ InstallGlobalFunction( SupersolvableResiduumDefault, function( G ) # dual space of the module, w.r.t. `pcgs'. mg:= List( gs, x -> TransposedMat( List( pcgs, y -> one * ExponentsOfPcElement( pcgs, Image( ph, - Image( dh, PreImagesRepresentative( - dh, PreImagesRepresentative(ph,y) )^x ) ) )))^-1); + Image( dh, PreImagesRepresentativeNC( + dh, PreImagesRepresentativeNC(ph,y) )^x ) ) )))^-1); #T inverting is not necessary, or? mg:= Filtered( mg, x -> x <> idm ); @@ -2141,11 +2141,11 @@ InstallGlobalFunction( SupersolvableResiduumDefault, function( G ) # Construct a group element corresponding to # the basis element of the submodule. - Add( tmp2, PreImagesRepresentative( ph, + Add( tmp2, PreImagesRepresentativeNC( ph, PcElementByExponentsNC( pcgs, v ) ) ); od; - Add( ds, PreImagesSet( dh, + Add( ds, PreImagesSetNC( dh, SubgroupNC( df, Concatenation( tmp2, gen ) ) ) ); od; Append( gen, tmp2 ); @@ -2154,14 +2154,14 @@ InstallGlobalFunction( SupersolvableResiduumDefault, function( G ) else # cyclic case - Add( ds, PreImagesSet( dh, + Add( ds, PreImagesSetNC( dh, SubgroupNC( df, AsSSortedList( gen ) ) ) ); fi; od; # Generate the new candidate. - ssr:= PreImagesSet( dh, SubgroupNC( df, AsSSortedList( gen ) ) ); + ssr:= PreImagesSetNC( dh, SubgroupNC( df, AsSSortedList( gen ) ) ); fi; @@ -2392,7 +2392,7 @@ InstallMethod( UpperCentralSeriesOfGroup, Add( S, C ); Info( InfoGroup, 2, "UpperCentralSeriesOfGroup: step ", Length(S) ); hom := NaturalHomomorphismByNormalSubgroupNC( G, C ); - C := PreImages( hom, Centre( Image( hom ) ) ); + C := PreImagesNC( hom, Centre( Image( hom ) ) ); od; if Last(S) = G then @@ -3598,7 +3598,7 @@ InstallMethod( HallSubgroupOp, iso := IsomorphismPermGroup( G ); H := HallSubgroup( ImagesSource( iso ), pi ); - return PreImagesSet(iso, H); + return PreImagesSetNC(iso, H); end ); @@ -5337,7 +5337,7 @@ InstallMethod (MinimalNormalSubgroups, local hom; hom := NiceMonomorphism (grp); return List (MinimalNormalSubgroups (NiceObject (grp)), - N -> PreImagesSet (hom, N)); + N -> PreImagesSetNC(hom, N)); end); diff --git a/lib/grpcompl.gi b/lib/grpcompl.gi index 9adf68a175..5058cd8610 100644 --- a/lib/grpcompl.gi +++ b/lib/grpcompl.gi @@ -100,11 +100,11 @@ local G,N,K,s, h, q, fpi, factorpres, com, comgens, cen, ocrels, fpcgs, ncom, factorpres:=[FreeGeneratorsOfFpGroup(Range(fpi)), RelatorsOfFpGroup(Range(fpi)), List(GeneratorsOfGroup(Range(fpi)), - i->PreImagesRepresentative(fpi,i))]; - Assert(1,ForAll(factorpres[3],i->Image(h,PreImagesRepresentative(h,i))=i)); + i->PreImagesRepresentativeNC(fpi,i))]; + Assert(1,ForAll(factorpres[3],i->Image(h,PreImagesRepresentativeNC(h,i))=i)); # initialize com:=[G]; - comgens:=[List(factorpres[3],i->PreImagesRepresentative(h,i))]; + comgens:=[List(factorpres[3],i->PreImagesRepresentativeNC(h,i))]; cen:=[s[1]]; ocrels:=false; diff --git a/lib/grpfp.gi b/lib/grpfp.gi index 8f9d97983b..0546a1f18a 100644 --- a/lib/grpfp.gi +++ b/lib/grpfp.gi @@ -319,7 +319,7 @@ local fam,hom; if hom=fail then TryNextMethod(); fi; - return PreImagesRepresentative(hom,Random(rs, Image(hom,gp))); + return PreImagesRepresentativeNC(hom,Random(rs, Image(hom,gp))); end ); ############################################################################# @@ -2031,11 +2031,11 @@ local d,A,B,e1,e2,Ag,Bg,s,sg,u,v,map,sz; # instead of intersecting both preimages with s we only intersect the # intersection - u:=PreImagesSet(Projection(d,1),G!.sub); + u:=PreImagesSetNC(Projection(d,1),G!.sub); if HasSize(B) then SetSize(u,Size(G!.sub)*Size(B)); fi; - v:=PreImagesSet(Projection(d,2),H!.sub); + v:=PreImagesSetNC(Projection(d,2),H!.sub); if HasSize(A) then SetSize(v,Size(H!.sub)*Size(A)); fi; @@ -3167,7 +3167,7 @@ InstallMethod( LowIndexSubgroupsFpGroupIterator, local u, v; u:= NextIterator( iter!.fullIterator ); - v:= PreImagesSet( fpi, u ); + v:= PreImagesSetNC( fpi, u ); SetIndexInWholeGroup( v, IndexInWholeGroup( G ) * IndexInWholeGroup( u ) ); return v; @@ -3236,7 +3236,7 @@ local fpi,u,l,i,a; l:=[]; for i in u do - a:=PreImagesSet(fpi,i); + a:=PreImagesSetNC(fpi,i); SetIndexInWholeGroup(a,IndexInWholeGroup(G)*IndexInWholeGroup(i)); Add(l,a); od; @@ -3379,8 +3379,8 @@ local d,A,B,e1,e2,Ag,Bg,s,sg,u,v; # get both subgroups in the direct product via the projections # instead of intersecting both preimages with s we only intersect the # intersection - u:=PreImagesSet(Projection(d,1),G!.sub); - v:=PreImagesSet(Projection(d,2),H!.sub); + u:=PreImagesSetNC(Projection(d,1),G!.sub); + v:=PreImagesSetNC(Projection(d,2),H!.sub); u:=Intersection(u,s); v:=Intersection(v,s); @@ -5497,7 +5497,7 @@ local G,T,gens,g,reps,ng,index,i,j,ndef,n,iso; subgroup := U, iso:=iso, table:=T, - reps:=List(reps,i->PreImagesRepresentative(iso,i)))); + reps:=List(reps,i->PreImagesRepresentativeNC(iso,i)))); fi; ndef := 1; @@ -5517,7 +5517,7 @@ local G,T,gens,g,reps,ng,index,i,j,ndef,n,iso; subgroup := U, iso:=iso, table:=T, - reps:=List(reps,i->PreImagesRepresentative(iso,i)))); + reps:=List(reps,i->PreImagesRepresentativeNC(iso,i)))); fi; fi; od; diff --git a/lib/grplatt.gi b/lib/grplatt.gi index 5563219bf7..7419486e85 100644 --- a/lib/grplatt.gi +++ b/lib/grplatt.gi @@ -955,7 +955,7 @@ InstallGlobalFunction(LatticeViaRadical,function(arg) #k:=PreImage(hom,a); # make generators of homomorphism fit nicely to presentation gf:=IsomorphismFpGroup(a); - e:=List(MappingGeneratorsImages(gf)[1],x->PreImagesRepresentative(hom,x)); + e:=List(MappingGeneratorsImages(gf)[1],x->PreImagesRepresentativeNC(hom,x)); # we cannot guarantee that the parent contains e, so no # ClosureSubgroup. k:=ClosureGroup(KernelOfMultiplicativeGeneralMapping(hom),e); @@ -2779,7 +2779,7 @@ local fgi,inducedfactorautos,projs,psubs,info,n,l,nl,emb,u,pos, auts:=[]; for i in GeneratorsOfGroup(n) do aut:=GroupHomomorphismByImages(f,f,gens,List(gens,x-> - Image(hom,PreImagesRepresentative(hom,x)^i))); + Image(hom,PreImagesRepresentativeNC(hom,x)^i))); SetIsBijective(aut,true); Add(auts,aut); od; @@ -2856,7 +2856,7 @@ local fgi,inducedfactorautos,projs,psubs,info,n,l,nl,emb,u,pos, for dc in DoubleCosetRepsAndSizes(t[7],ind,t[8]) do # form the subdirect product g:=List(GeneratorsOfGroup(j[1]), - x->x*Image(emb,PreImagesRepresentative(t[5], + x->x*Image(emb,PreImagesRepresentativeNC(t[5], Image(dc[1],Image(iso,x))) )); Append(g,List(GeneratorsOfGroup(t[1]),x->Image(emb,x))); g:=Subgroup(D,g); diff --git a/lib/grpmat.gi b/lib/grpmat.gi index 5766951a76..17eae4f5e0 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -623,7 +623,7 @@ local gens,s,dom,mon,no; # call the recursive function to do the work gens:= SCMinSmaGens( no, s, [], One( no ), true ).gens; SetMinimalStabChain(G,s); - return List(gens,i->PreImagesRepresentative(mon,i)); + return List(gens,i->PreImagesRepresentativeNC(mon,i)); end); ############################################################################# @@ -660,7 +660,7 @@ local s,dom,mon, img; i->Position(HomeEnumerator(dom),i)))); # call the recursive function to do the work s:= LargestElementStabChain( s, One( img ) ); - return PreImagesRepresentative(mon,s); + return PreImagesRepresentativeNC(mon,s); end); ############################################################################# @@ -699,7 +699,7 @@ local mon,dom,S,o,oimgs,p,i,g; od; # change by corresponding matrix element - e:=PreImagesRepresentative(mon,g)*e; + e:=PreImagesRepresentativeNC(mon,g)*e; S:=S.stabilizer; od; @@ -1202,9 +1202,9 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . for a blow up isomorphism +#M PreImagesRepresentativeNC( , ) . . . for a blow up isomorphism ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for a blow up isomorphism, and a matrix in the range", FamRangeEqFamElm, [ IsBlowUpIsomorphism, IsMatrix ], diff --git a/lib/grpnames.gi b/lib/grpnames.gi index 8220d79e88..11dcafd25e 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -173,7 +173,7 @@ InstallMethod( NormalComplementNC, i:=0; for gF in IndependentGeneratorsOfAbelianGroup(F) do i := i+1; - g := PreImagesRepresentative(nat, gF); + g := PreImagesRepresentativeNC(nat, gF); R := RightCoset(N, g); # DirectFactorsOfGroup already computed Center and RationalClasses # when calling NormalComplement diff --git a/lib/grpnice.gd b/lib/grpnice.gd index 5a9480fd86..e22d72c39a 100644 --- a/lib/grpnice.gd +++ b/lib/grpnice.gd @@ -363,7 +363,7 @@ BindGlobal( "AttributeMethodByNiceMonomorphismList", function( oper, par ) local nice; nice:= NiceMonomorphism( obj ); return List( oper( NiceObject( obj ) ), - x -> PreImagesRepresentative( nice, x ) ); + x -> PreImagesRepresentativeNC( nice, x ) ); end ); end ); @@ -398,7 +398,7 @@ BindGlobal( "AttributeMethodByNiceMonomorphismCollElm", function( oper, par ) img := ImagesRepresentative( nice, obj2 : actioncanfail:= true ); if img = fail or not ( img in ImagesSource( nice ) and - PreImagesRepresentative( nice, img ) = obj2 ) then + PreImagesRepresentativeNC( nice, img ) = obj2 ) then TryNextMethod(); fi; return oper( NiceObject( obj1 ), img ); @@ -441,7 +441,7 @@ BindGlobal( "AttributeMethodByNiceMonomorphismElmColl", img := ImagesRepresentative( nice, obj1 : actioncanfail:= true ); if img = fail or not (img in ImagesSource( nice ) and - PreImagesRepresentative( nice, img ) = obj1) then + PreImagesRepresentativeNC( nice, img ) = obj1) then TryNextMethod(); fi; return oper( img, NiceObject( obj2 ) ); @@ -525,7 +525,7 @@ BindGlobal( "GroupMethodByNiceMonomorphismCollElm", img := ImagesRepresentative( nice, obj2 : actioncanfail:= true ); if img = fail or not (img in ImagesSource( nice ) and - PreImagesRepresentative( nice, img ) = obj2) then + PreImagesRepresentativeNC( nice, img ) = obj2) then TryNextMethod(); fi; img1 := oper( NiceObject( obj1 ), img ); @@ -613,7 +613,7 @@ BindGlobal( "SubgroupMethodByNiceMonomorphismCollColl", function( oper, par ) img:=ImagesSet( nice, obj2 ); if img = fail or not ( IsSubset( ImagesSource( nice ), img ) and - PreImagesSet( nice, img ) = obj2 ) then + PreImagesSetNC( nice, img ) = obj2 ) then TryNextMethod(); fi; img := oper( NiceObject( obj1 ), img ); @@ -637,7 +637,7 @@ BindGlobal( "SubgroupMethodByNiceMonomorphismCollElm", function( oper, par ) img := ImagesRepresentative( nice, obj2 : actioncanfail:= true ); if img = fail or not ( img in ImagesSource( nice ) and - PreImagesRepresentative (nice , img ) = obj2 ) then + PreImagesRepresentativeNC( nice, img ) = obj2 ) then TryNextMethod(); fi; img1 := oper( NiceObject( obj1 ), img ); @@ -764,7 +764,7 @@ BindGlobal( "GroupSeriesMethodByNiceMonomorphismCollElm", img := ImagesRepresentative( nice, obj2 : actioncanfail:= true ); if img = fail or not ( img in ImagesSource( nice ) and - PreImagesRepresentative( nice, img ) = obj2 ) then + PreImagesRepresentativeNC( nice, img ) = obj2 ) then TryNextMethod(); fi; list := ShallowCopy( oper( NiceObject( obj1 ), img ) ); diff --git a/lib/grpnice.gi b/lib/grpnice.gi index f72d348e81..6e3db2bd6f 100644 --- a/lib/grpnice.gi +++ b/lib/grpnice.gi @@ -212,7 +212,7 @@ function( elm, G ) nice := NiceMonomorphism( G ); img := ImagesRepresentative( nice, elm:actioncanfail:=true ); return img<>fail and img in NiceObject( G ) - and PreImagesRepresentative( nice, img ) = elm; + and PreImagesRepresentativeNC( nice, img ) = elm; end ); @@ -284,7 +284,7 @@ function( obj1, obj2 ) img := ImagesRepresentative( nice, obj2:actioncanfail:=true ); if img = fail or not (img in ImagesSource(nice) and - PreImagesRepresentative(nice,img)=obj2) then + PreImagesRepresentativeNC(nice,img)=obj2) then TryNextMethod(); fi; no:=NiceObject(obj1); @@ -344,10 +344,10 @@ local mon,cl,clg,c,i; cl:=ConjugacyClasses(NiceObject(g)); clg:=[]; for i in cl do - c:=ConjugacyClass(g,PreImagesRepresentative(mon,Representative(i))); + c:=ConjugacyClass(g,PreImagesRepresentativeNC(mon,Representative(i))); c!.niceClass:=i; if HasStabilizerOfExternalSet(i) then - SetStabilizerOfExternalSet(c,PreImages(mon,StabilizerOfExternalSet(i))); + SetStabilizerOfExternalSet(c,PreImagesNC(mon,StabilizerOfExternalSet(i))); fi; Add(clg,c); od; @@ -767,7 +767,7 @@ SubgroupMethodByNiceMonomorphism( SolvableRadical, InstallMethodWithRandomSource( Random, "for a random source and a group handled by nice monomorphism", [ IsRandomSource, IsGroup and IsHandledByNiceMonomorphism ], 0, - {rs, G} -> PreImagesRepresentative( NiceMonomorphism( G ), + {rs, G} -> PreImagesRepresentativeNC( NiceMonomorphism( G ), Random( rs, NiceObject( G ) ) ) ); @@ -783,9 +783,9 @@ local mon,cl,clg,c,i; cl:=RationalClasses(NiceObject(g)); clg:=[]; for i in cl do - c:=RationalClass(g,PreImagesRepresentative(mon,Representative(i))); + c:=RationalClass(g,PreImagesRepresentativeNC(mon,Representative(i))); if HasStabilizerOfExternalSet(i) then - SetStabilizerOfExternalSet(c,PreImages(mon,StabilizerOfExternalSet(i))); + SetStabilizerOfExternalSet(c,PreImagesNC(mon,StabilizerOfExternalSet(i))); fi; if HasGaloisGroup(i) then SetGaloisGroup(c,GaloisGroup(i)); @@ -806,7 +806,7 @@ function(g,u) local mon,rt; mon:=NiceMonomorphism(g); rt:=RightTransversal(ImagesSet(mon,g),ImagesSet(mon,u)); - rt:=List(rt,i->RightCoset(u,PreImagesRepresentative(mon,i))); + rt:=List(rt,i->RightCoset(u,PreImagesRepresentativeNC(mon,i))); return rt; end); @@ -878,7 +878,7 @@ local hom,rep; rep:= RepresentativeAction( NiceObject( G ), ImageElm( hom, a ), ImageElm( hom, b ), OnPoints ); if rep<>fail then - rep:=PreImagesRepresentative(hom,rep); + rep:=PreImagesRepresentativeNC(hom,rep); fi; return rep; end); @@ -972,9 +972,9 @@ end); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . . via images +#M PreImagesRepresentativeNC( , ) . . . . . . . . . . via images ## -InstallMethod( PreImagesRepresentative, "for PBG-Niceo", +InstallMethod( PreImagesRepresentativeNC, "for PBG-Niceo", FamRangeEqFamElm, [ IsPreimagesByAsGroupGeneralMappingByImages and IsNiceMonomorphism, IsMultiplicativeElementWithInverse ], 0, @@ -983,7 +983,7 @@ local p, tmp; # avoid the double dispatch for `AsGroupGeneralMappingByImages' tmp := RUN_IN_GGMBI; RUN_IN_GGMBI:=true; - p:=PreImagesRepresentative( AsGroupGeneralMappingByImages( hom ), elm ); + p:=PreImagesRepresentativeNC( AsGroupGeneralMappingByImages( hom ), elm ); RUN_IN_GGMBI:=tmp; return p; end ); @@ -1078,7 +1078,7 @@ InstallMethod( \[\],"enum-by-niceo", true, function( enum, pos ) local img; img:=enum!.niceEnumerator[pos]; - return PreImagesRepresentative(enum!.morphism,img); + return PreImagesRepresentativeNC(enum!.morphism,img); end); diff --git a/lib/grppc.gi b/lib/grppc.gi index f01a7af92d..9233d045e2 100644 --- a/lib/grppc.gi +++ b/lib/grppc.gi @@ -2147,7 +2147,7 @@ local e, # EAS if iso<>false then V:=PreImage(iso,V); no:=PreImage(iso,no); - ce:=PreImagesRepresentative(iso,ce); + ce:=PreImagesRepresentativeNC(iso,ce); fi; return [V,no,ce]; end ); @@ -2568,7 +2568,7 @@ local q, pcgs, sub, hom, f, ex, C; ex:=ExponentOfPGroupAndElm(f,q); while ex[1]>q do # take the element of highest order in f and take power of its preimage - ex:=PreImagesRepresentative(hom,ex[2]^q); + ex:=PreImagesRepresentativeNC(hom,ex[2]^q); sub:=NormalClosure(G,ClosureSubgroupNC(sub,ex)); hom:=NaturalHomomorphismByNormalSubgroup(G,sub); f:=Range(hom); @@ -2646,7 +2646,7 @@ function(G,p,e) local f; f:=MaximalAbelianQuotient(G); IsAbelian(Image(f)); - return SubgroupByPcgs(G,Pcgs(PreImagesSet(f,Omega(Image(f),p,e)))); + return SubgroupByPcgs(G,Pcgs(PreImagesSetNC(f,Omega(Image(f),p,e)))); end); # Efficiency notes: @@ -2679,7 +2679,7 @@ local z,f; f:=NaturalHomomorphismByNormalSubgroup(G,Subgroup(G,[z])); IsAbelian(Image(f)); # Probably is not, but quick to check - return SubgroupByPcgs(G,Pcgs(PreImagesSet(f,Omega(Image(f),p,e)))); + return SubgroupByPcgs(G,Pcgs(PreImagesSetNC(f,Omega(Image(f),p,e)))); end); # Efficiency Points: @@ -2820,7 +2820,7 @@ InstallMethod (HallSubgroupOp, "via IsomoprhismPcGroup", true, function (grp, pi) local iso; iso := IsomorphismPcGroup (grp); - return PreImagesSet (iso, HallSubgroup (ImagesSource (iso), pi)); + return PreImagesSetNC(iso, HallSubgroup (ImagesSource (iso), pi)); end); @@ -2841,7 +2841,7 @@ InstallMethod (SylowComplementOp, "via IsomoprhismPcGroup", true, function (grp, p) local iso; iso := IsomorphismPcGroup (grp); - return PreImagesSet (iso, SylowComplement (ImagesSource (iso), p)); + return PreImagesSetNC(iso, SylowComplement (ImagesSource (iso), p)); end); diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 2840694725..eb3e7a5f51 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -437,7 +437,7 @@ local spec,s,n,M, if d = 1 then hom := IsomorphismPermGroup( B ); pcgs := Pcgs( Image( hom ) ); - pcs := List( pcgs, x -> PreImagesRepresentative( hom, x ) ); + pcs := List( pcgs, x -> PreImagesRepresentativeNC( hom, x ) ); TransferPcgsInfo( B, pcs, RelativeOrders( pcgs ) ); return B; fi; @@ -509,12 +509,12 @@ local spec,s,n,M, Info( InfoOverGr, 1, "computed normalizer of size ", Size(L)); # go back to mat group - B := List( GeneratorsOfGroup(L), x -> PreImagesRepresentative(hom,x) ); + B := List( GeneratorsOfGroup(L), x -> PreImagesRepresentativeNC(hom,x) ); w := PrimitiveRoot(field)* Immutable( IdentityMat( d, field ) ); B := SubgroupNC( S, Concatenation( B, [w] ) ); if IsSolvableGroup( L ) then - pcgs := List( Pcgs(L), x -> PreImagesRepresentative( hom, x ) ); + pcgs := List( Pcgs(L), x -> PreImagesRepresentativeNC( hom, x ) ); Add( pcgs, w ); rels := ShallowCopy( RelativeOrders( Pcgs(L) ) ); Add( rels, p-1 ); @@ -536,7 +536,7 @@ BindGlobal( "CocycleSQ", function( epi, field ) H := Source( epi ); F := Image( epi ); N := KernelOfMultiplicativeGeneralMapping( epi ); - pcsH := List( Pcgs( F ), x -> PreImagesRepresentative( epi, x ) ); + pcsH := List( Pcgs( F ), x -> PreImagesRepresentativeNC( epi, x ) ); pcsN := Pcgs( N ); pcgsH := PcgsByPcSequence( ElementsFamily( FamilyObj( H ) ), Concatenation( pcsH, pcsN ) ); @@ -646,7 +646,7 @@ BindGlobal( "LiftInduciblePair", function( epi, ind, M, weight ) pcgsF := Pcgs( F ); - pcsH := List( pcgsF, x -> PreImagesRepresentative( epi, x ) ); + pcsH := List( pcgsF, x -> PreImagesRepresentativeNC( epi, x ) ); pcsN := Pcgs( N ); pcgsH := PcgsByPcSequence( ElementsFamily( FamilyObj( H ) ), Concatenation( pcsH, pcsN ) ); @@ -656,7 +656,7 @@ BindGlobal( "LiftInduciblePair", function( epi, ind, M, weight ) # use automorphism of F imgsF := List( pcgsF, x -> Image( ind[1], x ) ); opmats := List( imgsF, x -> MappedPcElement( x, pcgsF, M.generators ) ); - imgsF := List( imgsF, x -> PreImagesRepresentative( epi, x ) ); + imgsF := List( imgsF, x -> PreImagesRepresentativeNC( epi, x ) ); # use automorphism of N imgsN := List( pcsN, x -> ExponentsOfPcElement( pcsN, x ) ); @@ -1418,11 +1418,11 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) hom := ActionHomomorphism( xset, "surjective"); P := Image( hom ); if IsSolvableGroup( P ) then - pcsA := List( Pcgs(P), x -> PreImagesRepresentative( hom, x )); + pcsA := List( Pcgs(P), x -> PreImagesRepresentativeNC( hom, x )); TransferPcgsInfo( A, pcsA, RelativeOrders( Pcgs(P) ) ); else imgs := SmallGeneratingSet( P ); - gens := List( imgs, x -> PreImagesRepresentative( hom, x ) ); + gens := List( imgs, x -> PreImagesRepresentativeNC( hom, x ) ); tmp := Size( A ); A := GroupByGenerators( gens, One( A ) ); SetSize( A, tmp ); @@ -1543,10 +1543,10 @@ InstallGlobalFunction(AutomorphismGroupFrattFreeGroup,function( G ) imgs := []; for i in [1..Length(gensK)] do m := gensU[i]^n; - a := PreImagesRepresentative( hom, m ); + a := PreImagesRepresentativeNC( hom, m ); Add( imgs, a ); od; - l := PreImagesRepresentative( iso, n ); + l := PreImagesRepresentativeNC( iso, n ); Append( imgs, List( gensF, x -> Image( l, x ) ) ); new := GroupHomomorphismByImagesNC( G, G, gensG, imgs ); SetIsBijective( new, true ); diff --git a/lib/grppccom.gi b/lib/grppccom.gi index 2dc5682575..bb59eef42e 100644 --- a/lib/grppccom.gi +++ b/lib/grppccom.gi @@ -19,7 +19,7 @@ local r,img,i,gens,img2; gens:=GeneratorsOfGroup(img); img2:=Image(h[i],G); r[i]:=GroupHomomorphismByImagesNC(img,img2,gens,List(gens,j-> - Image(h[i],PreImagesRepresentative(h[i+1],j)))); + Image(h[i],PreImagesRepresentativeNC(h[i+1],j)))); SetKernelOfMultiplicativeGeneralMapping(r[i], Image(h[i+1],KernelOfMultiplicativeGeneralMapping(h[i]))); img:=img2; @@ -890,7 +890,7 @@ local H, E, cor, a, i, fun2,pcgs,home; #a :=NaturalHomomorphism( G, G / N ); #cor:=PPrimeSetsOC( Image( a ) ); #cor.generators:=List( cor.generators, x -> - # PreImagesRepresentative( a, x ) ); + # PreImagesRepresentativeNC( a, x ) ); cor:=rec(home:=home,generators:=pcgs mod InducedPcgs(pcgs,N)); cor.useCentralSK:=true; fi; diff --git a/lib/grppcext.gi b/lib/grppcext.gi index 4cfb4063a1..bcc5e554a9 100644 --- a/lib/grppcext.gi +++ b/lib/grppcext.gi @@ -378,11 +378,11 @@ local ag, p1iso, agp, p2iso, DP, p1, p2, gens, genimgs, triso,s,i,u,opt, genimgs:=List(gens, i->ImagesRepresentative(Embedding(D,1), - PreImagesRepresentative(p1iso, - PreImagesRepresentative(pc1,ImagesRepresentative(p1,i)))) + PreImagesRepresentativeNC(p1iso, + PreImagesRepresentativeNC(pc1,ImagesRepresentative(p1,i)))) *ImagesRepresentative(Embedding(D,2), - PreImagesRepresentative(p2iso, - PreImagesRepresentative(pc2,ImagesRepresentative(p2,i)))) ); + PreImagesRepresentativeNC(p2iso, + PreImagesRepresentativeNC(pc2,ImagesRepresentative(p2,i)))) ); else opt:=rec(limit:=s,random:=1); @@ -426,9 +426,9 @@ local ag, p1iso, agp, p2iso, DP, p1, p2, gens, genimgs, triso,s,i,u,opt, genimgs:=List(gens, i->ImagesRepresentative(Embedding(D,1), - PreImagesRepresentative(p1iso,ImagesRepresentative(p1,i))) + PreImagesRepresentativeNC(p1iso,ImagesRepresentative(p1,i))) *ImagesRepresentative(Embedding(D,2), - PreImagesRepresentative(p2iso,ImagesRepresentative(p2,i))) ); + PreImagesRepresentativeNC(p2iso,ImagesRepresentative(p2,i))) ); fi; triso:=GroupHomomorphismByImagesNC(DP,D,gens,genimgs); @@ -528,7 +528,7 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, gens,M.generators); test:=function(perm) local aut,imgs,mat; - aut:=PreImagesRepresentative(triso,perm); + aut:=PreImagesRepresentativeNC(triso,perm); imgs:=List(gens,x->ImagesRepresentative(aut,x)); imgs:=List(imgs,x->ImagesRepresentative(modulehom,x)); mat:=MTX.IsomorphismModules(M,GModuleByMats(imgs,M.field)); @@ -696,9 +696,9 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, basicact:=function( tup, elm ) local gens; - #gens := List( tup[1], x -> PreImagesRepresentative( elm[1], x ) ); + #gens := List( tup[1], x -> PreImagesRepresentativeNC( elm[1], x ) ); #gens := List( gens, x -> MappedPcElement( x, tup[1], tup[2] ) ); - gens := List( Ggens, x -> PreImagesRepresentative( elm[1], x ) ); + gens := List( Ggens, x -> PreImagesRepresentativeNC( elm[1], x ) ); gens := List( gens, x -> MappedPcElement( x, Ggens, tup ) ); gens := List( gens, x -> x ^ elm[2] ); return gens; @@ -711,10 +711,10 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, Assert(1,MappingGeneratorsImages(epi)[2]=Ggens); f:=function( tup, elm ) local gens; - #gens := List( tup[1], x -> PreImagesRepresentative( elm[1], x ) ); + #gens := List( tup[1], x -> PreImagesRepresentativeNC( elm[1], x ) ); #gens := List( gens, x -> MappedPcElement( x, tup[1], tup[2] ) ); - gens := List( Ggens, x -> PreImagesRepresentative( elm[1], x ) ); - gens := List( gens, x -> MappedWord( PreImagesRepresentative(epi,x), + gens := List( Ggens, x -> PreImagesRepresentativeNC( elm[1], x ) ); + gens := List( gens, x -> MappedWord( PreImagesRepresentativeNC(epi,x), GeneratorsOfGroup(Source(epi)), tup ) ); gens := List( gens, x -> x ^ elm[2] ); return gens; @@ -730,13 +730,13 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, elmlist:=[]; tmp:=List(genimgs,x->x[1]); - preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentative(x,y))]); + preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentativeNC(x,y))]); f:=function( tup, elm ) local gens,p; p:=PositionProperty(preimlist,x->IsIdenticalObj(x[1],elm[1])); if p=fail then - gens := List( Ggens, x -> PreImagesRepresentative( elm[1], x ) ); + gens := List( Ggens, x -> PreImagesRepresentativeNC( elm[1], x ) ); else gens:=preimlist[p][2]; fi; @@ -781,7 +781,7 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, if elmlist<>fail then tmp:=List(genimgs,x->x[1]); - preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentative(x,y))]); + preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentativeNC(x,y))]); # ensure we also account for action u:=Group(tup); @@ -911,7 +911,7 @@ BindGlobal( "MatrixOperationOfCPGroup", function( cc, gens ) mats := List( gens, x -> [] ); base := Basis( Image( cc.cohom ) ); - prei := List( base, x -> PreImagesRepresentative( cc.cohom, x ) ); + prei := List( base, x -> PreImagesRepresentativeNC( cc.cohom, x ) ); pcgs := Pcgs( cc.group ); ords := RelativeOrders( pcgs ); @@ -1008,7 +1008,7 @@ function( G, M, C ) return [ExtensionSQ( cc.collector, G, M, 0 )]; elif Dimension( Image(cc.cohom)) = 1 then c := Basis(Image(cc.cohom))[1]; - c := PreImagesRepresentative(cc.cohom, c); + c := PreImagesRepresentativeNC(cc.cohom, c); return [ExtensionSQ( cc.collector, G, M, 0 ), ExtensionSQ( cc.collector, G, M, c )]; fi; @@ -1018,7 +1018,7 @@ function( G, M, C ) # compute orbit of mats on H^2( G, M ) Mgrp := GroupByGenerators( mats ); orbs := OrbitsDomain( Mgrp, Image(cc.cohom), OnRight ); - orbs := List( orbs, x -> PreImagesRepresentative( cc.cohom, x[1] ) ); + orbs := List( orbs, x -> PreImagesRepresentativeNC( cc.cohom, x[1] ) ); ext := List( orbs, x -> ExtensionSQ( cc.collector, G, M, x ) ); return ext; end); @@ -1113,7 +1113,7 @@ BindGlobal( "NonSplitExtensions", function( arg ) red := true; elif Dimension( Image(cc.cohom ) ) = 1 then - c := PreImagesRepresentative(cc.cohom, Basis(Image(cc.cohom))[1]); + c := PreImagesRepresentativeNC(cc.cohom, Basis(Image(cc.cohom))[1]); all := [ExtensionSQ( C, G, M, c)]; red := true; @@ -1121,7 +1121,7 @@ BindGlobal( "NonSplitExtensions", function( arg ) elif IsBound( arg[3] ) and not arg[3] then all := NormedRowVectors( Image(cc.cohom) ); all := List( all, x -> ExtensionSQ(cohom.collector, G, M, - PreImagesRepresentative(cc.cohom,x ))); + PreImagesRepresentativeNC(cc.cohom,x ))); red := false; # sometimes we do not want to reduce @@ -1132,7 +1132,7 @@ BindGlobal( "NonSplitExtensions", function( arg ) then all := NormedRowVectors( Image(cc.cohom) ); all := List( all, x -> ExtensionSQ(cc.collector, G, M, - PreImagesRepresentative(cc.cohom, x ))); + PreImagesRepresentativeNC(cc.cohom, x ))); red := false; # then we want to reduce @@ -1151,7 +1151,7 @@ BindGlobal( "NonSplitExtensions", function( arg ) # create extensions and add info all := List( all, x -> ExtensionSQ(cc.collector, G, M, - PreImagesRepresentative(cc.cohom, x ))); + PreImagesRepresentativeNC(cc.cohom, x ))); fi; if red then diff --git a/lib/grppclat.gi b/lib/grppclat.gi index 4b8113783e..b313ba6359 100644 --- a/lib/grppclat.gi +++ b/lib/grppclat.gi @@ -86,7 +86,7 @@ local f; else aut:= GroupHomomorphismByImagesNC(f,f,GeneratorsOfGroup(f), List(GeneratorsOfGroup(f), - i->Image(epi,Image(aut,PreImagesRepresentative(epi,i))))); + i->Image(epi,Image(aut,PreImagesRepresentativeNC(epi,i))))); SetIsInjective(aut,true); SetIsSurjective(aut,true); fi; @@ -672,7 +672,7 @@ local g, # group # hom:=[]; # for i in func do # hom2:=GroupHomomorphismByImagesNC(g,g,g.generators,List(g.generators, -# j->Image(isom,Image(i,PreImagesRepresentative(isom,j))))); +# j->Image(isom,Image(i,PreImagesRepresentativeNC(isom,j))))); # hom2.isMapping:=true; # Add(hom,hom2); # od; @@ -788,7 +788,7 @@ local g, # group hom:= GroupHomomorphismByImagesNC(f,fa,GeneratorsOfGroup(f), List(GeneratorsOfGroup(f),i-> - Image(hom,PreImagesRepresentative(epi,i)))); + Image(hom,PreImagesRepresentativeNC(epi,i)))); Assert(2,KernelOfMultiplicativeGeneralMapping(hom)=n); # lift the known groups diff --git a/lib/grpperm.gi b/lib/grpperm.gi index 020398dfe5..08f7805298 100644 --- a/lib/grpperm.gi +++ b/lib/grpperm.gi @@ -1592,7 +1592,7 @@ InstallGlobalFunction( SylowSubgroupPermGroup, function( G, p ) O := Orbit( S, D[1] ); f := ActionHomomorphism( S, O,"surjective" ); T := SylowSubgroupPermGroup( Range( f ), p ); - S := PreImagesSet( f, T ); + S := PreImagesSetNC( f, T ); SubtractSet( D, O ); od; return S; @@ -1605,7 +1605,7 @@ InstallGlobalFunction( SylowSubgroupPermGroup, function( G, p ) f := ActionHomomorphism( G, B, OnSets,"surjective" ); T := SylowSubgroupPermGroup( Range( f ), p ); if Size( T ) < Size( Range( f ) ) then - T := PreImagesSet( f, T ); + T := PreImagesSetNC( f, T ); S := SylowSubgroupPermGroup( T , p) ; return S; fi; @@ -1630,7 +1630,7 @@ InstallGlobalFunction( SylowSubgroupPermGroup, function( G, p ) Info(InfoGroup,1,"PermSylow: cycleaction"); f := ActionHomomorphism( C, B, OnSets,"surjective" ); T := SylowSubgroupPermGroup( Range( f ), p ); - S := PreImagesSet( f, T ); + S := PreImagesSetNC( f, T ); return S; end ); diff --git a/lib/grpprmcs.gi b/lib/grpprmcs.gi index c8a8a1166a..8ba3001d28 100644 --- a/lib/grpprmcs.gi +++ b/lib/grpprmcs.gi @@ -1173,7 +1173,7 @@ InstallGlobalFunction( PullbackKernelCSPG, fi; for g in gens do for j in [1..i-1] do - g := PreImagesRepresentative(homlist[i-j],g); + g := PreImagesRepresentativeNC(homlist[i-j],g); od; Add(normals[index],g); Add(factors[index],()); @@ -1193,7 +1193,7 @@ InstallGlobalFunction( PullbackCSPG, function(p,homlist) # compute a preimage of the permutation p in the input group lenhomlist := Length(homlist); for i in [1..lenhomlist] do - p := PreImagesRepresentative(homlist[lenhomlist+1-i],p); + p := PreImagesRepresentativeNC(homlist[lenhomlist+1-i],p); od; return p; end ); @@ -1522,7 +1522,7 @@ InstallMethod( PCoreOp, for g in GeneratorsOfGroup( KernelOfMultiplicativeGeneralMapping( homlist[i] ) ) do for j in [1..i-1] do - g := PreImagesRepresentative(homlist[i-j],g); + g := PreImagesRepresentativeNC(homlist[i-j],g); od; Add(pgenlist,g); od; @@ -1747,7 +1747,7 @@ InstallMethod( SolvableRadical, for g in GeneratorsOfGroup( KernelOfMultiplicativeGeneralMapping( homlist[i] ) ) do for j in [1..i-1] do - g := PreImagesRepresentative(homlist[i-j],g); + g := PreImagesRepresentativeNC(homlist[i-j],g); od; Add(solvable,g); od; @@ -1873,7 +1873,7 @@ InstallMethod( Centre, else order := Size( centr ); cent := IntersectionNormalClosurePermGroup(GG,centr,order*Size(GG)); - cent:= PreImages(tchom,cent); + cent:= PreImagesNC(tchom,cent); Assert( 1, IsAbelian( cent ) ); SetIsAbelian( cent, true ); return cent; @@ -1917,7 +1917,7 @@ InstallMethod( Centre, cent := IntersectionNormalClosurePermGroup ( GG, GroupByGenerators(hgens,()), order*Size(GG) ); if n <> len then - cent:= PreImages( tchom, cent ); + cent:= PreImagesNC( tchom, cent ); fi; Assert( 1, IsAbelian( cent ) ); SetIsAbelian( cent, true ); @@ -2012,7 +2012,7 @@ InstallGlobalFunction( CentralizerNormalCSPG, function(G,N) # handle case of transitive GG directly if Length(significant) = 1 then centrnorm := CentralizerNormalTransCSPG(GG,NN); - return PreImages(tchom,centrnorm); + return PreImagesNC(tchom,centrnorm); fi; # case of intransitive GG @@ -2054,7 +2054,7 @@ InstallGlobalFunction( CentralizerNormalCSPG, function(G,N) if n = len then return central; else - return PreImages(tchom,central); + return PreImagesNC(tchom,central); fi; end ); diff --git a/lib/liefam.gi b/lib/liefam.gi index 6122a753b0..ca6c3161c6 100644 --- a/lib/liefam.gi +++ b/lib/liefam.gi @@ -447,7 +447,7 @@ InstallMethod( ImagesElm, return [ LieObject( elm ) ]; end ); -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for Lie embedding and Lie object in default representation", FamRangeEqFamElm, [ IsGeneralMapping and IsLieEmbeddingRep, diff --git a/lib/mapphomo.gi b/lib/mapphomo.gi index 3e396945ff..fbd38cb004 100644 --- a/lib/mapphomo.gi +++ b/lib/mapphomo.gi @@ -330,9 +330,9 @@ InstallMethod( ImagesSet, ############################################################################# ## -#M PreImagesElm( , ) . for s.p. gen. mapping resp. mult. & inv. +#M PreImagesElmNC( , ) . for s.p. gen. mapping resp. mult. & inv. ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "method for s.p. general mapping respecting mult. & inv., and element", FamRangeEqFamElm, [ IsSPGeneralMapping and RespectsMultiplication and RespectsInverses, @@ -340,7 +340,7 @@ InstallMethod( PreImagesElm, function( map, elm ) local pre; - pre:= PreImagesRepresentative( map, elm ); + pre:= PreImagesRepresentativeNC( map, elm ); if pre = fail then return []; else @@ -351,9 +351,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . for s.p. gen. mapping resp. mult. & inv. +#M PreImagesSetNC( , ) . for s.p. gen. mapping resp. mult. & inv. ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for s.p. general mapping respecting mult. & inv., and group", CollFamRangeEqFamElms, [ IsSPGeneralMapping and RespectsMultiplication and RespectsInverses, @@ -367,7 +367,7 @@ InstallMethod( PreImagesSet, fi; genpreimages:= List(genpreimages, - gen -> PreImagesRepresentative( map, gen ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; @@ -384,7 +384,7 @@ InstallMethod( PreImagesSet, return pre; end ); -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for injective s.p. mapping respecting mult. & inv., and group", CollFamRangeEqFamElms, [ IsSPGeneralMapping and IsMapping and IsInjective and @@ -395,7 +395,7 @@ InstallMethod( PreImagesSet, pre := SubgroupNC( Source( map ), List( GeneratorsOfMagmaWithInverses( elms ), - gen -> PreImagesRepresentative( map, gen ) ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ) ); UseIsomorphismRelation( elms, pre ); return pre; end ); @@ -684,9 +684,9 @@ InstallMethod( ImagesSet, ############################################################################# ## -#M PreImagesElm( , ) for s.p. gen. mapping resp. add. & add.inv. +#M PreImagesElmNC( , ) for s.p. gen. mapping resp. add. & add.inv. ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "method for s.p. gen. mapping respecting add. & add.inv., and element", FamRangeEqFamElm, [ IsSPGeneralMapping and RespectsAddition and RespectsAdditiveInverses, @@ -694,7 +694,7 @@ InstallMethod( PreImagesElm, function( map, elm ) local pre; - pre:= PreImagesRepresentative( map, elm ); + pre:= PreImagesRepresentativeNC( map, elm ); if pre = fail then return []; else @@ -705,9 +705,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) for s.p. gen. mapping resp. add. & add.inv. +#M PreImagesSetNC( , ) for s.p. gen. mapp. resp. add. & add.inv. ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for s.p. gen. mapping resp. add. & add.inv., and add. group", CollFamRangeEqFamElms, [ IsSPGeneralMapping and RespectsAddition and RespectsAdditiveInverses, @@ -715,7 +715,7 @@ InstallMethod( PreImagesSet, function( map, elms ) local genpreimages; genpreimages:= List( GeneratorsOfAdditiveGroup( elms ), - gen -> PreImagesRepresentative( map, gen ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; @@ -890,9 +890,9 @@ InstallMethod( ImagesSet, ############################################################################# ## -#M PreImagesSet( , ) . . . . for linear mapping and left module +#M PreImagesSetNC( , ) . . . for linear mapping and left module ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for linear mapping and left module", CollFamRangeEqFamElms, [ IsSPGeneralMapping and RespectsAddition and RespectsAdditiveInverses @@ -901,7 +901,7 @@ InstallMethod( PreImagesSet, function( map, elms ) local genpreimages; genpreimages:= List( GeneratorsOfLeftModule( elms ), - gen -> PreImagesRepresentative( map, gen ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; @@ -984,9 +984,9 @@ InstallMethod( ImagesSet, ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . for algebra hom. and FLMLOR +#M PreImagesSetNC( , ) . . . . . . . for algebra hom. and FLMLOR ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for algebra hom. and FLMLOR", CollFamRangeEqFamElms, [ IsSPGeneralMapping and RespectsAddition and RespectsAdditiveInverses @@ -995,7 +995,7 @@ InstallMethod( PreImagesSet, function( map, elms ) local genpreimages; genpreimages:= List( GeneratorsOfLeftOperatorRing( elms ), - gen -> PreImagesRepresentative( map, gen ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; @@ -1010,9 +1010,9 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesSet( , ) for alg.-with-one hom. and FLMLOR-with-one +#M PreImagesSetNC( , ) for alg-with-one hom. and FLMLOR-with-one ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "method for algebra-with-one hom. and FLMLOR-with-one", CollFamRangeEqFamElms, [ IsSPGeneralMapping and RespectsAddition and RespectsAdditiveInverses @@ -1022,7 +1022,7 @@ InstallMethod( PreImagesSet, function( map, elms ) local genpreimages; genpreimages:= List( GeneratorsOfLeftOperatorRingWithOne( elms ), - gen -> PreImagesRepresentative( map, gen ) ); + gen -> PreImagesRepresentativeNC( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; diff --git a/lib/mapping.gd b/lib/mapping.gd index 12d2ff39dc..70c0be49a0 100644 --- a/lib/mapping.gd +++ b/lib/mapping.gd @@ -751,7 +751,7 @@ DeclareAttribute( "ImagesSource", IsGeneralMapping ); ## ## is the set of preimages of the range of the general mapping map. ##

-## delegates to , +## delegates to , ## it is introduced only to store the preimage of map as attribute ## value. ## @@ -968,7 +968,8 @@ DeclareGlobalFunction( "Images" ); ############################################################################# ## -#O PreImagesElm( , ) . all preimages of elm under a gen. mapping +#O PreImagesElm( , ) . . . . . . . . . . . . all preimages of elm +#O PreImagesElmNC( , ) . . . . . . . . . . . under a gen. mapping ## ## <#GAPDoc Label="PreImagesElm"> ## @@ -976,16 +977,22 @@ DeclareGlobalFunction( "Images" ); ## ## ## If elm is an element of the range of the general mapping -## map then returns the set of all +## map then returns the set of all ## preimages of elm under map. ##

## Anything may happen if elm is not an element of the range of ## map. +##

+## In order to improve this state of affairs, +## PreImagesElm has been renamed PreImagesElmNC +## throughout the library, and PreImagesElm now checks that +## elm is an element of the range before calling PreImagesElmNC. ## ## ## <#/GAPDoc> ## DeclareOperation( "PreImagesElm", [ IsGeneralMapping, IsObject ] ); +DeclareOperation( "PreImagesElmNC", [ IsGeneralMapping, IsObject ] ); ############################################################################# @@ -1015,11 +1022,12 @@ DeclareOperation( "PreImageElm", ############################################################################# ## #O PreImagesRepresentative( , ) . . . one preimage of an element -## under a gen. mapping +#O PreImagesRepresentativeNC( , ) . . . . under a general mapping ## ## <#GAPDoc Label="PreImagesRepresentative"> ## ## +## ## ## ## If elm is an element of the range of the general mapping @@ -1030,21 +1038,28 @@ DeclareOperation( "PreImageElm", ##

## Anything may happen if elm is not an element of the range of ## map. +##

+## In order to improve this state of affairs, PreImagesRepresentative +## has been renamed PreImagesRepresentativeNC throughout the library, +## and PreImagesRepresentative now checks that elm is an +## element of the range before calling PreImagesRepresentativeNC. ## ## ## <#/GAPDoc> ## -DeclareOperation( "PreImagesRepresentative", - [ IsGeneralMapping, IsObject ] ); +DeclareOperation( "PreImagesRepresentative", [ IsGeneralMapping, IsObject ] ); +DeclareOperation( "PreImagesRepresentativeNC", [ IsGeneralMapping, IsObject ] ); ############################################################################# ## #O PreImagesSet( , ) +#O PreImagesSetNC( , ) ## ## <#GAPDoc Label="PreImagesSet"> ## ## +## ## ## ## If elms is a subset of the range of the general mapping map @@ -1053,11 +1068,17 @@ DeclareOperation( "PreImagesRepresentative", ##

## Anything may happen if elms is not a subset of the range of ## map. +##

+## In order to improve this state of affairs, PreImagesSet +## has been renamed PreImagesSetNC throughout the library, +## and PreImagesSet now checks that elm is an +## element of the range before calling PreImagesSetNC. ## ## ## <#/GAPDoc> ## DeclareOperation( "PreImagesSet", [ IsGeneralMapping, IsListOrCollection ] ); +DeclareOperation( "PreImagesSetNC", [ IsGeneralMapping, IsListOrCollection ] ); ############################################################################# @@ -1119,18 +1140,27 @@ DeclareGlobalFunction( "PreImage" ); ############################################################################# ## #F PreImages( ) . . . set of preimages of the range of a gen. mapping +#F PreImagesNC( ) . . set of preimages of the range of a gen. mapping #F PreImages(,) . set of preimages of an elm under a gen. mapping -#F PreImages(,) set of preimages of a coll. under a gen. mapping +#F PreImagesNC(,) set of preimages of an elm under a gen. mapping +#F PreImages(,) set of preimages of a coll. under a gen. mapping +#F PreImagesNC(,) set of preimages of a coll. under a gen. mapping ## ## <#GAPDoc Label="PreImages"> ## ## PreImages ## +## ## +## ## +## ## ## ## PreImages( map ) is the preimage of the general mapping @@ -1157,13 +1187,16 @@ DeclareGlobalFunction( "PreImage" ); ## and to resp. when ## called with two arguments. ##

-## If the second argument is not an element or a subset of the range of -## the first argument, an error is signalled. +## In order to improve this state of affairs, PreImages +## has been renamed PreImagesNC throughout the library, +## and PreImages now checks that elm or coll +## belong to the range before calling PreImagesNC. ## ## ## <#/GAPDoc> ## DeclareGlobalFunction( "PreImages" ); +DeclareGlobalFunction( "PreImagesNC" ); ############################################################################# diff --git a/lib/mapping.gi b/lib/mapping.gi index 7ae902e971..f54e58ee2d 100644 --- a/lib/mapping.gi +++ b/lib/mapping.gi @@ -273,9 +273,9 @@ InstallGlobalFunction( PreImage, function ( arg ) fi; if IsDomain( img ) or IsSSortedList( img ) then - return PreImagesSet( map, img ); + return PreImagesSetNC( map, img ); elif IsHomogeneousList( img ) then - return PreImagesSet( map, Set( img ) ); + return PreImagesSetNC( map, Set( img ) ); fi; # preimage of the empty list @@ -297,10 +297,68 @@ end ); ############################################################################# ## -#F PreImages( ) . . . set of preimages of the range of a gen. mapping -#F PreImages(,) . set of preimages of an elm under a gen. mapping -#F PreImages(,) set of preimages of a coll. under a gen. mapping +#F PreImages() +#F PreImagesNC() . . . set of preimages of the range of a gen. mapping +#F PreImages(,) +#F PreImagesNC(,) set of preimages of an elm under a gen. mapping +#F PreImages(,) +#F PreImagesNC(,) set of preimages of a coll. under a gen. mapping ## +InstallGlobalFunction( PreImagesNC, function ( arg ) + + local map, # mapping , first argument + img; # element , second argument + + # preimage of the range under + if Length( arg ) = 1 then + + return PreImagesRange( arg[1] ); + + elif Length( arg ) = 2 then + + map := arg[1]; + img := arg[2]; + + if not IsGeneralMapping( map ) then + ErrorNoReturn( " must be a general mapping" ); + fi; + + # preimage of a single element under + if FamRangeEqFamElm( FamilyObj( map ), FamilyObj( img ) ) then + if not img in Range( map ) then + ErrorNoReturn( " must be an element of Range()" ); + fi; + return PreImagesElmNC( map, img ); + + # preimage of a collection of elements under + elif CollFamRangeEqFamElms( FamilyObj( map ), FamilyObj( img ) ) then + if not IsSubset( Range( map ), img ) then + ErrorNoReturn( "the collection must be contained in ", + "Range()" ); + fi; + + if IsDomain( img ) or IsSSortedList( img ) then + return PreImagesSetNC( map, img ); + elif IsHomogeneousList( img ) then + return PreImagesSetNC( map, Set( img ) ); + fi; + + # preimage of the empty list + elif IsList( img ) and IsEmpty( img ) then + + return []; + + else + ErrorNoReturn( "the families of the element or collection ", + "and Range() don't match, ", + "maybe is not contained in Range() or ", + "is not a homogeneous list or collection" ); + fi; + fi; + ErrorNoReturn( "usage: PreImagesNC(), PreImagesNC(,), ", + "PreImagesNC(,)" ); +end ); + InstallGlobalFunction( PreImages, function ( arg ) local map, # mapping , first argument @@ -1067,16 +1125,17 @@ InstallMethod( PreImageElm, "for inj. & surj. general mapping, and element", FamRangeEqFamElm, [ IsGeneralMapping and IsInjective and IsSurjective, IsObject ], 0, - PreImagesRepresentative ); + PreImagesRepresentativeNC ); ############################################################################# ## #M PreImagesElm( , ) . . . . . . for general mapping and element +#M PreImagesElmNC( , ) . . . . . for general mapping and element ## ## more or less delegate to `ImagesElm' ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for general mapping with finite source, and element", FamRangeEqFamElm, [ IsGeneralMapping, IsObject ], 0, @@ -1093,12 +1152,26 @@ InstallMethod( PreImagesElm, fi; end ); +InstallMethod( PreImagesElm, + "for general mapping with finite source, and element", + FamRangeEqFamElm, + [ IsGeneralMapping, IsObject ], 0, + function ( map, elm ) + + if not ( elm in Image( map ) ) then + return []; + else + return PreImagesElmNC( map, elm ); + fi; + end ); + ############################################################################# ## -#M PreImagesElm( , ) for const. time access gen. map., and elm. +#M PreImagesElm( , ) . for const. time access gen. map., and elm. +#M PreImagesElmNC( , ) for const. time access gen. map., and elm. ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for constant time access general mapping, and element", FamRangeEqFamElm, [ IsGeneralMapping and IsConstantTimeAccessGeneralMapping, IsObject ], 0, @@ -1113,12 +1186,25 @@ InstallMethod( PreImagesElm, return preimgs; end ); +InstallMethod( PreImagesElm, + "for constant time access general mapping, and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsConstantTimeAccessGeneralMapping, IsObject ], 0, + function( map, elm ) + if not ( elm in Image( map ) ) then + return []; + else + return PreImagesElmNC( map, elm ); + fi; + end ); + ############################################################################# ## #M PreImagesSet( , ) . for general mapping and finite collection +#M PreImagesSetNC( , ) for general mapping and finite collection ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for general mapping, and finite collection", CollFamRangeEqFamElms, [ IsGeneralMapping, IsCollection ], 0, @@ -1129,12 +1215,31 @@ InstallMethod( PreImagesSet, fi; primgs:= []; for elm in Enumerator( elms ) do - UniteSet( primgs, AsList( PreImagesElm( map, elm ) ) ); + UniteSet( primgs, AsList( PreImagesElmNC( map, elm ) ) ); od; return primgs; end ); + InstallMethod( PreImagesSet, + "for general mapping, and finite collection", + CollFamRangeEqFamElms, + [ IsGeneralMapping, IsCollection ], 0, + function( map, elms ) + local im, elm; + if not IsFinite( elms ) then + TryNextMethod(); + fi; + im:= Image( map ); + for elm in Enumerator( elms ) do + if not (elm in im ) then + return []; + fi; + od; + return PreImagesSetNC( map, elms ); + end ); + +InstallMethod( PreImagesSetNC, "for general mapping, and empty list", true, [ IsGeneralMapping, IsList and IsEmpty ], 0, @@ -1142,6 +1247,14 @@ InstallMethod( PreImagesSet, return []; end ); +InstallMethod( PreImagesSet, + "for general mapping, and empty list", + true, + [ IsGeneralMapping, IsList and IsEmpty ], 0, + function( map, elms ) + return []; + end ); + ############################################################################# ## @@ -1151,7 +1264,7 @@ InstallMethod( PreImagesRange, "for general mapping", true, [ IsGeneralMapping ], 0, - map -> PreImagesSet( map, Range( map ) ) ); + map -> PreImagesSetNC( map, Range( map ) ) ); ############################################################################# @@ -1169,6 +1282,7 @@ InstallMethod( PreImagesRange, ############################################################################# ## #M PreImagesRepresentative( , ) . . for s.p. gen. mapping & elm +#M PreImagesRepresentativeNC( , ) . for s.p. gen. mapping & elm ## InstallMethod( PreImagesRepresentative, "for s.p. general mapping, and element", @@ -1178,12 +1292,21 @@ InstallMethod( PreImagesRepresentative, Error( "no default method for s.p. general mapping" ); end ); +InstallMethod( PreImagesRepresentativeNC, + "for s.p. general mapping, and element", + FamRangeEqFamElm, + [ IsSPGeneralMapping, IsObject ], 0, + function( map, elm ) + Error( "no default method for s.p. general mapping" ); + end ); + ############################################################################# ## #M PreImagesRepresentative( , ) +#M PreImagesRepresentativeNC( , ) ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for total non-s.p. general mapping, and element", FamRangeEqFamElm, [ IsNonSPGeneralMapping, IsObject ], 0, @@ -1191,17 +1314,28 @@ InstallMethod( PreImagesRepresentative, local pres; # all preimages of under # get all preimages of under - pres := PreImagesElm( map, elm ); + pres := PreImagesElmNC( map, elm ); # check that has at least one preimage under if IsEmpty( pres ) then - return fail; + return []; fi; # pick one preimage, and return it. return Representative( pres ); end ); +InstallMethod( PreImagesRepresentative, + "for total non-s.p. general mapping, and element", + FamRangeEqFamElm, + [ IsNonSPGeneralMapping, IsObject ], 0, + function( map, elm ) + if not elm in Image( map ) then + return []; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); + ############################################################################# ## @@ -1459,7 +1593,7 @@ InstallMethod( Enumerator, return enum; elif IsFinite( R ) then for elm in Enumerator( R ) do - imgs:= PreImagesElm( map, elm ); + imgs:= PreImagesElmNC( map, elm ); if IsFinite( imgs ) then UniteSet( enum, List( imgs, im -> DirectProductElement( [ im, elm ] ) ) ); else diff --git a/lib/mapprep.gi b/lib/mapprep.gi index 96bf008e8b..67ea3b1233 100644 --- a/lib/mapprep.gi +++ b/lib/mapprep.gi @@ -302,17 +302,17 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesElm( , ) . . . . . . . . . . for composition mapping +#M PreImagesElmNC( , ) . . . . . . . . . for composition mapping ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for a composition mapping, and an element", FamRangeEqFamElm, [ IsCompositionMappingRep, IsObject ], 0, function( com, elm ) local im; - im:= PreImagesElm( com!.map2, elm ); + im:= PreImagesElmNC( com!.map2, elm ); if not IsEmpty( im ) then - return PreImagesSet( com!.map1, im ); + return PreImagesSetNC( com!.map1, im ); else return []; fi; @@ -321,17 +321,17 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . . . for composition mapping +#M PreImagesSetNC( , ) . . . . . . . . . for composition mapping ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for a composition mapping, and a collection", CollFamRangeEqFamElms, [ IsCompositionMappingRep, IsCollection ], 0, function( com, elms ) local im; - im:= PreImagesSet( com!.map2, elms ); + im:= PreImagesSetNC( com!.map2, elms ); if not IsEmpty( im ) then - return PreImagesSet( com!.map1, im ); + return PreImagesSetNC( com!.map1, im ); else return []; fi; @@ -340,27 +340,27 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . for composition mapping +#M PreImagesRepresentativeNC( , ) . . . . for composition mapping ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for a composition mapping, and an element", FamRangeEqFamElm, [ IsCompositionMappingRep, IsObject ], 0, function( com, elm ) local im, rep; - im:= PreImagesRepresentative( com!.map2, elm ); + im:= PreImagesRepresentativeNC( com!.map2, elm ); if im = fail then # 'elm' has no preimages under 'com!.map2', so it has none under 'com'. return fail; else - im:= PreImagesRepresentative( com!.map1, im ); + im:= PreImagesRepresentativeNC( com!.map1, im ); if im <> fail then return im; fi; # It may happen that only the chosen representative has no preimages. - for im in Enumerator( PreImagesElm( com!.map2, elm ) ) do - rep:= PreImagesRepresentative( com!.map1, im ); + for im in Enumerator( PreImagesElmNC( com!.map2, elm ) ) do + rep:= PreImagesRepresentativeNC( com!.map1, im ); if rep <> fail then return rep; fi; @@ -383,7 +383,7 @@ InstallMethod( KernelOfAdditiveGeneralMapping, if IsInjective( com!.map2 ) then return KernelOfAdditiveGeneralMapping( com!.map1 ); else - return PreImagesSet( com!.map1, + return PreImagesSetNC( com!.map1, KernelOfAdditiveGeneralMapping( com!.map2 ) ); fi; end ); @@ -421,7 +421,7 @@ InstallMethod( KernelOfMultiplicativeGeneralMapping, if IsInjective( com!.map2 ) then return KernelOfMultiplicativeGeneralMapping( com!.map1 ); else - return PreImagesSet( com!.map1, + return PreImagesSetNC( com!.map1, KernelOfMultiplicativeGeneralMapping( com!.map2 ) ); fi; end ); @@ -629,9 +629,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . for mapping by function +#M PreImagesRepresentativeNC( , ) . . . . . for mapping by function ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for mapping by function", FamRangeEqFamElm, [ IsMappingByFunctionRep, IsObject ], 0, @@ -659,9 +659,9 @@ InstallMethod( PreImageElm, ############################################################################# ## -#M PreImagesElm( , ) . . . . . . . . . . for mapping by function +#M PreImagesElmNC( , ) . . . . . . . . . . for mapping by function ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for mapping by function", FamRangeEqFamElm, [ IsMappingByFunctionWithInverseRep, IsObject ], 0, @@ -671,9 +671,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . for mapping by function +#M PreImagesRepresentativeNC( , ) . . . . for mapping by function ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for mapping by function with inverse", FamRangeEqFamElm, [ IsMappingByFunctionWithInverseRep, IsObject ], 0, @@ -1008,7 +1008,7 @@ InstallMethod( ImagesElm, FamSourceEqFamElm, [ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm ) - return PreImagesElm( InverseGeneralMapping( inv ), elm ); + return PreImagesElmNC( InverseGeneralMapping( inv ), elm ); end ); @@ -1021,7 +1021,7 @@ InstallMethod( ImagesSet, CollFamSourceEqFamElms, [ IsGeneralMapping and IsInverseGeneralMappingRep, IsCollection ], 0, function ( inv, elms ) - return PreImagesSet( InverseGeneralMapping( inv ), elms ); + return PreImagesSetNC( InverseGeneralMapping( inv ), elms ); end ); @@ -1034,7 +1034,7 @@ InstallMethod( ImagesRepresentative, FamSourceEqFamElm, [ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm ) - return PreImagesRepresentative( InverseGeneralMapping( inv ), elm ); + return PreImagesRepresentativeNC( InverseGeneralMapping( inv ), elm ); end ); @@ -1054,9 +1054,9 @@ InstallMethod( PreImageElm, ############################################################################# ## -#M PreImagesElm( , ) . . . . . for inverse mapping and element +#M PreImagesElmNC( , ) . . . . for inverse mapping and element ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for an inverse mapping and an element", FamRangeEqFamElm, [ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, @@ -1067,9 +1067,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . . for inverse mapping and collection +#M PreImagesSetNC( , ) . . for inverse mapping and collection ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for an inverse mapping and a collection", CollFamRangeEqFamElms, [ IsGeneralMapping and IsInverseGeneralMappingRep, IsCollection ], 0, @@ -1080,9 +1080,9 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) . . for inv. mapping and elm. +#M PreImagesRepresentativeNC( , ) . . for inv. mapping and elm. ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for an inverse mapping and an element", FamRangeEqFamElm, [ IsInverseGeneralMappingRep, IsObject ], 0, @@ -1293,9 +1293,9 @@ InstallMethod( PreImageElm, ############################################################################# ## -#M PreImagesElm( , ) . . . . for identity mapping and element +#M PreImagesElmMC( , ) . . . for identity mapping and element ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for identity mapping and object", FamRangeEqFamElm, [ IsGeneralMapping and IsOne, IsObject ], @@ -1307,9 +1307,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . . . for identity mapping and collection +#M PreImagesSetNC( , ) . . for identity mapping and collection ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for identity mapping and collection", CollFamRangeEqFamElms, [ IsGeneralMapping and IsOne, IsCollection ], @@ -1321,9 +1321,9 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) +#M PreImagesRepresentativeNC( , ) ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for identity mapping and object", FamRangeEqFamElm, [ IsGeneralMapping and IsOne, IsObject ], @@ -1581,9 +1581,9 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesElm( , ) . . . . . for zero mapping and element +#M PreImagesElmNC( , ) . . . . for zero mapping and element ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for zero mapping and object", FamRangeEqFamElm, [ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, @@ -1598,9 +1598,9 @@ InstallMethod( PreImagesElm, ############################################################################# ## -#M PreImagesSet( , ) . . . . for zero mapping and collection +#M PreImagesSetNC( , ) . . . for zero mapping and collection ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for zero mapping and collection", CollFamRangeEqFamElms, [ IsGeneralMapping and IsZero, IsCollection ], SUM_FLAGS, @@ -1615,9 +1615,9 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) +#M PreImagesRepresentativeNC( , ) ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for zero mapping and object", FamRangeEqFamElm, [ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, @@ -1817,15 +1817,15 @@ end ); ############################################################################# ## -#M PreImagesElm( , ) . . . . . . . . . . for restricted mapping +#M PreImagesElmNC( , ) . . . . . . . . . for restricted mapping ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for a restricted mapping, and an element", FamRangeEqFamElm, [ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm ) local preim; - preim:= PreImagesElm( res!.map, elm ); + preim:= PreImagesElmNC( res!.map, elm ); if not ( (HasIsInjective(res) and IsInjective(res)) or (HasIsInjective(res!.map) and IsInjective(res!.map)) ) then preim:=Intersection(Source(res),preim); @@ -1836,15 +1836,15 @@ end ); ############################################################################# ## -#M PreImagesSet( , ) . . . . . . . . . . for restricted mapping +#M PreImagesSetNC( , ) . . . . . . . . . for restricted mapping ## -InstallMethod( PreImagesSet, +InstallMethod( PreImagesSetNC, "for a restricted mapping, and a collection", CollFamRangeEqFamElms, [ IsGeneralRestrictedMappingRep, IsCollection ], 0, function( res, elms ) local preim; - preim:= PreImagesSet( res!.map, elms ); + preim:= PreImagesSetNC( res!.map, elms ); if not ( (HasIsInjective(res) and IsInjective(res)) or (HasIsInjective(res!.map) and IsInjective(res!.map)) ) then preim:=Intersection(Source(res),preim); @@ -1855,15 +1855,15 @@ InstallMethod( PreImagesSet, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . for restricted mapping +#M PreImagesRepresentativeNC( , ) . . . . for restricted mapping ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for a restricted mapping, and an element", FamRangeEqFamElm, [ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm ) local preim; - preim:= PreImagesRepresentative( res!.map, elm ); + preim:= PreImagesRepresentativeNC( res!.map, elm ); if preim = fail then # 'elm' has no preimages under 'res!.map', so it has none under 'res'. return fail; @@ -1872,7 +1872,7 @@ InstallMethod( PreImagesRepresentative, elif HasIsInjective(res!.map) and IsInjective(res!.map) then return fail; # no other choice else - preim:= PreImages( res!.map, elm ); + preim:= PreImagesNC( res!.map, elm ); return First(preim,x->x in Source(res)); fi; end ); diff --git a/lib/maxsub.gi b/lib/maxsub.gi index e04c94eaa5..d9a9923d6d 100644 --- a/lib/maxsub.gi +++ b/lib/maxsub.gi @@ -182,7 +182,7 @@ BindGlobal("MaximalSubgroupClassesSol",function(G) sel:=Filtered([1..Length(mgi[2])],x->not IsOne(mgi[2][x])); if 4^Length(sel)>Size(Range(ff.factorhom)) then f:=SmallGeneratingSet(Image(ff.factorhom)); - mgi:=[List(f,x->PreImagesRepresentative(ff.factorhom,x)),f]; + mgi:=[List(f,x->PreImagesRepresentativeNC(ff.factorhom,x)),f]; sel:=[1..Length(mgi[1])]; fi; gensG:=mgi[1]{sel}; @@ -195,8 +195,8 @@ BindGlobal("MaximalSubgroupClassesSol",function(G) fam:=FamilyObj(One(Range(fphom))); # just in case the stored group generators differ... wordfpgens:=List(wordgens,x->ElementOfFpGroup(fam,x)); - wordpre:=List(wordfpgens,x->PreImagesRepresentative(ff.factorhom, - PreImagesRepresentative(fphom,x))); + wordpre:=List(wordfpgens,x->PreImagesRepresentativeNC(ff.factorhom, + PreImagesRepresentativeNC(fphom,x))); fphom:=ff.factorhom*fphom; # no assertion as this is not a proper homomorphism, but an inverse # multiplicative map @@ -513,7 +513,7 @@ local hom,embs,s,k,agens,ad,i,j,perm,dia,ggens,e,tgens,d,m,reco,emba,outs,id; m:=[]; d:=SubgroupNC(w,d); for i in e do - j:=PreImagesRepresentative(hom,i^-1); + j:=PreImagesRepresentativeNC(hom,i^-1); Info(InfoLattice,2,"Orders:",Order(i),",",Order(j)); j:=d^j; if donorm then @@ -633,9 +633,9 @@ local dom, o, t1, a1, t1d, proj, reps, ts, ta, tb, s1, i, fix, wnew, max, s, p1, # get the ts corresponding to points proj:=Projection(w); projG:=RestrictedMapping(proj,G); - reps:=List([1..n],i->PreImagesRepresentative(projG,RepresentativeAction(Image(projG),1,i))); + reps:=List([1..n],i->PreImagesRepresentativeNC(projG,RepresentativeAction(Image(projG),1,i))); reps[n+1]:= - PreImagesRepresentative(proj,RepresentativeAction(Image(proj),[1..n],[n+1..2*n],OnSets)); + PreImagesRepresentativeNC(proj,RepresentativeAction(Image(proj),[1..n],[n+1..2*n],OnSets)); for i in [2..n] do j:=reps[i]*reps[n+1]; reps[1^Image(proj,j)]:=j; @@ -665,8 +665,8 @@ local dom, o, t1, a1, t1d, proj, reps, ts, ta, tb, s1, i, fix, wnew, max, s, p1, en1:=Embedding(wnew,1); en2:=Embedding(wnew,2); emb:=List(GeneratorsOfGroup(s),i-> - Image(en1,PreImagesRepresentative(p1,RestrictedPerm(i,ts[1]))) - *Image(en2,PreImagesRepresentative(p2,RestrictedPerm(i,ts[f]))) ); + Image(en1,PreImagesRepresentativeNC(p1,RestrictedPerm(i,ts[1]))) + *Image(en2,PreImagesRepresentativeNC(p2,RestrictedPerm(i,ts[f]))) ); emb:=GroupHomomorphismByImages(s,wnew,GeneratorsOfGroup(s),emb); ma:=MaxesType3(wnew,Image(emb,s),a1,t1,2,false); for i in ma do @@ -699,7 +699,7 @@ local m, fact, fg, reps, ma, idx, nm, embs, proj, kproj, k, ag, agl, ug, # type 4c reps:=List([1..n], - i->PreImagesRepresentative(fact,RepresentativeAction(fg,1,i))); + i->PreImagesRepresentativeNC(fact,RepresentativeAction(fg,1,i))); # get the maximal subgroups of A, intersect with t to get the socle part @@ -758,8 +758,8 @@ local m, fact, fg, reps, ma, idx, nm, embs, proj, kproj, k, ag, agl, ug, #phi:=ActionHomomorphism(fg,u.orbit,OnSets); #ue:=Image(phi,fg); #reps:=List([1..nlb],i->RepresentativeAction(ue,1,i)); - #reps:=List(reps,i->PreImagesRepresentative(phi,i)); - #reps:=List(reps,i->PreImagesRepresentative(fact,i)); + #reps:=List(reps,i->PreImagesRepresentativeNC(phi,i)); + #reps:=List(reps,i->PreImagesRepresentativeNC(fact,i)); #u:=u.stabilizer; uphi:=ActionHomomorphism(Image(fact,u),b); diff --git a/lib/mgmring.gi b/lib/mgmring.gi index 077f27c153..f7a4688a36 100644 --- a/lib/mgmring.gi +++ b/lib/mgmring.gi @@ -1220,7 +1220,7 @@ InstallMethod( ImagesRepresentative, end ); -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for embedding of ring into magma ring, and free magma ring element", FamRangeEqFamElm, [ IsEmbeddingRingMagmaRing, IsElementOfFreeMagmaRing ], @@ -1236,7 +1236,7 @@ InstallMethod( PreImagesElm, fi; end ); -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for embedding of ring into magma ring, and free magma ring element", FamRangeEqFamElm, [ IsEmbeddingRingMagmaRing, IsElementOfFreeMagmaRing ], @@ -1324,7 +1324,7 @@ InstallMethod( ImagesRepresentative, end ); -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "for embedding of magma into magma ring, and free magma ring element", FamRangeEqFamElm, [ IsEmbeddingMagmaMagmaRing, IsElementOfFreeMagmaRing ], @@ -1340,7 +1340,7 @@ InstallMethod( PreImagesElm, fi; end ); -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for embedding of magma into magma ring, and free magma ring element", FamRangeEqFamElm, [ IsEmbeddingMagmaMagmaRing, IsElementOfFreeMagmaRing ], diff --git a/lib/morpheus.gi b/lib/morpheus.gi index 0e92772399..9cb2957e14 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -748,10 +748,10 @@ local hom, gens, c, ran, r, cen, img, u, orbs, function(perm) if perm in store[1] then return ConjugatorAutomorphismNC(g, - PreImagesRepresentative(img[2],perm)); + PreImagesRepresentativeNC(img[2],perm)); fi; return GroupHomomorphismByImagesNC(g,g,GeneratorsOfGroup(g), - List(store[2],i->PreImagesRepresentative(img[2],i^perm))); + List(store[2],i->PreImagesRepresentativeNC(img[2],i^perm))); end); if bestdegPreImagesRepresentative(store[3],i^perm))); + List(store[4],i->PreImagesRepresentativeNC(store[3],i^perm))); end); if bestdegPreImagesRepresentative(gens,i)); + i->PreImagesRepresentativeNC(gens,i)); Ggc:=List(gens,i->First(Gcl,j->ForAny(j,j->ForAny(j.classes,k->i in k)))); combi:=List(Ggc,i->Concatenation(List(i,i->i.classes))); bcl:=ShallowCopy(combi); @@ -2106,7 +2106,7 @@ local d,id,H,iso,aut,auts,i,all,hom,field,dim,P,diag,mats,gens,gal; fi; aut:=GroupGeneralMappingByImages(G,G,gens, List(gens, - x->PreImagesRepresentative(iso,Image(iso,x)^(1,2)))); + x->PreImagesRepresentativeNC(iso,Image(iso,x)^(1,2)))); auts:=[aut]; all:=true; fi; @@ -2167,7 +2167,7 @@ local d,id,H,iso,aut,auts,i,all,hom,field,dim,P,diag,mats,gens,gal; fi; auts:=Concatenation(auts, List(mats,s->GroupGeneralMappingByImages(G,G,gens,List(gens,x-> - Image(hom,PreImagesRepresentative(hom,x)^s))))); + Image(hom,PreImagesRepresentativeNC(hom,x)^s))))); else gal:=Group(()); # to force trivial @@ -2179,13 +2179,13 @@ local d,id,H,iso,aut,auts,i,all,hom,field,dim,P,diag,mats,gens,gal; List(MinimalGeneratingSet(gal), s->GroupGeneralMappingByImages(G,G,gens,List(gens,x-> Image(hom, - List(PreImagesRepresentative(hom,x),r->List(r,y->Image(s,y)))))))); + List(PreImagesRepresentativeNC(hom,x),r->List(r,y->Image(s,y)))))))); fi; # graph if id.series="L" and id.parameter[1]>2 then Add(auts, GroupGeneralMappingByImages(G,G,gens,List(gens,x-> - Image(hom,Inverse(TransposedMat(PreImagesRepresentative(hom,x))))))); + Image(hom,Inverse(TransposedMat(PreImagesRepresentativeNC(hom,x))))))); all:=true; elif id.series="L" and id.parameter[1]=2 then # note no graph @@ -2350,7 +2350,7 @@ InstallGlobalFunction(AutomorphismGroupFittingFree,function(g) thom:=i[j][2]; thom:=GroupHomomorphismByImagesNC(t,t,GeneratorsOfGroup(t), List(GeneratorsOfGroup(t), - j->Image(thom,PreImagesRepresentative(thom,j)^gen))); + j->Image(thom,PreImagesRepresentativeNC(thom,j)^gen))); thom:=Image(auph,thom); Add(genimgs,thom); od; @@ -2408,7 +2408,7 @@ InstallGlobalFunction(AutomorphismGroupFittingFree,function(g) for i in gens do au:=GroupHomomorphismByImages(g,g,GeneratorsOfGroup(g), List(GeneratorsOfGroup(g), - j->PreImagesRepresentative(emb,Image(emb,j)^i))); + j->PreImagesRepresentativeNC(emb,Image(emb,j)^i))); Add(a,au); od; au:=Group(a); @@ -2449,7 +2449,7 @@ InstallGlobalFunction(AutomorphismGroupFittingFree,function(g) bi:=[]; for i in newbas do s:=List(stbs[i], - x->Image(emb,Image(autom,PreImagesRepresentative(emb,x)))); + x->Image(emb,Image(autom,PreImagesRepresentativeNC(emb,x)))); s:=First(orb[orpo[i]],x->ForAll(s,j->x^j=x)); Add(bi,s); od; diff --git a/lib/norad.gi b/lib/norad.gi index 7457f035e8..6323d1070d 100644 --- a/lib/norad.gi +++ b/lib/norad.gi @@ -173,7 +173,7 @@ local d,orb,len,S,depths,rel,stb,img,pos,i,j,k,ii,po,rep,sg,sf,sfs,fr,first, if r<>fail then Add(good,r);fi; return r<>fail; end); - good:=List(good,x->PreImagesRepresentative(pacthom,x)); + good:=List(good,x->PreImagesRepresentativeNC(pacthom,x)); good:=Filtered(good,x->not IsOne(x[2])); @@ -418,7 +418,7 @@ local sus,ser,len,factorhom,uf,n,d,up,mran,nran,mpcgs,pcgs,pcisom,nf,ng,np,sub, glact:=ActionHomomorphism(glperm,lvecs, GeneratorsOfGroup(glperm), List(GeneratorsOfGroup(glperm), - x->PreImagesRepresentative(glhom,x)), + x->PreImagesRepresentativeNC(glhom,x)), OnLines,"surjective"); stb:=Image(glact); for clu in localclust do @@ -478,7 +478,7 @@ local sus,ser,len,factorhom,uf,n,d,up,mran,nran,mpcgs,pcgs,pcisom,nf,ng,np,sub, Info(InfoFitFree,1,"Radsize= ",Size(ufr)," index ",Index(uf,ufr)); uff:=SmallGeneratingSet(uf); - ufg:=List(uff,x->PreImagesRepresentative(sus.rest,x)); + ufg:=List(uff,x->PreImagesRepresentativeNC(sus.rest,x)); n:=Normalizer(Image(factorhom),uf); @@ -503,7 +503,7 @@ local sus,ser,len,factorhom,uf,n,d,up,mran,nran,mpcgs,pcgs,pcisom,nf,ng,np,sub, nf:=SmallGeneratingSet(n); fi; - ng:=List(nf,x->PreImagesRepresentative(factorhom,x)); + ng:=List(nf,x->PreImagesRepresentativeNC(factorhom,x)); np:=pcgs; up:=sus.pcgs; diff --git a/lib/onecohom.gi b/lib/onecohom.gi index c2b6d29723..e1432730e3 100644 --- a/lib/onecohom.gi +++ b/lib/onecohom.gi @@ -128,7 +128,7 @@ local hom,fg,fpi,fpg,nt,fam; fpg:=FreeGeneratorsOfFpGroup(Range(hom)); ocr.factorpres:=[fpg,RelatorsOfFpGroup(Range(hom))]; ocr.generators:=List(GeneratorsOfGroup(Range(hom)), - i->PreImagesRepresentative(hom,i)); + i->PreImagesRepresentativeNC(hom,i)); else if (Index(ocr.group,nt)>Size(nt)^3 @@ -159,9 +159,9 @@ local hom,fg,fpi,fpg,nt,fam; fpg:=FreeGeneratorsOfFpGroup(Range(fpi)); ocr.factorpres:=[fpg,RelatorsOfFpGroup(Range(fpi)), List(GeneratorsOfGroup(Range(fpi)), - i->PreImagesRepresentative(fpi,i))]; + i->PreImagesRepresentativeNC(fpi,i))]; if not IsBound(ocr.generators) then - ocr.generators:=List(ocr.factorpres[3],i->PreImagesRepresentative(hom,i)); + ocr.generators:=List(ocr.factorpres[3],i->PreImagesRepresentativeNC(hom,i)); fi; @@ -171,7 +171,7 @@ local hom,fg,fpi,fpg,nt,fam; # else # old code # fpi:=IsomorphismFpGroup(ocr.group:noshort:=true); # ocr.generators:=List(MappingGeneratorsImages(fpi)[2], -# i->PreImagesRepresentative(fpi,i)); +# i->PreImagesRepresentativeNC(fpi,i)); # fi; fpg:=FreeGeneratorsOfFpGroup(Range(fpi)); ocr.factorpres:=[fpg,RelatorsOfFpGroup(Range(fpi))]; @@ -191,7 +191,7 @@ local hom,fg,fpi,fpg,nt,fam; fpi:=IsomorphismFpGroupByChiefSeriesFactor(ocr.group,"f",nt); fam:=FamilyObj(One(Range(fpi))); fpg:=FreeGeneratorsOfFpGroup(Range(fpi)); - ocr.generators:=List(fpg,i->PreImagesRepresentative(fpi, + ocr.generators:=List(fpg,i->PreImagesRepresentativeNC(fpi, ElementOfFpGroup(fam,i))); ocr.factorpres:=[fpg,RelatorsOfFpGroup(Range(fpi)),ocr.generators]; fi; diff --git a/lib/oprt.gi b/lib/oprt.gi index a7b758b73f..9d12954fef 100644 --- a/lib/oprt.gi +++ b/lib/oprt.gi @@ -2920,7 +2920,7 @@ local G, D, d, e, gens, acts, act, xset, hom, p, rep; rep := RepresentativeActionOp( ImagesSource( hom ), d, e, OnPoints ); if rep <> fail then - rep := PreImagesRepresentative( hom, rep ); + rep := PreImagesRepresentativeNC( hom, rep ); fi; return rep; elif IsBound( D ) then @@ -3374,9 +3374,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . build matrix +#M PreImagesRepresentativeNC( , ) . . . . . . . . . build matrix ## -InstallMethod( PreImagesRepresentative,"IsLinearActionHomomorphism", +InstallMethod( PreImagesRepresentativeNC,"IsLinearActionHomomorphism", FamRangeEqFamElm, [ IsLinearActionHomomorphism, IsPerm ], 0, function( hom, elm ) local V, G, Grep, filt, R, xset,lab,f; @@ -3388,7 +3388,7 @@ function( hom, elm ) TryNextMethod(); fi; - # PreImagesRepresentative does not test membership + # PreImagesRepresentativeNC does not test membership #if not elm in Image( hom ) then return fail; fi; xset:=UnderlyingExternalSet(hom); V := HomeEnumerator(xset); @@ -3420,7 +3420,7 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . . . . . build matrix +#M PreImagesRepresentativeNC( , ) . . . . . . . . . build matrix ## ## The idea is as follows. ## We have an $F$-basis $(v_1, \ldots, v_n)$. @@ -3441,7 +3441,7 @@ end ); ## matrix group contains all scalar matrices, or we know that the preimage ## has determinant $1$ and taking the root in question is unique. ## -InstallMethod( PreImagesRepresentative,"IsProjectiveActionHomomorphism", +InstallMethod( PreImagesRepresentativeNC,"IsProjectiveActionHomomorphism", FamRangeEqFamElm, [ IsProjectiveActionHomomorphism, IsPerm ], 0, function( hom, elm ) local V, G, Grep, filt, R, mat, xset,lab,dim,sol,i; @@ -3457,7 +3457,7 @@ function( hom, elm ) TryNextMethod(); fi; - # PreImagesRepresentative does not test membership + # PreImagesRepresentativeNC does not test membership #if not elm in Image( hom ) then return fail; fi; xset:=UnderlyingExternalSet(hom); V := HomeEnumerator(xset); diff --git a/lib/oprtglat.gi b/lib/oprtglat.gi index b80acc2755..43b4531805 100644 --- a/lib/oprtglat.gi +++ b/lib/oprtglat.gi @@ -224,7 +224,7 @@ local acts,gps,clusters,conj,ncl,nacts,i,j,new,q,hom,lhom,c,n,r,len, Info(InfoLattice,5,"reduced (factor) by ",Size(q)/Size(n)); Add(nacts,PreImage(lhom,n)); for k in new.clusters[j] do - r:=PreImagesRepresentative(lhom,new.conjugators[k]); + r:=PreImagesRepresentativeNC(lhom,new.conjugators[k]); conj[c[k]]:=conj[c[k]]*r; gps[c[k]]:=gps[c[k]]^r; od; diff --git a/lib/oprtperm.gi b/lib/oprtperm.gi index 0678e7eafb..a1a1616b7c 100644 --- a/lib/oprtperm.gi +++ b/lib/oprtperm.gi @@ -964,7 +964,7 @@ InstallMethod( Earns, "G, ints, gens, perms, act", true, fi; gens := [ ]; for gen in GeneratorsOfGroup( Centre( P ) ) do - pre := PreImagesRepresentative( f, gen ); + pre := PreImagesRepresentativeNC( f, gen ); ord := Order( pre ); pa := 1; while ord mod p = 0 do ord := ord / p; diff --git a/lib/pcgsnice.gi b/lib/pcgsnice.gi index 0496a0c212..caa90d90ec 100644 --- a/lib/pcgsnice.gi +++ b/lib/pcgsnice.gi @@ -23,7 +23,7 @@ AttributeMethodByNiceMonomorphism( Pcgs, if npcgs = fail then return fail; fi; - pcgs := List( npcgs, gen -> PreImagesRepresentative( nice, gen ) ); + pcgs := List( npcgs, gen -> PreImagesRepresentativeNC( nice, gen ) ); pcgs := PcgsByPcSequenceNC( ElementsFamily( FamilyObj( G ) ), pcgs ); if HasIsPrimeOrdersPcgs( npcgs ) and IsPrimeOrdersPcgs( npcgs ) then SetIsPrimeOrdersPcgs( pcgs, true ); diff --git a/lib/permdeco.gi b/lib/permdeco.gi index f57059f634..e605798c0f 100644 --- a/lib/permdeco.gi +++ b/lib/permdeco.gi @@ -314,7 +314,7 @@ local tryrep,sel,selin,a,s,dom,iso,stabs,outs,map,i,j,p,found,seln, for i in GeneratorsOfGroup(G) do a:=One(d); for j in [1..Length(stabs)] do - a:=a*Image(Embedding(d,j),PreImagesRepresentative(outs[j],i)); + a:=a*Image(Embedding(d,j),PreImagesRepresentativeNC(outs[j],i)); od; Add(p,a); od; @@ -360,7 +360,7 @@ local G,H,tg,th,hom, tga, Gemb, C, outs, auts, ar, Hemb; i->GroupHomomorphismByImagesNC(tg,tg, GeneratorsOfGroup(tg), List(GeneratorsOfGroup(tg), - j->Image(hom,PreImagesRepresentative(hom,j)^i)))); + j->Image(hom,PreImagesRepresentativeNC(hom,j)^i)))); Gemb:=fail; if ForAll(tga,IsConjugatorAutomorphism) then @@ -442,7 +442,7 @@ local cs,i,k,u,o,norm,T,Thom,autos,ng,a,Qhom,Q,Ehom,genimages, autos:=List(ng,i->GroupHomomorphismByImagesNC(T,T, GeneratorsOfGroup(T), List(GeneratorsOfGroup(T), - j->Image(Thom,PreImagesRepresentative(Thom,j)^i)))); + j->Image(Thom,PreImagesRepresentativeNC(Thom,j)^i)))); a:=AutomorphismRepresentingGroup(T,autos); Thom:=GroupHomomorphismByImagesNC(norm,a[1],ng,a[3]); a:=a[1]; @@ -455,7 +455,7 @@ local cs,i,k,u,o,norm,T,Thom,autos,ng,a,Qhom,Q,Ehom,genimages, # define isomorphisms between the components reps:=List([1..n],i-> - PreImagesRepresentative(Qhom,RepresentativeAction(Q,1,i))); + PreImagesRepresentativeNC(Qhom,RepresentativeAction(Q,1,i))); genimages:=[]; for i in GeneratorsOfGroup(G) do @@ -539,7 +539,7 @@ local limit, r, pcgs, ser, ind, m, p, l, l2, good, i, j,nser,hom; ser:=InvariantElementaryAbelianSeries(p, List( GeneratorsOfGroup( G ), i -> GroupHomomorphismByImagesNC(p,p,GeneratorsOfGroup(p), List(GeneratorsOfGroup(p), - j->Image(m,PreImagesRepresentative(m,j)^i)))), + j->Image(m,PreImagesRepresentativeNC(m,j)^i)))), TrivialSubgroup(p),true); ser:=List(ser,i->PreImage(m,i)); else diff --git a/lib/relation.gi b/lib/relation.gi index e5208df4b7..115e5409ae 100644 --- a/lib/relation.gi +++ b/lib/relation.gi @@ -71,7 +71,7 @@ ## ## I. Operations and methods for binary relations on points ## 1. ImagesElm (compatibility with GeneralMapping) -## 2. PreImagesElm (compatibility with GeneralMapping) +## 2. PreImagesElmNC (compatibility with GeneralMapping) ## 3. \=, \in, \< ## 4. \* for relations, transformations, and permutation ## 5. Set operations \+, \- (union, difference) @@ -92,7 +92,7 @@ ## 4. MeetEquivalenceRelations ## 5. \= ## 6. ImagesElm (compatibility with GeneralMapping) -## 7. PreImagesElm (compatibility with GeneralMapping) +## 7. PreImagesElmNC (compatibility with GeneralMapping) ## 8. PrintObj ## ## L. Constructors of equivalence classes @@ -104,7 +104,7 @@ ## 2. PrintObj, Enumerator ## 3. \< ## 4. ImagesRepresentative -## 6. PreImagesRepresentative +## 6. PreImagesRepresentativeNC ## ############################################################################ ############################################################################ @@ -230,7 +230,7 @@ InstallMethod(IsReflexiveBinaryRelation, ## #P IsSymmetricBinaryRelation() ## -## Depends on Images and Preimages returning SSorted lists. +## Depends on Images and PreimagesNC returning SSorted lists. ## InstallMethod(IsSymmetricBinaryRelation, @@ -250,7 +250,7 @@ InstallMethod(IsSymmetricBinaryRelation, List(Enumerator(UnderlyingRelation(m)),x->[x[1],x[2]]))); for e in el do - if not PreImages(m,e)=Images(m,e) then + if not PreImagesNC(m,e)=Images(m,e) then return false; fi; od; @@ -312,7 +312,7 @@ InstallMethod(IsAntisymmetricBinaryRelation, List(Enumerator(UnderlyingRelation(rel)),x->[x[1],x[2]]))); for e in el do - i := IntersectionSet(PreImages(rel,e),Images(rel,e)); + i := IntersectionSet(PreImagesNC(rel,e),Images(rel,e)); if not IsEmpty(i) and not i=[e] then return false; fi; @@ -376,7 +376,7 @@ function(rel) for a in Source(rel) do for b in Source(rel) do # intersecting downsets - intersection := Intersection(PreImages(rel,b),PreImages(rel,a)); + intersection := Intersection(PreImagesNC(rel,b),PreImagesNC(rel,a)); # new relation on the intersection induced by the original relation nrel := PartialOrderByOrderingFunction( Domain(intersection), @@ -607,11 +607,11 @@ InstallMethod(HasseDiagramBinaryRelation, HDBRMinElts := function(list, rel) ## x minimal if - ## {y in list | y<>x and y in PreImagesElm( rel,x)} is empty + ## {y in list | y<>x and y in PreImagesElmNC( rel,x)} is empty ## return Filtered(list, x->IsEmpty(Filtered(list, y-> (y <> x) and - (y in PreImagesElm(rel,x))))); + (y in PreImagesElmNC(rel,x))))); end; ## return the elements which cover x in rel @@ -983,11 +983,11 @@ InstallMethod(ImagesElm, ############################################################################# ## -#M PreImagesElm( , ) +#M PreImagesElmNC( , ) ## ## For binary relations over [1..n] represented as a list of images ## -InstallMethod(PreImagesElm, +InstallMethod(PreImagesElmNC, "for binary rels over [1..n] with images list", true, [IsBinaryRelation and IsBinaryRelationOnPointsRep, IsPosInt], 0, function( rel, n ) @@ -1781,9 +1781,9 @@ InstallMethod( ImagesRepresentative, "equivalence relations", ############################################################################# ## -#M PreImagesRepresentative( , ) . . . for equivalence relations +#M PreImagesRepresentativeNC( , ) . . . for equivalence relations ## -InstallMethod( PreImagesRepresentative, "equivalence relations", +InstallMethod( PreImagesRepresentativeNC, "equivalence relations", FamRangeEqFamElm, [IsEquivalenceRelation, IsObject], 0, function( map, elm ) return elm; @@ -1813,9 +1813,9 @@ InstallMethod( ImagesElm, ############################################################################# ## -#M PreImagesElm( , ) for equivalence relations with partition +#M PreImagesElmNC( , ) . for equivalence relations with partition ## -InstallMethod( PreImagesElm, +InstallMethod( PreImagesElmNC, "equivalence relations with partition and element", FamRangeEqFamElm, [IsEquivalenceRelation and HasEquivalenceRelationPartition, diff --git a/lib/ringhom.gi b/lib/ringhom.gi index 21791f48a8..2dc8ab4bb7 100644 --- a/lib/ringhom.gi +++ b/lib/ringhom.gi @@ -444,9 +444,9 @@ end ); ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . . for ring g.m.b.i. +#M PreImagesRepresentativeNC( , ) . . . . . . for ring g.m.b.i. ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for ring g.m.b.i., and element", FamRangeEqFamElm, [ IsRingGeneralMapping and IsRingGeneralMappingByImagesDefaultRep, diff --git a/lib/schur.gi b/lib/schur.gi index f53b66dbdd..b34a4608c9 100644 --- a/lib/schur.gi +++ b/lib/schur.gi @@ -130,7 +130,7 @@ InstallMethod(EpimorphismSchurCover,"generic, via fp group",true,[IsGroup],1, j->One(F))))); hom:=GroupHomomorphismByImagesNC(D,G,GeneratorsOfGroup(D), - List(Dgens,i->PreImagesRepresentative(iso,i))); + List(Dgens,i->PreImagesRepresentativeNC(iso,i))); Dgens:=TzImagesOldGens(p); Dgens:=List(Dgens{[Length(Fgens)+1..Length(Dgens)]}, i->MappedWord(i,p!.generators,GeneratorsOfGroup(D))); @@ -201,7 +201,7 @@ local s,pcgs,n,l,cov,pco,ng,gens,imgs,ran,zer,i,j,e,a, fi; # get a decent pcgs for the cover - pco:=List(pcgs,i->Image(epi,PreImagesRepresentative(de,i))); + pco:=List(pcgs,i->Image(epi,PreImagesRepresentativeNC(de,i))); Append(pco,Pcgs(mul)); pco:=PcgsByPcSequenceNC(FamilyObj(One(cov)),pco); @@ -261,7 +261,7 @@ local s,pcgs,n,l,cov,pco,ng,gens,imgs,ran,zer,i,j,e,a, # factor generators gens:=GeneratorsOfGroup(qs); # their conjugates - imgs:=List(gens,j->PreImagesRepresentative(epi,Image(epi,j)^dc[i])); + imgs:=List(gens,j->PreImagesRepresentativeNC(epi,Image(epi,j)^dc[i])); rels:=ClosureGroup(rels,CommutGenImgs(pco,gens,imgs, Intersection(mul,DerivedSubgroup(qs)))); fi; @@ -306,7 +306,7 @@ BindGlobal("PositiveExponentsPresentationFpHom",function(hom) local G,F,geni,ro,fam,r,i,j,rel,n,e; G:=Image(hom); F:=FreeGeneratorsOfFpGroup(G); - geni:=List(GeneratorsOfGroup(G),i->PreImagesRepresentative(hom,i)); + geni:=List(GeneratorsOfGroup(G),i->PreImagesRepresentativeNC(hom,i)); ro:=List(geni,Order); fam:=FamilyObj(F[1]); r:=[]; @@ -351,7 +351,7 @@ local G,H,D,T,i,j,k,l,a,h,nk,evals,rels,gens,r,np,g,invlist,el,elp,TL,rp,pos; # this will guarantee we always take the same preimages el:=AsSSortedListNonstored(H); - elp:=List(el,i->PreImagesRepresentative(s,i)); + elp:=List(el,i->PreImagesRepresentativeNC(s,i)); #ensure the preimage of identity is one if IsOne(el[1]) then pos:=1; @@ -401,13 +401,13 @@ local G,H,D,T,i,j,k,l,a,h,nk,evals,rels,gens,r,np,g,invlist,el,elp,TL,rp,pos; fi; np:=k*g; nk:=TL[PositionCanonical(T,np)]; - #h:=h*PreImagesRepresentative(s,np/nk); + #h:=h*PreImagesRepresentativeNC(s,np/nk); h:=h*elp[Position(el,np/nk)]; k:=nk; od; - #Print(PreImagesRepresentative(s,Image(s,h))*h,"\n"); - #a:=a/PreImagesRepresentative(s,Image(s,h))*h; + #Print(PreImagesRepresentativeNC(s,Image(s,h))*h,"\n"); + #a:=a/PreImagesRepresentativeNC(s,Image(s,h))*h; a:=a/h*elp[Position(el,Image(s,h))]; od; @@ -485,7 +485,7 @@ local G,B,P,s,D,i,j,v,ri,rank,bas,basr,row,rel,sol,snf,mat; j:=NaturalHomomorphismByNormalSubgroupNC(D,v); i:=GeneratorsOfGroup(Image(j)); i:=GroupHomomorphismByImagesNC(Image(j),P,i, - List(i,k->ImageElm(s,PreImagesRepresentative(j,k)))); + List(i,k->ImageElm(s,PreImagesRepresentativeNC(j,k)))); SetKernelOfMultiplicativeGeneralMapping(i, Image(j,KernelOfMultiplicativeGeneralMapping(s))); return i; @@ -558,7 +558,7 @@ local hom, #isomorphism fp s:=sl[pp]; mg:=IsomorphismPermGroup(KernelOfMultiplicativeGeneralMapping(s)); mg:=List(IndependentGeneratorsOfAbelianGroup(Image(mg)), - i->PreImagesRepresentative(mg,i)); + i->PreImagesRepresentativeNC(mg,i)); sdc:=ListWithIdenticalEntries(Last(ngl),One(Source(s))); sdc{[ngl[pp]+1..ngl[pp+1]]}:=mg; @@ -579,7 +579,7 @@ local hom, #isomorphism fp q:=[]; for i in ce do - Add(q,PreImagesRepresentative(sdc,i[2])); + Add(q,PreImagesRepresentativeNC(sdc,i[2])); od; rel2[pp]:=q; od; diff --git a/lib/semirel.gi b/lib/semirel.gi index dd0fad38fa..f3bb8188cc 100644 --- a/lib/semirel.gi +++ b/lib/semirel.gi @@ -1299,7 +1299,7 @@ end); ######## ######## -InstallMethod(PreImagesRepresentative, "for semigroup homomorphism by images", +InstallMethod(PreImagesRepresentativeNC, "for semigroup homomorphism by images", FamRangeEqFamElm, [IsSemigroupHomomorphism and IsSemigroupHomomorphismByImagesRep, IsMultiplicativeElement], function(hom, x) diff --git a/lib/stbcbckt.gi b/lib/stbcbckt.gi index f0b4eb0046..1d9ccd727f 100644 --- a/lib/stbcbckt.gi +++ b/lib/stbcbckt.gi @@ -2602,7 +2602,7 @@ dom, et, ft, Pr, rbase, BF, Q, data,lc; found:=PartitionBacktrack( G, Pr, true, rbase, data, L, R ); if IsPerm(found) and map<>false then - found:=PreImagesRepresentative(map,found); + found:=PreImagesRepresentativeNC(map,found); fi; return found; end ); diff --git a/lib/twocohom.gi b/lib/twocohom.gi index 179e1f453a..7af0728b1e 100644 --- a/lib/twocohom.gi +++ b/lib/twocohom.gi @@ -813,7 +813,7 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, od; gens:=List(GeneratorsOfGroup(FamilyObj(fpg)!.wholeGroup), - x->PreImagesRepresentative(fp,x)); + x->PreImagesRepresentativeNC(fp,x)); hom:=GroupHomomorphismByImagesNC(G,Group(mo.generators), GeneratorsOfGroup(G),mo.generators); @@ -845,7 +845,7 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, else # Length of r[1] is 1. That is, this generator is not used! m:=First(RelationsOfFpMonoid(mon),x->List(x,LetterRepAssocWord)=r); - m:=List(m,x->PreImagesRepresentative(fm,ElementOfFpMonoid(FamilyObj(One(mon)),x))); + m:=List(m,x->PreImagesRepresentativeNC(fm,ElementOfFpMonoid(FamilyObj(One(mon)),x))); m:=List(m,UnderlyingElement); # free group elements/words if not IsOne(m[1]*Subword(m[2],1,1)) then @@ -866,7 +866,7 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, model:=ValueOption("model"); if model<>fail then q:=GQuotients(model,G)[1]; - pre:=List(gens,x->PreImagesRepresentative(q,x)); + pre:=List(gens,x->PreImagesRepresentativeNC(q,x)); ker:=KernelOfMultiplicativeGeneralMapping(q); pcgs:=Pcgs(ker); l1:=GModuleByMats(LinearActionLayer(Group(pre),pcgs),mo.field); @@ -880,7 +880,7 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, m:=GroupGeneralMappingByImagesNC(fpg,model,GeneratorsOfGroup(fpg),pre); mats:=List(GeneratorsOfMonoid(mon), x->ImagesRepresentative(m, - PreImagesRepresentative(fm,x))); #Elements for monoid generators + PreImagesRepresentativeNC(fm,x))); #Elements for monoid generators nonone:=[1..Length(mats)]; pre:=mats; onemat:=One(G); @@ -896,8 +896,8 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, zerovec:=Zero(onemat[1]); mats:=List(GeneratorsOfMonoid(mon), - x->ImagesRepresentative(hom,PreImagesRepresentative(fp, - PreImagesRepresentative(fm,x)))); # matrices for monoid generators + x->ImagesRepresentative(hom,PreImagesRepresentativeNC(fp, + PreImagesRepresentativeNC(fm,x)))); # matrices for monoid generators one:=One(mats[1]); nonone:=Filtered([1..Length(mats)],x->not IsOne(mats[x])); zero:=zerovec; @@ -1046,7 +1046,7 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, one:=One(FreeGroupOfFpGroup(fpg)); k:=List(GeneratorsOfMonoid(mon), - x->UnderlyingElement(PreImagesRepresentative(fm,x))); + x->UnderlyingElement(PreImagesRepresentativeNC(fm,x))); # matrix corresponding to monoid word mapped2:=function(list) local a,i; @@ -1124,8 +1124,8 @@ local field,fp,fpg,gens,hom,mats,fm,mon,tzrules,dim,rules,eqs,i,j,k,l,o,l1, local a; if not IsBound(imagemonwords[nr]) then # apply automorphism - a:=PreImagesRepresentative(fm,GeneratorsOfMonoid(mon)[nr]); - a:=PreImagesRepresentative(fp,a); + a:=PreImagesRepresentativeNC(fm,GeneratorsOfMonoid(mon)[nr]); + a:=PreImagesRepresentativeNC(fp,a); a:=ImagesRepresentative(autom,a); a:=ImagesRepresentative(fp,a); a:=ImagesRepresentative(fm,a); diff --git a/lib/vspchom.gi b/lib/vspchom.gi index 4b6aee7a75..daf0e145bf 100644 --- a/lib/vspchom.gi +++ b/lib/vspchom.gi @@ -485,9 +485,9 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . for left module g.m.b.i. +#M PreImagesRepresentativeNC( , ) . . . for left module g.m.b.i. ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for left module g.m.b.i., and element", FamRangeEqFamElm, [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep, @@ -1221,9 +1221,9 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentative( , ) . . . . . for left module m.b.m. +#M PreImagesRepresentativeNC( , ) . . . . for left module m.b.m. ## -InstallMethod( PreImagesRepresentative, +InstallMethod( PreImagesRepresentativeNC, "for left module m.b.m., and element", FamRangeEqFamElm, [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep, From 1f6bbafcbeb686978daeaf0db4edd4fc69da1927 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 20 May 2026 19:01:26 +0100 Subject: [PATCH 02/50] added non-NC methods so that tests pass --- lib/alghom.gi | 32 ++-- lib/alglie.gi | 14 ++ lib/field.gi | 25 +++ lib/fldabnum.gi | 35 ++++- lib/ghom.gi | 11 ++ lib/ghomfp.gi | 25 +++ lib/ghompcgs.gi | 11 ++ lib/ghomperm.gi | 11 ++ lib/gprdmat.gi | 35 +++++ lib/gprdperm.gi | 47 ++++++ lib/grpmat.gi | 12 ++ lib/grpnice.gi | 12 ++ lib/liefam.gi | 11 ++ lib/mapprep.gi | 222 ++++++++++++++++++++++++++- lib/mgmring.gi | 43 ++++++ lib/morpheus.gi | 10 ++ lib/oprt.gi | 20 +++ lib/relation.gi | 34 ++++ lib/ringhom.gi | 13 ++ lib/vspchom.gi | 24 +++ tst/testbugfix/2012-11-25-t00264.tst | 4 +- 21 files changed, 629 insertions(+), 22 deletions(-) diff --git a/lib/alghom.gi b/lib/alghom.gi index 550ac43fd6..51147d67cd 100644 --- a/lib/alghom.gi +++ b/lib/alghom.gi @@ -576,7 +576,8 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## -#M PreImagesRepresentativeNC( , ) . . . . . . for algebra g.m.b.i. +#M PreImagesRepresentativeNC( , ) . . . . . for algebra g.m.b.i. +#M PreImagesRepresentative( , ) . . . . . . for algebra g.m.b.i. ## InstallMethod( PreImagesRepresentativeNC, "for algebra g.m.b.i., and element", @@ -588,6 +589,18 @@ InstallMethod( PreImagesRepresentativeNC, AsLeftModuleGeneralMappingByImages(map), elm ); end ); +InstallMethod( PreImagesRepresentative, + "for algebra g.m.b.i., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsAlgebraGeneralMappingByImagesDefaultRep, + IsObject ], + function( map, elm ) + if not ( elm in Range( map ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); + ############################################################################# ## @@ -915,12 +928,6 @@ BindGlobal( "PreImagesRepresentativeOperationAlgebraHomomorphism", function( oph return mat; end ); -InstallMethod( PreImagesRepresentativeNC, - "for an operation algebra homomorphism, and an element", - FamRangeEqFamElm, - [ IsOperationAlgebraHomomorphismDefaultRep, IsMatrix ], - PreImagesRepresentativeOperationAlgebraHomomorphism ); - ############################################################################# ## @@ -1074,17 +1081,6 @@ InstallMethod( ImagesRepresentative, end ); -############################################################################# -## -#M PreImagesRepresentativeNC( , ) -## -InstallMethod( PreImagesRepresentativeNC, - "for an alg. hom. from f. p. algebra, and an element", - FamRangeEqFamElm, - [ IsAlgebraHomomorphismFromFpRep, IsMatrix ], - PreImagesRepresentativeOperationAlgebraHomomorphism ); - - ############################################################################# ## #M OperationAlgebraHomomorphism( , , ) diff --git a/lib/alglie.gi b/lib/alglie.gi index d3343f8fc4..d682f71459 100644 --- a/lib/alglie.gi +++ b/lib/alglie.gi @@ -4018,6 +4018,7 @@ InstallMethod( ImagesRepresentative, ########################################################################### ## #M PreImagesRepresentativeNC( f, x ) +#M PreImagesRepresentative( f, x ) ## InstallMethod( PreImagesRepresentativeNC, "for Fp to SCA mapping, and element", @@ -4095,6 +4096,19 @@ InstallMethod( PreImagesRepresentativeNC, end); +InstallMethod( PreImagesRepresentative, + "for Fp to SCA mapping, and element", + FamRangeEqFamElm, + [ IsFptoSCAMorphism, IsSCAlgebraObj ], 0, + + function( f, x ) + if not ( x in Range( f ) ) then + return fail; + fi; + return PreImagesRepresentative( f, x ); + +end ); + ############################################################################# ## #M Dimension( ) diff --git a/lib/field.gi b/lib/field.gi index a65dd50266..ff2e31c3ba 100644 --- a/lib/field.gi +++ b/lib/field.gi @@ -1316,6 +1316,7 @@ InstallMethod( ImagesSet, ############################################################################# ## #M PreImagesElmNC( , ) . . . . . . . . . . . . preimage of an elm +#M PreImagesElm( , ) . . . . . . . . . . . . . preimage of an elm ## InstallMethod( PreImagesElmNC, "for field homomorphism and element", @@ -1331,10 +1332,22 @@ InstallMethod( PreImagesElmNC, fi; end ); +InstallMethod( PreImagesElm, + "for field homomorphism and element", + FamRangeEqFamElm, + [ IsFieldHomomorphism, IsObject ], + function ( hom, elm ) + if not (elm in Range(hom)) then + return []; + fi; + return PreImagesElm( hom, elm ); + end ); ############################################################################# ## #M PreImagesSetNC +#M PreImagesSet +## InstallMethod( PreImagesSetNC, "for field homomorphism and field", CollFamRangeEqFamElms, @@ -1345,3 +1358,15 @@ InstallMethod( PreImagesSetNC, UseSubsetRelation( Source( hom ), elms ); return elms; end ); + +InstallMethod( PreImagesSet, + "for field homomorphism and field", + CollFamRangeEqFamElms, + [ IsFieldHomomorphism, IsField ], + function ( hom, elms ) + if not IsSubset( Range(hom), elms ) then + return []; + fi; + return PreImagesSet( hom, elms ); + end ); + diff --git a/lib/fldabnum.gi b/lib/fldabnum.gi index 6fb312be2d..6c5f22d030 100644 --- a/lib/fldabnum.gi +++ b/lib/fldabnum.gi @@ -1918,7 +1918,8 @@ InstallMethod( PreImageElm, ############################################################################# ## -#M PreImagesElmNC( , ) . . . . . . for autom. of ab. number fields +#M PreImagesElmNC( , ) . . . . . for autom. of ab. number fields +#M PreImagesElm( , ) . . . . . . for autom. of ab. number fields ## InstallMethod( PreImagesElmNC, "for ANF automorphism and scalar", @@ -1929,10 +1930,21 @@ InstallMethod( PreImagesElmNC, mod Conductor( Range( aut ) ) ) ]; end ); +InstallMethod( PreImagesElm, + "for ANF automorphism and scalar", + FamRangeEqFamElm, + [ IsFieldHomomorphism and IsANFAutomorphismRep, IsScalar ], + function ( aut, elm ) + if not ( elm in Range(aut) ) then + return []; + fi; + return PreImagesElmNC( aut, elm ); + end ); ############################################################################# ## #M PreImagesSetNC( , ) . . . . . for autom. of ab. number fields +#M PreImagesSet( , ) . . . . . . for autom. of ab. number fields ## InstallMethod( PreImagesSetNC, "for ANF automorphism and scalar", @@ -1942,10 +1954,21 @@ InstallMethod( PreImagesSetNC, return F; end ); +InstallMethod( PreImagesSet, + "for ANF automorphism and scalar", + CollFamRangeEqFamElms, + [ IsFieldHomomorphism and IsANFAutomorphismRep, IsField ], + function ( aut, F ) + if not IsSubset( Range(aut), F ) then + return []; + fi; + return PreImagesSetNC( aut, F ); + end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) for autom. of ab. number fields +#M PreImagesRepresentative( , ) . for autom. of ab. number fields ## InstallMethod( PreImagesRepresentativeNC, "for ANF automorphism and scalar", @@ -1956,6 +1979,16 @@ InstallMethod( PreImagesRepresentativeNC, mod Conductor( Range( aut ) ) ); end ); +InstallMethod( PreImagesRepresentative, + "for ANF automorphism and scalar", + FamRangeEqFamElm, + [ IsFieldHomomorphism and IsANFAutomorphismRep, IsScalar ], + function ( aut, elm ) + if not ( elm in Range( aut ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( aut, elm ); + end ); ############################################################################# ## diff --git a/lib/ghom.gi b/lib/ghom.gi index 8047a39206..29caa4a36b 100644 --- a/lib/ghom.gi +++ b/lib/ghom.gi @@ -254,6 +254,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . via images +#M PreImagesRepresentative( , ) . . . . . . . . . . . via images InstallMethod( PreImagesRepresentativeNC, "for PBG-Hom", FamRangeEqFamElm, [ IsPreimagesByAsGroupGeneralMappingByImages, @@ -268,6 +269,16 @@ function( hom, elm ) fi; end ); +InstallMethod( PreImagesRepresentative, "for PBG-Hom", FamRangeEqFamElm, + [ IsPreimagesByAsGroupGeneralMappingByImages, + IsMultiplicativeElementWithInverse ], 0, +function( hom, elm ) + if not ( elm in Range( hom ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( hom, elm ); +end ); + InstallAttributeMethodByGroupGeneralMappingByImages( CoKernelOfMultiplicativeGeneralMapping ); InstallAttributeMethodByGroupGeneralMappingByImages( KernelOfMultiplicativeGeneralMapping ); InstallAttributeMethodByGroupGeneralMappingByImages( PreImagesRange ); diff --git a/lib/ghomfp.gi b/lib/ghomfp.gi index fb2ce5f073..be891d7ee9 100644 --- a/lib/ghomfp.gi +++ b/lib/ghomfp.gi @@ -528,6 +528,7 @@ end); ############################################################################# ## #M PreImagesSetNC( , ) +#M PreImagesSet( , ) ## InstallMethod( PreImagesSetNC, "map from (sub)group of fp group", CollFamRangeEqFamElms, @@ -624,6 +625,16 @@ local s,gens,t,p,w,c,q,chom,tg,thom,hi,i,lp,max; return SubgroupOfWholeGroupByQuotientSubgroup(FamilyObj(s),u,Stabilizer(u,1)); end); +InstallMethod( PreImagesSet, "map from (sub)group of fp group", + CollFamRangeEqFamElms, + [ IsFromFpGroupHomomorphism,IsGroup ],0, +function(hom,u) + if not (u in Range(hom)) then + return []; + fi; + return PreImagesSetNC(hom,u); +end); + ############################################################################# ## @@ -719,6 +730,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC +#M PreImagesRepresentative ## InstallMethod( PreImagesRepresentativeNC, "hom. to standard generators of fp group, using 'MappedWord'", @@ -747,6 +759,19 @@ local mapi; return mapi; end); +InstallMethod( PreImagesRepresentative, + "hom. to standard generators of fp group, using 'MappedWord'", + FamRangeEqFamElm, + [IsToFpGroupHomomorphismByImages,IsMultiplicativeElementWithInverse], + 1, +function(hom,elm) + if not (elm in Range(hom)) then + return fail; + fi; + return PreImagesRepresentativeNC(hom,elm); +end); + + ############################################################################# ## ## methods to construct homomorphisms to fp groups diff --git a/lib/ghompcgs.gi b/lib/ghompcgs.gi index 78ba75b339..984f80f3f3 100644 --- a/lib/ghompcgs.gi +++ b/lib/ghompcgs.gi @@ -504,6 +504,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . via images +#M PreImagesRepresentative( , ) . . . . . . . . . . . via images ## InstallMethod( PreImagesRepresentativeNC, "method for pcgs hom", FamRangeEqFamElm, @@ -530,6 +531,16 @@ function( hom, elm ) return pre; end); +InstallMethod( PreImagesRepresentative, "method for pcgs hom", + FamRangeEqFamElm, + [ IsToPcGroupHomomorphismByImages,IsMultiplicativeElementWithInverse ], 0, +function( hom, elm ) + if not ( elm in Range( hom ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( hom, elm ); +end ); + ############################################################################# ## #M NaturalHomomorphismByNormalSubgroup( , ) . . . . . . for pc groups diff --git a/lib/ghomperm.gi b/lib/ghomperm.gi index 7bf4a40a70..8b5c6a79dd 100644 --- a/lib/ghomperm.gi +++ b/lib/ghomperm.gi @@ -1163,6 +1163,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . for perm group range +#M PreImagesRepresentative( , ) . . . . . . for perm group range ## InstallMethod( PreImagesRepresentativeNC, FamRangeEqFamElm, [ IsToPermGroupGeneralMappingByImages, @@ -1171,6 +1172,16 @@ InstallMethod( PreImagesRepresentativeNC, FamRangeEqFamElm, return ImagesRepresentative( RestrictedInverseGeneralMapping( hom ), elm ); end ); +InstallMethod( PreImagesRepresentative, FamRangeEqFamElm, + [ IsToPermGroupGeneralMappingByImages, + IsMultiplicativeElementWithInverse ], 0, + function( hom, elm ) + if not ( elm in Range( hom ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( hom, elm ); +end ); + ############################################################################# ## #F StabChainPermGroupToPermGroupGeneralMappingByImages( ) . . . local diff --git a/lib/gprdmat.gi b/lib/gprdmat.gi index c582173350..d73b63e568 100644 --- a/lib/gprdmat.gi +++ b/lib/gprdmat.gi @@ -144,6 +144,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC(,) . . . . . . . . . . . of embedding +#M PreImagesRepresentative(,) . . . . . . . . . . . . of embedding ## InstallMethod(PreImagesRepresentativeNC,"matrix direct product embedding", FamRangeEqFamElm, @@ -162,6 +163,17 @@ local info,a,b; fi; end); +InstallMethod(PreImagesRepresentative,"matrix direct product embedding", + FamRangeEqFamElm, + [ IsEmbeddingDirectProductMatrixGroup, + IsMultiplicativeElementWithInverse ], +function(emb,g) + if not (g in Range(emb)) then + return fail; + fi; + return PreImagesRepresentativeNC(emb,g); +end); + ############################################################################# ## #R IsProjectionDirectProductMatrixGroup() projection onto direct factor @@ -207,6 +219,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC(,) . . . . . . . . . . . of projection +#M PreImagesRepresentative(,) . . . . . . . . . . . . of projection ## InstallMethod(PreImagesRepresentativeNC,"matrix direct product projection", FamRangeEqFamElm, @@ -220,6 +233,17 @@ local info,a; return ImmutableMatrix(info.field,a); end); +InstallMethod(PreImagesRepresentative,"matrix direct product projection", + FamRangeEqFamElm, + [ IsProjectionDirectProductMatrixGroup, + IsMultiplicativeElementWithInverse ],0, +function(prj,m) + if not (m in Range(prj)) then + return fail; + fi; + return PreImagesRepresentativeNC(prj,m); +end); + ############################################################################# ## #M KernelOfMultiplicativeGeneralMapping() . . . . . . . of projection @@ -383,6 +407,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . of embedding +#M PreImagesRepresentative( , ) . . . . . . . . . . . of embedding ## InstallMethod( PreImagesRepresentativeNC, "imprim matrix wreath product embedding", FamRangeEqFamElm, @@ -401,6 +426,16 @@ local info,a,b; fi; end); +InstallMethod( PreImagesRepresentative, + "imprim matrix wreath product embedding", FamRangeEqFamElm, + [ IsEmbeddingImprimitiveWreathProductMatrixGroup, + IsMultiplicativeElementWithInverse ], 0, +function( emb, g ) + if not (g in Range(emb)) then + return fail; + fi; + return PreImagesRepresentativeNC(emb,g); +end); ############################################################################# ## diff --git a/lib/gprdperm.gi b/lib/gprdperm.gi index 36973b6b46..75583f7a0d 100644 --- a/lib/gprdperm.gi +++ b/lib/gprdperm.gi @@ -170,6 +170,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . of embedding +#M PreImagesRepresentative( , ) . . . . . . . . . . . of embedding ## InstallMethod( PreImagesRepresentativeNC, "perm direct product embedding", FamRangeEqFamElm, @@ -191,6 +192,17 @@ InstallMethod( PreImagesRepresentativeNC, "perm direct product embedding", fi; end ); +InstallMethod( PreImagesRepresentative, "perm direct product embedding", + FamRangeEqFamElm, + [ IsEmbeddingDirectProductPermGroup, + IsMultiplicativeElementWithInverse ], + function( emb, g ) + if not ( g in Range( emb ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( emb, g ); +end ); + ############################################################################# ## #M ImagesSource( ) . . . . . . . . . . . . . . . . . . . of embedding @@ -293,6 +305,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . of projection +#M PreImagesRepresentative( , ) . . . . . . . . . . . of projection ## InstallMethod( PreImagesRepresentativeNC,"perm direct product projection", FamRangeEqFamElm, @@ -302,6 +315,17 @@ InstallMethod( PreImagesRepresentativeNC,"perm direct product projection", return g ^ DirectProductInfo( Source( prj ) ).perms[ prj!.component ]; end ); +InstallMethod( PreImagesRepresentative,"perm direct product projection", + FamRangeEqFamElm, + [ IsProjectionDirectProductPermGroup, + IsMultiplicativeElementWithInverse ], 0, + function( prj, g ) + if not ( g in Range( prj ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( prj, g ); +end ); + ############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( ) . . . . . . . of projection @@ -467,6 +491,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . of projection +#M PreImagesRepresentative( , ) . . . . . . . . . . . of projection ## InstallMethod( PreImagesRepresentativeNC,"perm subdirect product projection", FamRangeEqFamElm, @@ -498,6 +523,17 @@ InstallMethod( PreImagesRepresentativeNC,"perm subdirect product projection", return elm; end ); +InstallMethod( PreImagesRepresentative,"perm subdirect product projection", + FamRangeEqFamElm, + [ IsProjectionSubdirectProductPermGroup, + IsMultiplicativeElementWithInverse ], 0, + function( prj, img ) + if not ( img in Range( prj ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( prj, img ); +end ); + ############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( ) . . . . . . . of projection @@ -800,6 +836,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . of embedding +#M PreImagesRepresentative( , ) . . . . . . . . . . . of embedding ## InstallMethod( PreImagesRepresentativeNC, "imprim perm wreath product embedding", FamRangeEqFamElm, @@ -820,6 +857,16 @@ InstallMethod( PreImagesRepresentativeNC, ^ (info.perms[ emb!.component ] ^ -1); end ); +InstallMethod( PreImagesRepresentative, + "imprim perm wreath product embedding", FamRangeEqFamElm, + [ IsEmbeddingImprimitiveWreathProductPermGroup, + IsMultiplicativeElementWithInverse ], 0, + function( emb, g ) + if not ( g in Range( emb ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( emb, g ); +end ); ############################################################################# ## diff --git a/lib/grpmat.gi b/lib/grpmat.gi index 17eae4f5e0..65104b3aa4 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -1203,6 +1203,7 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . for a blow up isomorphism +#M PreImagesRepresentative( , ) . . . . for a blow up isomorphism ## InstallMethod( PreImagesRepresentativeNC, "for a blow up isomorphism, and a matrix in the range", @@ -1257,6 +1258,17 @@ InstallMethod( PreImagesRepresentativeNC, return preim; end ); +InstallMethod( PreImagesRepresentative, + "for a blow up isomorphism, and a matrix in the range", + FamRangeEqFamElm, + [ IsBlowUpIsomorphism, IsMatrix ], + function( iso, mat ) + if not ( mat in Range(iso) ) then + return fail; + fi; + return PreImagesRepresentativeNC( iso, mat ); + end ); + ############################################################################# ## diff --git a/lib/grpnice.gi b/lib/grpnice.gi index 6e3db2bd6f..25f7d78045 100644 --- a/lib/grpnice.gi +++ b/lib/grpnice.gi @@ -973,6 +973,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . via images +#M PreImagesRepresentative( , ) . . . . . . . . . . . via images ## InstallMethod( PreImagesRepresentativeNC, "for PBG-Niceo", FamRangeEqFamElm, @@ -988,6 +989,17 @@ local p, tmp; return p; end ); +InstallMethod( PreImagesRepresentative, "for PBG-Niceo", + FamRangeEqFamElm, + [ IsPreimagesByAsGroupGeneralMappingByImages and IsNiceMonomorphism, + IsMultiplicativeElementWithInverse ], 0, +function( hom, elm ) + if not ( elm in Range(hom) ) then + return fail; + fi; + return PreImagesRepresentativeNC( hom, elm ); +end ); + ############################################################################# ## #M NiceMonomorphism( ) . . diff --git a/lib/liefam.gi b/lib/liefam.gi index ca6c3161c6..0a5590b03d 100644 --- a/lib/liefam.gi +++ b/lib/liefam.gi @@ -456,6 +456,17 @@ InstallMethod( PreImagesElmNC, return [ elm![1] ]; end ); +InstallMethod( PreImagesElm, + "for Lie embedding and Lie object in default representation", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLieEmbeddingRep, + IsLieObject and IsPackedElementDefaultRep ], 0, + function( emb, elm ) + if not ( elm in Range(emb) ) then + return []; + fi; + return PreImagesElm( emb, elm ); + end ); ############################################################################# ## diff --git a/lib/mapprep.gi b/lib/mapprep.gi index 67ea3b1233..8b3ebe6fc2 100644 --- a/lib/mapprep.gi +++ b/lib/mapprep.gi @@ -303,6 +303,7 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## #M PreImagesElmNC( , ) . . . . . . . . . for composition mapping +#M PreImagesElm( , ) . . . . . . . . . . for composition mapping ## InstallMethod( PreImagesElmNC, "for a composition mapping, and an element", @@ -318,10 +319,22 @@ InstallMethod( PreImagesElmNC, fi; end ); +InstallMethod( PreImagesElm, + "for a composition mapping, and an element", + FamRangeEqFamElm, + [ IsCompositionMappingRep, IsObject ], 0, + function( com, elm ) + if not ( elm in Range(com) ) then + return []; + fi; + return PreImagesElmNC( com, elm ); + end ); + ############################################################################# ## #M PreImagesSetNC( , ) . . . . . . . . . for composition mapping +#M PreImagesSet( , ) . . . . . . . . . . for composition mapping ## InstallMethod( PreImagesSetNC, "for a composition mapping, and a collection", @@ -337,10 +350,22 @@ InstallMethod( PreImagesSetNC, fi; end ); +InstallMethod( PreImagesSet, + "for a composition mapping, and a collection", + CollFamRangeEqFamElms, + [ IsCompositionMappingRep, IsCollection ], 0, + function( com, elms ) + if not IsSubset( Range(com), elms ) then + return []; + fi; + return PreImagesSetNC( com, elms ); + end ); + ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . for composition mapping +#M PreImagesRepresentative( , ) . . . . . for composition mapping ## InstallMethod( PreImagesRepresentativeNC, "for a composition mapping, and an element", @@ -369,6 +394,17 @@ InstallMethod( PreImagesRepresentativeNC, fi; end ); +InstallMethod( PreImagesRepresentative, + "for a composition mapping, and an element", + FamRangeEqFamElm, + [ IsCompositionMappingRep, IsObject ], 0, + function( com, elm ) + if not ( elm in Range(com) ) then + return fail; + fi; + return PreImagesRepresentativeNC( com, elm ); + end ); + ############################################################################# ## @@ -629,7 +665,8 @@ end ); ############################################################################# ## -#M PreImagesRepresentativeNC( , ) . . . . . for mapping by function +#M PreImagesRepresentativeNC( , ) . . . . for mapping by function +#M PreImagesRepresentative( , ) . . . . . for mapping by function ## InstallMethod( PreImagesRepresentativeNC, "for mapping by function", @@ -643,6 +680,17 @@ InstallMethod( PreImagesRepresentativeNC, return map!.prefun( elm ); end ); +InstallMethod( PreImagesRepresentative, + "for mapping by function", + FamRangeEqFamElm, + [ IsMappingByFunctionRep, IsObject ], 0, + function ( map, elm ) + if not ( elm in Range(map) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); + ############################################################################# ## @@ -660,6 +708,7 @@ InstallMethod( PreImageElm, ############################################################################# ## #M PreImagesElmNC( , ) . . . . . . . . . . for mapping by function +#M PreImagesElm( , ) . . . . . . . . . . . for mapping by function ## InstallMethod( PreImagesElmNC, "for mapping by function", @@ -669,9 +718,22 @@ InstallMethod( PreImagesElmNC, return [ map!.invFun( elm ) ]; end ); +InstallMethod( PreImagesElm, + "for mapping by function", + FamRangeEqFamElm, + [ IsMappingByFunctionWithInverseRep, IsObject ], 0, + function ( map, elm ) + if not ( elm in Range(map) ) then + return []; + fi; + return PreImagesElmNC( map, elm ); + end ); + + ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . for mapping by function +#M PreImagesRepresentative( , ) . . . . . for mapping by function ## InstallMethod( PreImagesRepresentativeNC, "for mapping by function with inverse", @@ -681,6 +743,16 @@ InstallMethod( PreImagesRepresentativeNC, return map!.invFun( elm ); end ); +InstallMethod( PreImagesRepresentative, + "for mapping by function with inverse", + FamRangeEqFamElm, + [ IsMappingByFunctionWithInverseRep, IsObject ], 0, + function ( map, elm ) + if not ( elm in Range(map) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); ############################################################################# @@ -1055,6 +1127,7 @@ InstallMethod( PreImageElm, ############################################################################# ## #M PreImagesElmNC( , ) . . . . for inverse mapping and element +#M PreImagesElm( , ) . . . . . for inverse mapping and element ## InstallMethod( PreImagesElmNC, "for an inverse mapping and an element", @@ -1064,10 +1137,22 @@ InstallMethod( PreImagesElmNC, return ImagesElm( InverseGeneralMapping( inv ), elm ); end ); +InstallMethod( PreImagesElm, + "for an inverse mapping and an element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, + function ( inv, elm ) + if not ( elm in Range(inv) ) then + return []; + fi; + return PreImagesElmNC( inv, elm ); + end ); + ############################################################################# ## #M PreImagesSetNC( , ) . . for inverse mapping and collection +#M PreImagesSet( , ) . . . for inverse mapping and collection ## InstallMethod( PreImagesSetNC, "for an inverse mapping and a collection", @@ -1077,10 +1162,22 @@ InstallMethod( PreImagesSetNC, return ImagesSet( InverseGeneralMapping( inv ), elms ); end ); +InstallMethod( PreImagesSet, + "for an inverse mapping and a collection", + CollFamRangeEqFamElms, + [ IsGeneralMapping and IsInverseGeneralMappingRep, IsCollection ], 0, + function ( inv, elms ) + if not IsSubset( Range(inv), elms ) then + return []; + fi; + return PreImagesSetNC( inv, elms ); + end ); + ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . for inv. mapping and elm. +#M PreImagesRepresentative( , ) . . . for inv. mapping and elm. ## InstallMethod( PreImagesRepresentativeNC, "for an inverse mapping and an element", @@ -1090,6 +1187,17 @@ InstallMethod( PreImagesRepresentativeNC, return ImagesRepresentative( InverseGeneralMapping( inv ), elm ); end ); +InstallMethod( PreImagesRepresentative, + "for an inverse mapping and an element", + FamRangeEqFamElm, + [ IsInverseGeneralMappingRep, IsObject ], 0, + function ( inv, elm ) + if not ( elm in Range(inv) ) then + return fail; + fi; + return PreImagesRepresentativeNC( inv, elm ); + end ); + ############################################################################# ## @@ -1294,6 +1402,7 @@ InstallMethod( PreImageElm, ############################################################################# ## #M PreImagesElmMC( , ) . . . for identity mapping and element +#M PreImagesElm( , ) . . . . for identity mapping and element ## InstallMethod( PreImagesElmNC, "for identity mapping and object", @@ -1304,10 +1413,23 @@ InstallMethod( PreImagesElmNC, return [ elm ]; end ); +InstallMethod( PreImagesElm, + "for identity mapping and object", + FamRangeEqFamElm, + [ IsGeneralMapping and IsOne, IsObject ], + SUM_FLAGS, # can't do better + function ( id, elm ) + if not ( elm in Range(id) ) then + return []; + fi; + return PreImagesElmNC( id, elm ); + end ); + ############################################################################# ## #M PreImagesSetNC( , ) . . for identity mapping and collection +#M PreImagesSet( , ) . . . for identity mapping and collection ## InstallMethod( PreImagesSetNC, "for identity mapping and collection", @@ -1318,10 +1440,23 @@ InstallMethod( PreImagesSetNC, return elms; end ); +InstallMethod( PreImagesSet, + "for identity mapping and collection", + CollFamRangeEqFamElms, + [ IsGeneralMapping and IsOne, IsCollection ], + SUM_FLAGS, # can't do better + function ( id, elms ) + if not IsSubset( Range(id), elms ) then + return []; + fi; + return PreImagesSetNC( id, elms ); + end ); + ############################################################################# ## #M PreImagesRepresentativeNC( , ) +#M PreImagesRepresentative( , ) ## InstallMethod( PreImagesRepresentativeNC, "for identity mapping and object", @@ -1332,6 +1467,17 @@ InstallMethod( PreImagesRepresentativeNC, return elm; end ); +InstallMethod( PreImagesRepresentative, + "for identity mapping and object", + FamRangeEqFamElm, + [ IsGeneralMapping and IsOne, IsObject ], + SUM_FLAGS, # can't do better + function ( id, elm ) + if not ( elm in Range(id) ) then + return fail; + fi; + return elm; + end ); ############################################################################# ## @@ -1582,6 +1728,7 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## #M PreImagesElmNC( , ) . . . . for zero mapping and element +#M PreImagesElm( , ) . . . . . for zero mapping and element ## InstallMethod( PreImagesElmNC, "for zero mapping and object", @@ -1595,10 +1742,22 @@ InstallMethod( PreImagesElmNC, fi; end ); +InstallMethod( PreImagesElm, + "for zero mapping and object", + FamRangeEqFamElm, + [ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, + function( zero, elm ) + if not ( elm in Range(zero) ) then + return []; + fi; + return PreImagesElmNC( zero, elm ); + end ); + ############################################################################# ## #M PreImagesSetNC( , ) . . . for zero mapping and collection +#M PreImagesSet( , ) . . . . for zero mapping and collection ## InstallMethod( PreImagesSetNC, "for zero mapping and collection", @@ -1612,10 +1771,22 @@ InstallMethod( PreImagesSetNC, fi; end ); +InstallMethod( PreImagesSet, + "for zero mapping and collection", + CollFamRangeEqFamElms, + [ IsGeneralMapping and IsZero, IsCollection ], SUM_FLAGS, + function( zero, elms ) + if not IsSubset( Range(zero), elms ) then + return []; + fi; + return PreImagesSetNC( zero, elms ); + end ); + ############################################################################# ## #M PreImagesRepresentativeNC( , ) +#M PreImagesRepresentative( , ) ## InstallMethod( PreImagesRepresentativeNC, "for zero mapping and object", @@ -1629,6 +1800,17 @@ InstallMethod( PreImagesRepresentativeNC, fi; end ); +InstallMethod( PreImagesRepresentative, + "for zero mapping and object", + FamRangeEqFamElm, + [ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, + function( zero, elm ) + if not ( elm in Range(zero) ) then + return fail; + fi; + return PreImagesRepresentativeNC( zero, elm ); + end ); + ############################################################################# ## @@ -1818,6 +2000,7 @@ end ); ############################################################################# ## #M PreImagesElmNC( , ) . . . . . . . . . for restricted mapping +#M PreImagesElm( , ) . . . . . . . . . . for restricted mapping ## InstallMethod( PreImagesElmNC, "for a restricted mapping, and an element", @@ -1831,12 +2014,24 @@ InstallMethod( PreImagesElmNC, preim:=Intersection(Source(res),preim); fi; return preim; -end ); + end ); + +InstallMethod( PreImagesElm, + "for a restricted mapping, and an element", + FamRangeEqFamElm, + [ IsGeneralRestrictedMappingRep, IsObject ], 0, + function( res, elm ) + if not ( elm in Range(res) ) then + return []; + fi; + return PreImagesElmNC( res, elm ); + end ); ############################################################################# ## #M PreImagesSetNC( , ) . . . . . . . . . for restricted mapping +#M PreImagesSet( , ) . . . . . . . . . . for restricted mapping ## InstallMethod( PreImagesSetNC, "for a restricted mapping, and a collection", @@ -1852,10 +2047,22 @@ InstallMethod( PreImagesSetNC, return preim; end ); +InstallMethod( PreImagesSet, + "for a restricted mapping, and a collection", + CollFamRangeEqFamElms, + [ IsGeneralRestrictedMappingRep, IsCollection ], 0, + function( res, elms ) + if not IsSubset( Range(res), elms ) then + return []; + fi; + return PreImagesSetNC( res, elms ); + end ); + ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . for restricted mapping +#M PreImagesRepresentative( , ) . . . . . for restricted mapping ## InstallMethod( PreImagesRepresentativeNC, "for a restricted mapping, and an element", @@ -1877,6 +2084,17 @@ InstallMethod( PreImagesRepresentativeNC, fi; end ); +InstallMethod( PreImagesRepresentative, + "for a restricted mapping, and an element", + FamRangeEqFamElm, + [ IsGeneralRestrictedMappingRep, IsObject ], 0, + function( res, elm ) + if not ( elm in Range(res) ) then + return fail; + fi; + return PreImagesRepresentativeNC( res, elm ); + end ); + ############################################################################# ## diff --git a/lib/mgmring.gi b/lib/mgmring.gi index f7a4688a36..d4d0771b79 100644 --- a/lib/mgmring.gi +++ b/lib/mgmring.gi @@ -1236,6 +1236,17 @@ InstallMethod( PreImagesElmNC, fi; end ); +InstallMethod( PreImagesElm, + "for embedding of ring into magma ring, and free magma ring element", + FamRangeEqFamElm, + [ IsEmbeddingRingMagmaRing, IsElementOfFreeMagmaRing ], + function ( emb, elm ) + if not ( elm in Range( emb ) ) then + return fail; + fi; + return PreImagesElm( emb, elm ); + end ); + InstallMethod( PreImagesRepresentativeNC, "for embedding of ring into magma ring, and free magma ring element", FamRangeEqFamElm, @@ -1252,6 +1263,17 @@ InstallMethod( PreImagesRepresentativeNC, fi; end ); +InstallMethod( PreImagesRepresentative, + "for embedding of ring into magma ring, and free magma ring element", + FamRangeEqFamElm, + [ IsEmbeddingRingMagmaRing, IsElementOfFreeMagmaRing ], + function ( emb, elm ) + if not ( elm in Range( emb ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( emb, elm ); + end ); + ############################################################################# ## @@ -1340,6 +1362,17 @@ InstallMethod( PreImagesElmNC, fi; end ); +InstallMethod( PreImagesElm, + "for embedding of magma into magma ring, and free magma ring element", + FamRangeEqFamElm, + [ IsEmbeddingMagmaMagmaRing, IsElementOfFreeMagmaRing ], + function ( emb, elm ) + if not ( elm in Range( emb ) ) then + return fail; + fi; + return PreImagesElmNC( emb, elm ); + end ); + InstallMethod( PreImagesRepresentativeNC, "for embedding of magma into magma ring, and free magma ring element", FamRangeEqFamElm, @@ -1356,6 +1389,16 @@ InstallMethod( PreImagesRepresentativeNC, fi; end ); +InstallMethod( PreImagesRepresentative, + "for embedding of magma into magma ring, and free magma ring element", + FamRangeEqFamElm, + [ IsEmbeddingMagmaMagmaRing, IsElementOfFreeMagmaRing ], + function ( emb, elm ) + if not ( elm in Range( emb ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( emb, elm ); + end ); ############################################################################# ## diff --git a/lib/morpheus.gi b/lib/morpheus.gi index 9cb2957e14..a440d864fc 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -1071,6 +1071,7 @@ end); ############################################################################# ## #M PreImagesRepresentativeNC for OpHomAutomGrp +#M PreImagesRepresentative. for OpHomAutomGrp ## InstallMethod(PreImagesRepresentativeNC,"AutomGroup Niceomorphism", FamRangeEqFamElm,[IsActionHomomorphismAutomGroup,IsPerm],0, @@ -1086,6 +1087,15 @@ local xset,g,imgs; return elm; end); +InstallMethod(PreImagesRepresentative,"AutomGroup Niceomorphism", + FamRangeEqFamElm,[IsActionHomomorphismAutomGroup,IsPerm],0, +function(hom,elm) + if not (elm in Range(hom)) then + return fail; + fi; + return PreImagesRepresentativeNC(hom,elm); +end); + ############################################################################# ## diff --git a/lib/oprt.gi b/lib/oprt.gi index 9d12954fef..2a36087133 100644 --- a/lib/oprt.gi +++ b/lib/oprt.gi @@ -3375,6 +3375,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . build matrix +#M PreImagesRepresentative( , ) . . . . . . . . . . build matrix ## InstallMethod( PreImagesRepresentativeNC,"IsLinearActionHomomorphism", FamRangeEqFamElm, [ IsLinearActionHomomorphism, IsPerm ], 0, @@ -3418,9 +3419,19 @@ function( hom, elm ) return hom!.linActInverse*elm; end ); +InstallMethod( PreImagesRepresentative,"IsLinearActionHomomorphism", + FamRangeEqFamElm, [ IsLinearActionHomomorphism, IsPerm ], 0, +function( hom, elm ) + if not ( elm in Range( hom ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( hom, elm ); +end ); + ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . build matrix +#M PreImagesRepresentative( , ) . . . . . . . . . . build matrix ## ## The idea is as follows. ## We have an $F$-basis $(v_1, \ldots, v_n)$. @@ -3493,6 +3504,15 @@ function( hom, elm ) return MakeImmutable( mat ); end); +InstallMethod( PreImagesRepresentative,"IsProjectiveActionHomomorphism", + FamRangeEqFamElm, [ IsProjectiveActionHomomorphism, IsPerm ], 0, +function( hom, elm ) + if not ( elm in Range( hom ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( hom, elm ); +end); + ############################################################################# ## #A LinearActionBasis() diff --git a/lib/relation.gi b/lib/relation.gi index 115e5409ae..e349d50d5e 100644 --- a/lib/relation.gi +++ b/lib/relation.gi @@ -984,6 +984,7 @@ InstallMethod(ImagesElm, ############################################################################# ## #M PreImagesElmNC( , ) +#M PreImagesElm( , ) ## ## For binary relations over [1..n] represented as a list of images ## @@ -995,6 +996,16 @@ InstallMethod(PreImagesElmNC, i->n in Successors(rel)[i]); end); +InstallMethod(PreImagesElm, + "for binary rels over [1..n] with images list", + true, [IsBinaryRelation and IsBinaryRelationOnPointsRep, IsPosInt], 0, + function( rel, n ) + if not ( n in Range(rel) ) then + return []; + fi; + return PreImagesElm( rel, n ); + end ); + ############################################################################# ## #A Successors( ) @@ -1782,6 +1793,7 @@ InstallMethod( ImagesRepresentative, "equivalence relations", ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . for equivalence relations +#M PreImagesRepresentative( , ) . . . . for equivalence relations ## InstallMethod( PreImagesRepresentativeNC, "equivalence relations", FamRangeEqFamElm, [IsEquivalenceRelation, IsObject], 0, @@ -1789,6 +1801,15 @@ InstallMethod( PreImagesRepresentativeNC, "equivalence relations", return elm; end); +InstallMethod( PreImagesRepresentative, "equivalence relations", + FamRangeEqFamElm, [IsEquivalenceRelation, IsObject], 0, + function( map, elm ) + if not ( elm in Range(map) ) then + return fail; + fi; + return elm; + end); + ############################################################################# ## #M ImagesElm( , ) for equivalence relations with partition @@ -1814,6 +1835,7 @@ InstallMethod( ImagesElm, ############################################################################# ## #M PreImagesElmNC( , ) . for equivalence relations with partition +#M PreImagesElm( , ) . . for equivalence relations with partition ## InstallMethod( PreImagesElmNC, "equivalence relations with partition and element", @@ -1826,6 +1848,18 @@ InstallMethod( PreImagesElmNC, return ImagesElm(rel, elm); end); +InstallMethod( PreImagesElm, + "equivalence relations with partition and element", + FamRangeEqFamElm, + [IsEquivalenceRelation and HasEquivalenceRelationPartition, + IsObject],0, + function( rel, elm ) + if not ( elm in Range( rel ) ) then ##?? is there a Range(rel)? + return []; + fi; + return PreImagesElmNC( rel, elm ); + end); + ############################################################################# ## #M PrintObj( ) for equivalence relation diff --git a/lib/ringhom.gi b/lib/ringhom.gi index 2dc8ab4bb7..6377e0ceec 100644 --- a/lib/ringhom.gi +++ b/lib/ringhom.gi @@ -445,6 +445,7 @@ end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . for ring g.m.b.i. +#M PreImagesRepresentative( , ) . . . . . . . for ring g.m.b.i. ## InstallMethod( PreImagesRepresentativeNC, "for ring g.m.b.i., and element", @@ -455,6 +456,18 @@ function( map, elm ) return ImagesRepresentative(InverseGeneralMapping(map),elm); end ); +InstallMethod( PreImagesRepresentative, + "for ring g.m.b.i., and element", + FamRangeEqFamElm, + [ IsRingGeneralMapping and IsRingGeneralMappingByImagesDefaultRep, + IsObject ], +function( map, elm ) + if not ( elm in Range( map ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); +end ); + BindGlobal("IsomorphismSCRing",function(R) local e, z, one, o, sel, g, go, elms, dec, p, cands, m, a, b, nr, hom, i, j; if Size(R)>100000 then diff --git a/lib/vspchom.gi b/lib/vspchom.gi index daf0e145bf..7fe397f6bd 100644 --- a/lib/vspchom.gi +++ b/lib/vspchom.gi @@ -485,6 +485,7 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## +#M PreImagesRepresentative( , ) . . . . for left module g.m.b.i. #M PreImagesRepresentativeNC( , ) . . . for left module g.m.b.i. ## InstallMethod( PreImagesRepresentativeNC, @@ -503,6 +504,17 @@ InstallMethod( PreImagesRepresentativeNC, return LinearCombination( map!.preimagesbasisimage, elm ); end ); +InstallMethod( PreImagesRepresentative, + "for left module g.m.b.i., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsObject ], + function( map, elm ) + if not ( elm in Image( map ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); ############################################################################# ## @@ -1239,6 +1251,18 @@ InstallMethod( PreImagesRepresentativeNC, return LinearCombination( map!.preimagesbasisimage, elm ); end ); +InstallMethod( PreImagesRepresentative, + "for left module m.b.m., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep, + IsObject ], + function( map, elm ) + if not ( elm in Image( map ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); + ############################################################################# ## diff --git a/tst/testbugfix/2012-11-25-t00264.tst b/tst/testbugfix/2012-11-25-t00264.tst index 29e0fb14ee..754b367a0d 100644 --- a/tst/testbugfix/2012-11-25-t00264.tst +++ b/tst/testbugfix/2012-11-25-t00264.tst @@ -5,5 +5,7 @@ gap> f := FreeGroup(2); gap> iso:=GroupHomomorphismByImagesNC(f,f,[f.1*f.2,f.1*f.2^2],[f.2^2*f.1,f.2*f.1]); [ f1*f2, f1*f2^2 ] -> [ f2^2*f1, f2*f1 ] gap> SetIsSurjective(iso,true); -gap> Image(iso,PreImagesRepresentative(iso,f.1)); +gap> Image(iso,PreImagesRepresentativeNC(iso,f.1)); f1 +## (20/05/26): gap> Image(iso,PreImagesRepresentative(iso,f.1)); +## cannot be made to work because the code for the NC version is in a package From 5b98560c50db5dbe760147f5a7eb4bcee53def23 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 20 May 2026 19:44:30 +0100 Subject: [PATCH 03/50] adjust documentation in mapping.gd --- lib/mapping.gd | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/lib/mapping.gd b/lib/mapping.gd index 70c0be49a0..497fe25b85 100644 --- a/lib/mapping.gd +++ b/lib/mapping.gd @@ -751,7 +751,7 @@ DeclareAttribute( "ImagesSource", IsGeneralMapping ); ## ## is the set of preimages of the range of the general mapping map. ##

-## delegates to , +## delegates to , ## it is introduced only to store the preimage of map as attribute ## value. ## @@ -977,16 +977,17 @@ DeclareGlobalFunction( "Images" ); ## ## ## If elm is an element of the range of the general mapping -## map then returns the set of all +## map then returns the set of all ## preimages of elm under map. ##

-## Anything may happen if elm is not an element of the range of -## map. -##

-## In order to improve this state of affairs, -## PreImagesElm has been renamed PreImagesElmNC +## From &GAP; version 4.16.0 +## PreImagesElm was renamed PreImagesElmNC ## throughout the library, and PreImagesElm now checks that ## elm is an element of the range before calling PreImagesElmNC. +##

+## When using PreImagesElmNC anything may happen if elm +## is not an element of the range of map. +##

## ## ## <#/GAPDoc> @@ -1036,13 +1037,14 @@ DeclareOperation( "PreImageElm", ## fail, the latter if and only if elm ## has no preimages under map. ##

-## Anything may happen if elm is not an element of the range of -## map. -##

-## In order to improve this state of affairs, PreImagesRepresentative -## has been renamed PreImagesRepresentativeNC throughout the library, +## From &GAP; version 4.16.0 PreImagesRepresentative +## was renamed PreImagesRepresentativeNC throughout the library, ## and PreImagesRepresentative now checks that elm is an ## element of the range before calling PreImagesRepresentativeNC. +##

+## When using PreImagesRepresentativeNC anything may happen if +## elm is not an element of the range of map. +##

## ## ## <#/GAPDoc> @@ -1066,13 +1068,14 @@ DeclareOperation( "PreImagesRepresentativeNC", [ IsGeneralMapping, IsObject ] ); ## then returns the set of all preimages of ## elms under map. ##

-## Anything may happen if elms is not a subset of the range of -## map. -##

-## In order to improve this state of affairs, PreImagesSet +## From &GAP; version 4.16.0 PreImagesSet ## has been renamed PreImagesSetNC throughout the library, -## and PreImagesSet now checks that elm is an -## element of the range before calling PreImagesSetNC. +## and PreImagesSet now checks that elms is a +## subset of the range before calling PreImagesSetNC. +##

+## When using PreImagesSetNC anything may happen if elms +## is not a subset of the range of map. +##

## ## ## <#/GAPDoc> @@ -1182,15 +1185,18 @@ DeclareGlobalFunction( "PreImage" ); ## entries do in general not correspond.) ##

## -## delegates to when -## called with one argument, +## delegates to when called with one argument, ## and to resp. when ## called with two arguments. ##

-## In order to improve this state of affairs, PreImages +## From &GAP; version 4.16.0 PreImages ## has been renamed PreImagesNC throughout the library, ## and PreImages now checks that elm or coll ## belong to the range before calling PreImagesNC. +##

+## When using PreImagesNC anything may happen if elm +## or coll do not belong to the range of map. +##

## ## ## <#/GAPDoc> From 9fd69482998f54a7089217683471621b0db2fc4d Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 21 May 2026 10:12:07 +0100 Subject: [PATCH 04/50] replace items deleted in error in alghom.gi --- lib/alghom.gi | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/lib/alghom.gi b/lib/alghom.gi index 51147d67cd..15af8ea48d 100644 --- a/lib/alghom.gi +++ b/lib/alghom.gi @@ -916,6 +916,7 @@ InstallMethod( ImagesRepresentative, ############################################################################# ## #M PreImagesRepresentativeNC( , ) +#M PreImagesRepresentative( , ) ## BindGlobal( "PreImagesRepresentativeOperationAlgebraHomomorphism", function( ophom, mat ) if not IsBound( ophom!.basisImage ) then @@ -928,6 +929,22 @@ BindGlobal( "PreImagesRepresentativeOperationAlgebraHomomorphism", function( oph return mat; end ); +InstallMethod( PreImagesRepresentativeNC, + "for an operation algebra homomorphism, and an element", + FamRangeEqFamElm, + [ IsOperationAlgebraHomomorphismDefaultRep, IsMatrix ], + PreImagesRepresentativeOperationAlgebraHomomorphism ); + +InstallMethod( PreImagesRepresentative, + "for an operation algebra homomorphism, and an element", + FamRangeEqFamElm, + [ IsOperationAlgebraHomomorphismDefaultRep, IsMatrix ], + function( ophom, mat ) + if not ( mat in Range( ophom ) ) then + return fail; + fi; + return PreImagesRepresentativeOperationAlgebraHomomorphism( ophom, mat ); +end ); ############################################################################# ## @@ -1081,6 +1098,28 @@ InstallMethod( ImagesRepresentative, end ); +############################################################################# +## +#M PreImagesRepresentativeNC( , ) +#M PreImagesRepresentative( , ) +## +InstallMethod( PreImagesRepresentativeNC, + "for an alg. hom. from f. p. algebra, and an element", + FamRangeEqFamElm, + [ IsAlgebraHomomorphismFromFpRep, IsMatrix ], + PreImagesRepresentativeOperationAlgebraHomomorphism ); + +InstallMethod( PreImagesRepresentativeNC, + "for an alg. hom. from f. p. algebra, and an element", + FamRangeEqFamElm, + [ IsAlgebraHomomorphismFromFpRep, IsMatrix ], + function( ophom, mat ); + if not ( mat in Range( ophom ) ) then + return fail; + fi; + return PreImagesRepresentativeOperationAlgebraHomomorphism( ophom, mat ); + end ); + ############################################################################# ## #M OperationAlgebraHomomorphism( , , ) From 8481a3940d74be25ee6a1ebe1144bd986bb608db Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 21 May 2026 10:17:20 +0100 Subject: [PATCH 05/50] applied fix from stertooy --- lib/ghomfp.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ghomfp.gi b/lib/ghomfp.gi index be891d7ee9..fc045d8289 100644 --- a/lib/ghomfp.gi +++ b/lib/ghomfp.gi @@ -629,7 +629,7 @@ InstallMethod( PreImagesSet, "map from (sub)group of fp group", CollFamRangeEqFamElms, [ IsFromFpGroupHomomorphism,IsGroup ],0, function(hom,u) - if not (u in Range(hom)) then + if not IsSubset( Range(hom), u ) then return []; fi; return PreImagesSetNC(hom,u); From a8e5012e65dbd52f1fb334e5ddfa496839ca404d Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 21 May 2026 17:46:20 +0100 Subject: [PATCH 06/50] minor correction --- lib/alghom.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/alghom.gi b/lib/alghom.gi index 15af8ea48d..b28b163047 100644 --- a/lib/alghom.gi +++ b/lib/alghom.gi @@ -1109,7 +1109,7 @@ InstallMethod( PreImagesRepresentativeNC, [ IsAlgebraHomomorphismFromFpRep, IsMatrix ], PreImagesRepresentativeOperationAlgebraHomomorphism ); -InstallMethod( PreImagesRepresentativeNC, +InstallMethod( PreImagesRepresentative, "for an alg. hom. from f. p. algebra, and an element", FamRangeEqFamElm, [ IsAlgebraHomomorphismFromFpRep, IsMatrix ], From 168d9176686da36b09a663b0942f2fee5d295ef4 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 21 May 2026 18:36:32 +0100 Subject: [PATCH 07/50] another adjustment to bugfix test --- tst/testbugfix/2012-11-25-t00264.tst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tst/testbugfix/2012-11-25-t00264.tst b/tst/testbugfix/2012-11-25-t00264.tst index 754b367a0d..3d570f79c5 100644 --- a/tst/testbugfix/2012-11-25-t00264.tst +++ b/tst/testbugfix/2012-11-25-t00264.tst @@ -1,5 +1,7 @@ # 2012/11/25 (AK) # Fix of a bug that was reproducible in GAP 4.5.6 with FGA 1.1.1 +# (20/05/26): gap> Image(iso,PreImagesRepresentative(iso,f.1)); +# cannot be made to work because the code for the NC version is in a package gap> f := FreeGroup(2); gap> iso:=GroupHomomorphismByImagesNC(f,f,[f.1*f.2,f.1*f.2^2],[f.2^2*f.1,f.2*f.1]); @@ -7,5 +9,3 @@ gap> iso:=GroupHomomorphismByImagesNC(f,f,[f.1*f.2,f.1*f.2^2],[f.2^2*f.1,f.2*f.1 gap> SetIsSurjective(iso,true); gap> Image(iso,PreImagesRepresentativeNC(iso,f.1)); f1 -## (20/05/26): gap> Image(iso,PreImagesRepresentative(iso,f.1)); -## cannot be made to work because the code for the NC version is in a package From e61b7cb1de91e747a9c1d1fcd9071d55ef31607f Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 19 May 2026 19:55:29 +0200 Subject: [PATCH 08/50] PackageVariablesInfo: better support variadic functions (#6404) Teach args helper about multi-arg variadic functions. --- lib/package.gi | 9 +++++---- tst/mockpkg/gap/mockpkg.gi | 4 ++++ tst/testinstall/package.tst | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/package.gi b/lib/package.gi index 1930c9d6fd..a4b404027e 100644 --- a/lib/package.gi +++ b/lib/package.gi @@ -3348,12 +3348,13 @@ InstallGlobalFunction( PackageVariablesInfo, function( pkgname, version ) fi; num:= NumberArgumentsFunction( func ); nam:= NamesLocalVariablesFunction( func ); - if num = -1 then - str:= "arg"; - elif nam = fail then + if nam = fail then str:= "..."; else - str:= JoinStringsWithSeparator( nam{ [ 1 .. num ] }, ", " ); + str:= JoinStringsWithSeparator( nam{ [ 1 .. AbsInt(num) ] }, ", " ); + if num < 0 then + Append( str, "..." ); + fi; fi; return Concatenation( "( ", str, " )" ); end; diff --git a/tst/mockpkg/gap/mockpkg.gi b/tst/mockpkg/gap/mockpkg.gi index 3bcefc9c79..9ef3c4719a 100644 --- a/tst/mockpkg/gap/mockpkg.gi +++ b/tst/mockpkg/gap/mockpkg.gi @@ -13,3 +13,7 @@ InstallMethod( mockpkg_Operation, [ IsGroup, IsPosInt ], { G, n } -> n ); InstallMethod( mockpkg_Attribute, [ IsSolvableGroup ], G -> G ); InstallMethod( mockpkg_Property, [ IsNilpotentGroup ], IsAbelian ); + +BindGlobal( "mockpkg_Vararg", function(first, rest...) + return Concatenation([first], rest); +end ); diff --git a/tst/testinstall/package.tst b/tst/testinstall/package.tst index 2b1a5d6e84..48df3fbf39 100644 --- a/tst/testinstall/package.tst +++ b/tst/testinstall/package.tst @@ -450,9 +450,10 @@ new global functions: new global variables: mockpkg_ExtensionData* + mockpkg_Vararg( first, rest... )* new operations: - mockpkg_Operation( arg )* + mockpkg_Operation( ... )* new attributes: mockpkg_Attribute( ... )* From f496cdae391b87efd32a03148d8488bd89bf6673 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 21 May 2026 16:45:42 +0200 Subject: [PATCH 09/50] kernel: strengthen vecgf2 and vec8bit validation, reject empty vectors were not supported (#6401) Add runtime argument checks to the user-facing GF2 and 8-bit kernel entry points instead of relying on debug-only assertions or unchecked representation assumptions. Use shared Require helpers for compressed vectors and matrices, and tighten plain-list validation where these entry points expect list-backed inputs. Harden the exported vec8bit kernel entry points that assumed a first row existed, and fix SHIFT_VEC8BIT_RIGHT for empty compressed vectors. AI assistance from OpenAI Codex helped prepare these kernel validation changes. Co-authored-by: Codex --- src/vec8bit.c | 187 ++++- src/vecgf2.c | 158 +++- src/vecgf2.h | 8 + tst/testinstall/kernel/vec8bit.tst | 1187 ++++++++++++++++++++++++++++ tst/testinstall/kernel/vecgf2.tst | 973 ++++++++++++++++++++++- 5 files changed, 2459 insertions(+), 54 deletions(-) diff --git a/src/vec8bit.c b/src/vec8bit.c index 9137672f8c..3b50507c67 100644 --- a/src/vec8bit.c +++ b/src/vec8bit.c @@ -60,6 +60,10 @@ RequireArgumentCondition(funcname, op, IS_MAT8BIT_REP(op), \ "must belong to Is8BitMatrixRep") +#define RequireFFE(funcname, op) \ + RequireArgumentCondition(funcname, op, IS_FFE(op), \ + "must be a finite field element") + /**************************************************************************** ** *F IS_VEC8BIT_REP( ) . . . check that is in 8bit GFQ vector rep @@ -815,6 +819,7 @@ static UInt LcmDegree(UInt d, UInt d1) */ static Obj FuncCONV_VEC8BIT(Obj self, Obj list, Obj q) { + RequireSmallList(SELF_NAME, list); UInt iq = GetPositiveSmallInt(SELF_NAME, q); ConvVec8Bit(list, iq); return 0; @@ -937,6 +942,7 @@ static Obj NewVec8Bit(Obj list, UInt q) */ static Obj FuncCOPY_VEC8BIT(Obj self, Obj list, Obj q) { + RequireSmallList(SELF_NAME, list); UInt iq = GetPositiveSmallInt(SELF_NAME, q); return NewVec8Bit(list, iq); } @@ -1019,9 +1025,7 @@ void PlainVec8Bit(Obj list) */ static Obj FuncPLAIN_VEC8BIT(Obj self, Obj list) { - if (!IS_VEC8BIT_REP(list)) { - RequireArgument(SELF_NAME, list, "must be an 8bit vector"); - } + RequireVec8BitRep(SELF_NAME, list); if (DoFilter(IsLockedRepresentationVector, list) == True) { ErrorMayQuit("Cannot convert a locked vector compressed over " "GF(%d) to a plain list", @@ -1214,8 +1218,8 @@ static Obj ConvertToVectorRep; // BH: changed to static static Obj FuncSUM_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) { - GAP_ASSERT(IS_VEC8BIT_REP(vl)); - GAP_ASSERT(IS_VEC8BIT_REP(vr)); + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); Obj sum; if (FIELD_VEC8BIT(vl) != FIELD_VEC8BIT(vr)) { @@ -1395,6 +1399,9 @@ static Obj FuncPROD_VEC8BIT_FFE(Obj self, Obj vec, Obj ffe) Obj info; UInt d; + RequireVec8BitRep(SELF_NAME, vec); + RequireFFE(SELF_NAME, ffe); + if (VAL_FFE(ffe) == 1) { // ffe is the one return CopyVec8Bit(vec, IS_MUTABLE_OBJ(vec)); } @@ -1427,6 +1434,7 @@ static Obj FuncPROD_VEC8BIT_FFE(Obj self, Obj vec, Obj ffe) static Obj FuncZERO_VEC8BIT(Obj self, Obj vec) { + RequireVec8BitRep(SELF_NAME, vec); return ZeroVec8Bit(FIELD_VEC8BIT(vec), LEN_VEC8BIT(vec), 1); } @@ -1456,6 +1464,8 @@ static Obj FuncZERO_VEC8BIT_2(Obj self, Obj q, Obj len) static Obj FuncPROD_FFE_VEC8BIT(Obj self, Obj ffe, Obj vec) { + RequireFFE(SELF_NAME, ffe); + RequireVec8BitRep(SELF_NAME, vec); return FuncPROD_VEC8BIT_FFE(self, vec, ffe); } @@ -1492,16 +1502,19 @@ static Obj AInvVec8Bit(Obj vec, UInt mut) static Obj FuncAINV_VEC8BIT_MUTABLE(Obj self, Obj vec) { + RequireVec8BitRep(SELF_NAME, vec); return AInvVec8Bit(vec, 1); } static Obj FuncAINV_VEC8BIT_SAME_MUTABILITY(Obj self, Obj vec) { + RequireVec8BitRep(SELF_NAME, vec); return AInvVec8Bit(vec, IS_MUTABLE_OBJ(vec)); } static Obj FuncAINV_VEC8BIT_IMMUTABLE(Obj self, Obj vec) { + RequireVec8BitRep(SELF_NAME, vec); return AInvVec8Bit(vec, 0); } @@ -1608,6 +1621,8 @@ static void AddVec8BitVec8BitMultInner( static Obj FuncMULT_VECTOR_VEC8BITS(Obj self, Obj vec, Obj mul) { + RequireVec8BitRep(SELF_NAME, vec); + RequireFFE(SELF_NAME, mul); UInt q; q = FIELD_VEC8BIT(vec); @@ -1646,6 +1661,11 @@ static Obj AddRowVector; static Obj FuncADD_ROWVECTOR_VEC8BITS_5( Obj self, Obj vl, Obj vr, Obj mul, Obj from, Obj to) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); + RequireFFE(SELF_NAME, mul); + RequirePositiveSmallInt(SELF_NAME, from); + RequirePositiveSmallInt(SELF_NAME, to); UInt q; UInt len; len = LEN_VEC8BIT(vl); @@ -1720,6 +1740,9 @@ static Obj FuncADD_ROWVECTOR_VEC8BITS_5( static Obj FuncADD_ROWVECTOR_VEC8BITS_3(Obj self, Obj vl, Obj vr, Obj mul) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); + RequireFFE(SELF_NAME, mul); UInt q; if (LEN_VEC8BIT(vl) != LEN_VEC8BIT(vr)) { ErrorMayQuit( @@ -1778,6 +1801,8 @@ static Obj FuncADD_ROWVECTOR_VEC8BITS_3(Obj self, Obj vl, Obj vr, Obj mul) static Obj FuncADD_ROWVECTOR_VEC8BITS_2(Obj self, Obj vl, Obj vr) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); UInt q; if (LEN_VEC8BIT(vl) != LEN_VEC8BIT(vr)) { ErrorMayQuit( @@ -1913,6 +1938,8 @@ static Obj FuncDIFF_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) Obj diff; // UInt p; + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); if (FIELD_VEC8BIT(vl) != FIELD_VEC8BIT(vr)) { UInt ql = FIELD_VEC8BIT(vl), qr = FIELD_VEC8BIT(vr); @@ -2086,6 +2113,8 @@ static Obj ScalarProductVec8Bits(Obj vl, Obj vr) static Obj FuncPROD_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); if (FIELD_VEC8BIT(vl) != FIELD_VEC8BIT(vr)) return ProdListList(vl, vr); @@ -2146,6 +2175,8 @@ static UInt DistanceVec8Bits(Obj vl, Obj vr) static Obj FuncDISTANCE_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); if (FIELD_VEC8BIT(vl) != FIELD_VEC8BIT(vr) || LEN_VEC8BIT(vl) != LEN_VEC8BIT(vr)) return TRY_NEXT_METHOD; @@ -2215,6 +2246,10 @@ static Obj FuncDISTANCE_DISTRIB_VEC8BITS( UInt len; UInt q; + RequirePlainList(SELF_NAME, veclis); + RequireVec8BitRep(SELF_NAME, vec); + RequirePlainList(SELF_NAME, d); + len = LEN_VEC8BIT(vec); q = FIELD_VEC8BIT(vec); @@ -2331,6 +2366,8 @@ static Obj FuncA_CLOSEST_VEC8BIT( UInt len; UInt q; + RequirePlainList(SELF_NAME, veclis); + RequireVec8BitRep(SELF_NAME, vec); RequireNonnegativeSmallInt(SELF_NAME, cnt); RequireNonnegativeSmallInt(SELF_NAME, stop); @@ -2371,6 +2408,8 @@ static Obj FuncA_CLOSEST_VEC8BIT_COORDS( Obj res; + RequirePlainList(SELF_NAME, veclis); + RequireVec8BitRep(SELF_NAME, vec); RequireNonnegativeSmallInt(SELF_NAME, cnt); RequireNonnegativeSmallInt(SELF_NAME, stop); @@ -2413,6 +2452,7 @@ static Obj FuncA_CLOSEST_VEC8BIT_COORDS( static Obj FuncNUMBER_VEC8BIT(Obj self, Obj vec) { + RequireVec8BitRep(SELF_NAME, vec); Obj info; UInt elts; UInt len; @@ -2608,6 +2648,7 @@ static Obj FuncCOSET_LEADERS_INNER_8BITS( RequireSmallInt(SELF_NAME, weight); RequireSmallInt(SELF_NAME, tofind); RequirePlainList(SELF_NAME, leaders); + RequirePlainList(SELF_NAME, felts); lenv = LEN_PLIST(veclis); q = LEN_PLIST(felts); @@ -2628,6 +2669,8 @@ static Obj FuncCOSET_LEADERS_INNER_8BITS( static Obj FuncEQ_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); if (FIELD_VEC8BIT(vl) != FIELD_VEC8BIT(vr)) return EqListList(vl, vr) ? True : False; @@ -2645,6 +2688,8 @@ static Obj FuncEQ_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) static Obj FuncLT_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) { + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); if (FIELD_VEC8BIT(vl) != FIELD_VEC8BIT(vr)) return LtListList(vl, vr) ? True : False; @@ -2665,6 +2710,7 @@ static Obj FuncLT_VEC8BIT_VEC8BIT(Obj self, Obj vl, Obj vr) static Obj FuncSHALLOWCOPY_VEC8BIT(Obj self, Obj list) { + RequireVec8BitRep(SELF_NAME, list); return CopyVec8Bit(list, 1); } @@ -2675,6 +2721,7 @@ static Obj FuncSHALLOWCOPY_VEC8BIT(Obj self, Obj list) */ static Obj FuncLEN_VEC8BIT(Obj self, Obj list) { + RequireVec8BitRep(SELF_NAME, list); return INTOBJ_INT(LEN_VEC8BIT(list)); } @@ -2684,6 +2731,7 @@ static Obj FuncLEN_VEC8BIT(Obj self, Obj list) */ static Obj FuncQ_VEC8BIT(Obj self, Obj list) { + RequireVec8BitRep(SELF_NAME, list); return INTOBJ_INT(FIELD_VEC8BIT(list)); } @@ -2704,6 +2752,7 @@ static Obj FuncELM0_VEC8BIT(Obj self, Obj list, Obj pos) Obj info; UInt elts; + RequireVec8BitRep(SELF_NAME, list); p = GetPositiveSmallInt(SELF_NAME, pos); if (LEN_VEC8BIT(list) < p) { return Fail; @@ -2733,6 +2782,7 @@ static Obj FuncELM_VEC8BIT(Obj self, Obj list, Obj pos) Obj info; UInt elts; + RequireVec8BitRep(SELF_NAME, list); p = GetPositiveSmallInt(SELF_NAME, pos); if (LEN_VEC8BIT(list) < p) { ErrorMayQuit("List Element: [%d] must have an assigned value", @@ -2773,6 +2823,8 @@ static Obj FuncELMS_VEC8BIT(Obj self, Obj list, Obj poss) UInt1 byte; UInt len2; + RequireVec8BitRep(SELF_NAME, list); + RequirePlainList(SELF_NAME, poss); len = LEN_PLIST(poss); info = GetFieldInfo8Bit(FIELD_VEC8BIT(list)); len2 = LEN_VEC8BIT(list); @@ -2840,6 +2892,9 @@ static Obj FuncELMS_VEC8BIT_RANGE(Obj self, Obj list, Obj range) UInt e; UInt1 byte; + RequireVec8BitRep(SELF_NAME, list); + RequireArgumentCondition(SELF_NAME, range, IS_RANGE(range), "must be a range"); + info = GetFieldInfo8Bit(FIELD_VEC8BIT(list)); elts = ELS_BYTE_FIELDINFO_8BIT(info); len = GET_LEN_RANGE(range); @@ -3012,6 +3067,7 @@ void ASS_VEC8BIT(Obj list, Obj pos, Obj elm) static Obj FuncASS_VEC8BIT(Obj self, Obj list, Obj pos, Obj elm) { + RequireVec8BitRep(SELF_NAME, list); ASS_VEC8BIT(list, pos, elm); return 0; } @@ -3032,6 +3088,7 @@ static Obj FuncUNB_VEC8BIT(Obj self, Obj list, Obj pos) Obj info; UInt elts; + RequireVec8BitRep(SELF_NAME, list); // check that is mutable RequireMutable("List Unbind", list, "list"); if (True == DoFilter(IsLockedRepresentationVector, list)) { @@ -3121,12 +3178,15 @@ static UInt PositionNonZeroVec8Bit(Obj list, UInt from) static Obj FuncPOSITION_NONZERO_VEC8BIT(Obj self, Obj list, Obj zero) { + RequireVec8BitRep(SELF_NAME, list); return INTOBJ_INT(PositionNonZeroVec8Bit(list, 0)); } static Obj FuncPOSITION_NONZERO_VEC8BIT3(Obj self, Obj list, Obj zero, Obj from) { + RequireVec8BitRep(SELF_NAME, list); + RequireNonnegativeSmallInt(SELF_NAME, from); return INTOBJ_INT(PositionNonZeroVec8Bit(list, INT_INTOBJ(from))); } @@ -3150,6 +3210,9 @@ static Obj FuncAPPEND_VEC8BIT(Obj self, Obj vecl, Obj vecr) const UInt1 * settab; UInt posl, posr; + RequireVec8BitRep(SELF_NAME, vecl); + RequireVec8BitRep(SELF_NAME, vecr); + if (FIELD_VEC8BIT(vecl) != FIELD_VEC8BIT(vecr)) return TRY_NEXT_METHOD; @@ -3224,6 +3287,9 @@ static Obj FuncPROD_VEC8BIT_MATRIX(Obj self, Obj vec, Obj mat) const Obj * ffefelt; Obj x; + RequireVec8BitRep(SELF_NAME, vec); + RequirePlainList(SELF_NAME, mat); + len = LEN_VEC8BIT(vec); l2 = LEN_PLIST(mat); q = FIELD_VEC8BIT(vec); @@ -3310,6 +3376,14 @@ static inline UInt NR_COLS_MAT8BIT(Obj mat) return LEN_VEC8BIT(ELM_MAT8BIT(mat, 1)); } +static inline void RequireNonemptyMat8BitRows(const Char * funcname, Obj mat) +{ + if (LEN_MAT8BIT(mat) == 0) + ErrorMayQuit("%s: compressed 8bit matrices with empty rows are not " + "supported", + (Int)funcname, 0); +} + /**************************************************************************** ** *F PlainMat8Bit( ) @@ -3337,6 +3411,7 @@ static void PlainMat8Bit(Obj mat) static Obj FuncPLAIN_MAT8BIT(Obj self, Obj mat) { + RequireMat8BitRep(SELF_NAME, mat); PlainMat8Bit(mat); return 0; } @@ -3356,6 +3431,7 @@ static Obj FuncCONV_MAT8BIT(Obj self, Obj list, Obj q) Obj tmp; Obj type; + RequirePlainList(SELF_NAME, list); UInt iq = GetPositiveSmallInt(SELF_NAME, q); PLAIN_LIST(list); len = LEN_PLIST(list); @@ -3464,8 +3540,9 @@ static Obj FuncPROD_VEC8BIT_MAT8BIT(Obj self, Obj vec, Obj mat) { UInt q, q1, q2; - GAP_ASSERT(IS_VEC8BIT_REP(vec)); - GAP_ASSERT(IS_MAT8BIT_REP(mat)); + RequireVec8BitRep(SELF_NAME, vec); + RequireMat8BitRep(SELF_NAME, mat); + RequireNonemptyMat8BitRows(SELF_NAME, mat); // Now field mismatches -- consider promoting the vector q = FIELD_VEC8BIT(vec); @@ -3549,8 +3626,9 @@ static Obj FuncPROD_MAT8BIT_VEC8BIT(Obj self, Obj mat, Obj vec) { UInt q, q1, q2; - GAP_ASSERT(IS_MAT8BIT_REP(mat)); - GAP_ASSERT(IS_VEC8BIT_REP(vec)); + RequireMat8BitRep(SELF_NAME, mat); + RequireVec8BitRep(SELF_NAME, vec); + RequireNonemptyMat8BitRows(SELF_NAME, mat); // Now field mismatches -- consider promoting the vector q = FIELD_VEC8BIT(vec); @@ -3626,8 +3704,10 @@ static Obj ProdMat8BitMat8Bit(Obj matl, Obj matr) static Obj FuncPROD_MAT8BIT_MAT8BIT(Obj self, Obj matl, Obj matr) { - GAP_ASSERT(IS_MAT8BIT_REP(matl)); - GAP_ASSERT(IS_MAT8BIT_REP(matr)); + RequireMat8BitRep(SELF_NAME, matl); + RequireMat8BitRep(SELF_NAME, matr); + RequireNonemptyMat8BitRows(SELF_NAME, matl); + RequireNonemptyMat8BitRows(SELF_NAME, matr); if (FIELD_MAT8BIT(matl) != FIELD_MAT8BIT(matr)) { return TRY_NEXT_METHOD; @@ -3802,7 +3882,8 @@ static Obj InverseMat8Bit(Obj mat, UInt mut) static Obj FuncINV_MAT8BIT_MUTABLE(Obj self, Obj mat) { - GAP_ASSERT(IS_MAT8BIT_REP(mat)); + RequireMat8BitRep(SELF_NAME, mat); + RequireNonemptyMat8BitRows(SELF_NAME, mat); if (LEN_MAT8BIT(mat) != LEN_VEC8BIT(ELM_MAT8BIT(mat, 1))) { ErrorMayQuit("InverseOp: matrix must be square, not %d by %d", @@ -3820,7 +3901,8 @@ static Obj FuncINV_MAT8BIT_MUTABLE(Obj self, Obj mat) static Obj FuncINV_MAT8BIT_SAME_MUTABILITY(Obj self, Obj mat) { - GAP_ASSERT(IS_MAT8BIT_REP(mat)); + RequireMat8BitRep(SELF_NAME, mat); + RequireNonemptyMat8BitRows(SELF_NAME, mat); if (LEN_MAT8BIT(mat) != LEN_VEC8BIT(ELM_MAT8BIT(mat, 1))) { ErrorMayQuit( "InverseSameMutability: matrix must be square, not %d by %d", @@ -3838,7 +3920,8 @@ static Obj FuncINV_MAT8BIT_SAME_MUTABILITY(Obj self, Obj mat) static Obj FuncINV_MAT8BIT_IMMUTABLE(Obj self, Obj mat) { - GAP_ASSERT(IS_MAT8BIT_REP(mat)); + RequireMat8BitRep(SELF_NAME, mat); + RequireNonemptyMat8BitRows(SELF_NAME, mat); if (LEN_MAT8BIT(mat) != LEN_VEC8BIT(ELM_MAT8BIT(mat, 1))) { ErrorMayQuit("Inverse: matrix must be square, not %d by %d", LEN_MAT8BIT(mat), LEN_VEC8BIT(ELM_MAT8BIT(mat, 1))); @@ -3864,7 +3947,8 @@ static Obj FuncASS_MAT8BIT(Obj self, Obj mat, Obj pos, Obj obj) UInt p; Obj type; - GAP_ASSERT(IS_MAT8BIT_REP(mat)); + RequireMat8BitRep(SELF_NAME, mat); + RequireNonemptyMat8BitRows(SELF_NAME, mat); p = GetPositiveSmallInt(SELF_NAME, pos); len = LEN_MAT8BIT(mat); @@ -3957,7 +4041,7 @@ static Obj FuncASS_MAT8BIT(Obj self, Obj mat, Obj pos, Obj obj) */ static Obj FuncELM_MAT8BIT(Obj self, Obj mat, Obj pos) { - GAP_ASSERT(IS_MAT8BIT_REP(mat)); + RequireMat8BitRep(SELF_NAME, mat); UInt r = GetPositiveSmallInt(SELF_NAME, pos); if (LEN_MAT8BIT(mat) < r) { ErrorMayQuit("row index %d exceeds %d, the number of rows", r, @@ -4111,8 +4195,10 @@ static Obj SumMat8BitMat8Bit(Obj ml, Obj mr) static Obj FuncSUM_MAT8BIT_MAT8BIT(Obj self, Obj ml, Obj mr) { - GAP_ASSERT(IS_MAT8BIT_REP(ml)); - GAP_ASSERT(IS_MAT8BIT_REP(mr)); + RequireMat8BitRep(SELF_NAME, ml); + RequireMat8BitRep(SELF_NAME, mr); + RequireNonemptyMat8BitRows(SELF_NAME, ml); + RequireNonemptyMat8BitRows(SELF_NAME, mr); if (FIELD_MAT8BIT(ml) != FIELD_MAT8BIT(mr)) { return TRY_NEXT_METHOD; @@ -4204,8 +4290,10 @@ static Obj DiffMat8BitMat8Bit(Obj ml, Obj mr) static Obj FuncDIFF_MAT8BIT_MAT8BIT(Obj self, Obj ml, Obj mr) { - GAP_ASSERT(IS_MAT8BIT_REP(ml)); - GAP_ASSERT(IS_MAT8BIT_REP(mr)); + RequireMat8BitRep(SELF_NAME, ml); + RequireMat8BitRep(SELF_NAME, mr); + RequireNonemptyMat8BitRows(SELF_NAME, ml); + RequireNonemptyMat8BitRows(SELF_NAME, mr); if (FIELD_MAT8BIT(ml) != FIELD_MAT8BIT(mr)) return TRY_NEXT_METHOD; @@ -4407,6 +4495,8 @@ static void ShiftRightVec8Bit(Obj vec, UInt amount) // pads with zeros // make room len = LEN_VEC8BIT(vec); ResizeVec8Bit(vec, len + amount, 0); + if (len == 0) + return; q = FIELD_VEC8BIT(vec); info = GetFieldInfo8Bit(q); @@ -4461,6 +4551,10 @@ static void ShiftRightVec8Bit(Obj vec, UInt amount) // pads with zeros static Obj FuncADD_COEFFS_VEC8BIT_3(Obj self, Obj vec1, Obj vec2, Obj mult) { + RequireVec8BitRep(SELF_NAME, vec1); + RequireVec8BitRep(SELF_NAME, vec2); + RequireFFE(SELF_NAME, mult); + UInt q; UInt len; len = LEN_VEC8BIT(vec2); @@ -4525,6 +4619,9 @@ static Obj FuncADD_COEFFS_VEC8BIT_3(Obj self, Obj vec1, Obj vec2, Obj mult) static Obj FuncADD_COEFFS_VEC8BIT_2(Obj self, Obj vec1, Obj vec2) { + RequireVec8BitRep(SELF_NAME, vec1); + RequireVec8BitRep(SELF_NAME, vec2); + UInt q; UInt len; len = LEN_VEC8BIT(vec2); @@ -4578,8 +4675,8 @@ static Obj FuncADD_COEFFS_VEC8BIT_2(Obj self, Obj vec1, Obj vec2) static Obj FuncSHIFT_VEC8BIT_LEFT(Obj self, Obj vec, Obj amount) { - if (!IS_MUTABLE_OBJ(vec)) - RequireArgument(SELF_NAME, vec, "must be mutable"); + RequireVec8BitRep(SELF_NAME, vec); + RequireMutable(SELF_NAME, vec, "vector"); RequireNonnegativeSmallInt(SELF_NAME, amount); ShiftLeftVec8Bit(vec, INT_INTOBJ(amount)); return (Obj)0; @@ -4593,9 +4690,10 @@ static Obj FuncSHIFT_VEC8BIT_LEFT(Obj self, Obj vec, Obj amount) static Obj FuncSHIFT_VEC8BIT_RIGHT(Obj self, Obj vec, Obj amount, Obj zero) { - if (!IS_MUTABLE_OBJ(vec)) - RequireArgument(SELF_NAME, vec, "must be mutable"); + RequireVec8BitRep(SELF_NAME, vec); + RequireMutable(SELF_NAME, vec, "vector"); RequireNonnegativeSmallInt(SELF_NAME, amount); + RequireFFE(SELF_NAME, zero); ShiftRightVec8Bit(vec, INT_INTOBJ(amount)); return (Obj)0; } @@ -4608,6 +4706,7 @@ static Obj FuncSHIFT_VEC8BIT_RIGHT(Obj self, Obj vec, Obj amount, Obj zero) static Obj FuncRESIZE_VEC8BIT(Obj self, Obj vec, Obj newsize) { + RequireVec8BitRep(SELF_NAME, vec); RequireMutable(SELF_NAME, vec, "vector"); RequireNonnegativeSmallInt(SELF_NAME, newsize); ResizeVec8Bit(vec, INT_INTOBJ(newsize), 0); @@ -4622,6 +4721,7 @@ static Obj FuncRESIZE_VEC8BIT(Obj self, Obj vec, Obj newsize) static Obj FuncRIGHTMOST_NONZERO_VEC8BIT(Obj self, Obj vec) { + RequireVec8BitRep(SELF_NAME, vec); return INTOBJ_INT(RightMostNonZeroVec8Bit(vec)); } @@ -4807,6 +4907,12 @@ static Obj FuncPROD_COEFFS_VEC8BIT(Obj self, Obj vl, Obj ll, Obj vr, Obj lr) Obj res; UInt lenp; UInt last; + + RequireVec8BitRep(SELF_NAME, vl); + RequireVec8BitRep(SELF_NAME, vr); + RequireNonnegativeSmallInt(SELF_NAME, ll); + RequireNonnegativeSmallInt(SELF_NAME, lr); + q = FIELD_VEC8BIT(vl); if (q != FIELD_VEC8BIT(vr)) { Obj info1; @@ -4837,8 +4943,6 @@ static Obj FuncPROD_COEFFS_VEC8BIT(Obj self, Obj vl, Obj ll, Obj vr, Obj lr) q = q0; } - RequireNonnegativeSmallInt(SELF_NAME, ll); - RequireNonnegativeSmallInt(SELF_NAME, lr); ll1 = INT_INTOBJ(ll); lr1 = INT_INTOBJ(lr); if (0 > ll1 || ll1 > LEN_VEC8BIT(vl)) @@ -4855,7 +4959,8 @@ static Obj FuncPROD_COEFFS_VEC8BIT(Obj self, Obj vl, Obj ll, Obj vr, Obj lr) else lenp = ll1 + lr1 - 1; res = ZeroVec8Bit(q, lenp, 1); - ProdCoeffsVec8Bit(res, vl, ll1, vr, lr1); + if (lenp > 0) + ProdCoeffsVec8Bit(res, vl, ll1, vr, lr1); last = RightMostNonZeroVec8Bit(res); if (last != lenp) ResizeVec8Bit(res, last, 1); @@ -5060,10 +5165,11 @@ static Obj FuncREDUCE_COEFFS_VEC8BIT(Obj self, Obj vl, Obj ll, Obj vrshifted) UInt last; RequireVec8BitRep(SELF_NAME, vl); + RequireNonnegativeSmallInt(SELF_NAME, ll); + RequirePlainList(SELF_NAME, vrshifted); q = FIELD_VEC8BIT(vl); if (q != FIELD_VEC8BIT(ELM_PLIST(vrshifted, 1))) return Fail; - RequireNonnegativeSmallInt(SELF_NAME, ll); if (INT_INTOBJ(ll) > LEN_VEC8BIT(vl)) { ErrorQuit("ReduceCoeffs: given length of left argt (%d) is " "longer than the argt (%d)", @@ -5397,7 +5503,7 @@ static Obj FuncSEMIECHELON_LIST_VEC8BITS(Obj self, Obj mat) Obj row; UInt q; - GAP_ASSERT(IS_PLIST(mat)); + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) @@ -5436,7 +5542,7 @@ static Obj FuncSEMIECHELON_LIST_VEC8BITS_TRANSFORMATIONS(Obj self, Obj mat) UInt q; UInt width; - GAP_ASSERT(IS_PLIST(mat)); + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) @@ -5475,7 +5581,7 @@ static Obj FuncTRIANGULIZE_LIST_VEC8BITS(Obj self, Obj mat) Obj row; UInt q; - GAP_ASSERT(IS_PLIST(mat)); + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) @@ -5514,7 +5620,7 @@ static Obj FuncRANK_LIST_VEC8BITS(Obj self, Obj mat) Obj row; UInt q; - GAP_ASSERT(IS_PLIST(mat)); + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) @@ -5553,7 +5659,7 @@ static Obj FuncDETERMINANT_LIST_VEC8BITS(Obj self, Obj mat) UInt q; Obj det; - GAP_ASSERT(IS_PLIST(mat)); + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) @@ -5613,8 +5719,8 @@ static Int Cmp_MAT8BIT_MAT8BIT(Obj ml, Obj mr) static Obj FuncEQ_MAT8BIT_MAT8BIT(Obj self, Obj ml, Obj mr) { - GAP_ASSERT(IS_MAT8BIT_REP(ml)); - GAP_ASSERT(IS_MAT8BIT_REP(mr)); + RequireMat8BitRep(SELF_NAME, ml); + RequireMat8BitRep(SELF_NAME, mr); if (LEN_MAT8BIT(ml) != LEN_MAT8BIT(mr)) return False; @@ -5632,8 +5738,8 @@ static Obj FuncEQ_MAT8BIT_MAT8BIT(Obj self, Obj ml, Obj mr) static Obj FuncLT_MAT8BIT_MAT8BIT(Obj self, Obj ml, Obj mr) { - GAP_ASSERT(IS_MAT8BIT_REP(ml)); - GAP_ASSERT(IS_MAT8BIT_REP(mr)); + RequireMat8BitRep(SELF_NAME, ml); + RequireMat8BitRep(SELF_NAME, mr); if (LEN_MAT8BIT(ml) == 0) return (LEN_MAT8BIT(mr) != 0) ? True : False; @@ -5665,6 +5771,7 @@ static Obj FuncTRANSPOSED_MAT8BIT(Obj self, Obj mat) Obj type; RequireMat8BitRep(SELF_NAME, mat); + RequireNonemptyMat8BitRows(SELF_NAME, mat); // we will give result same type as mat // we assume here that there is a first row -- a zero row mat8bit is a @@ -5762,8 +5869,10 @@ static Obj FuncKRONECKERPRODUCT_MAT8BIT_MAT8BIT(Obj self, Obj matl, Obj matr) const UInt1 * getelt, *setelt, *scalar, *add; const UInt1 * datar; - GAP_ASSERT(IS_MAT8BIT_REP(matl)); - GAP_ASSERT(IS_MAT8BIT_REP(matr)); + RequireMat8BitRep(SELF_NAME, matl); + RequireMat8BitRep(SELF_NAME, matr); + RequireNonemptyMat8BitRows(SELF_NAME, matl); + RequireNonemptyMat8BitRows(SELF_NAME, matr); nrowl = LEN_MAT8BIT(matl); nrowr = LEN_MAT8BIT(matr); diff --git a/src/vecgf2.c b/src/vecgf2.c index 6c3e64a1c2..b3c7454cb0 100644 --- a/src/vecgf2.c +++ b/src/vecgf2.c @@ -86,6 +86,8 @@ Obj TYPE_LIST_GF2MAT_IMM; */ Obj IsGF2VectorRep; +Obj IsGF2MatrixRep; + /**************************************************************************** ** @@ -100,6 +102,18 @@ static Obj GF2One; */ static Obj GF2Zero; +#define RequireGF2VecRep(funcname, op) \ + RequireArgumentCondition(funcname, op, IS_GF2VEC_REP(op), \ + "must be a GF2 vector") + +#define RequireGF2MatRep(funcname, op) \ + RequireArgumentCondition(funcname, op, IS_GF2MAT_REP(op), \ + "must be a GF2 matrix") + +#define RequireFFE(funcname, op) \ + RequireArgumentCondition(funcname, op, IS_FFE(op), \ + "must be a finite field element") + /**************************************************************************** ** @@ -835,6 +849,12 @@ static Obj FuncPROD_GF2VEC_ANYMAT(Obj self, Obj vec, Obj mat) UInt i; UInt block = 0; + RequireGF2VecRep(SELF_NAME, vec); + RequirePlainList(SELF_NAME, mat); + + if (LEN_PLIST(mat) == 0) + return TRY_NEXT_METHOD; + len = LEN_GF2VEC(vec); if (len > LEN_PLIST(mat)) len = LEN_PLIST(mat); @@ -1389,6 +1409,7 @@ static void ConvGF2Vec(Obj list) */ static Obj FuncCONV_GF2VEC(Obj self, Obj list) { + RequireSmallList(SELF_NAME, list); ConvGF2Vec(list); return 0; } @@ -1467,7 +1488,6 @@ static Obj NewGF2Vec(Obj list) return res; } - /**************************************************************************** ** *F FuncCOPY_GF2VEC( , ) . . . . . convert into a GF2 vector rep @@ -1492,6 +1512,7 @@ static Obj FuncCONV_GF2MAT(Obj self, Obj list) UInt len, i; Obj tmp; UInt mut; + RequireSmallList(SELF_NAME, list); len = LEN_LIST(list); if (len == 0) return (Obj)0; @@ -1664,6 +1685,9 @@ static Int Cmp_GF2VEC_GF2VEC(Obj vl, Obj vr) */ static Obj FuncEQ_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) { + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); + // we can do this case MUCH faster if we just want equality if (LEN_GF2VEC(vl) != LEN_GF2VEC(vr)) return False; @@ -1677,6 +1701,7 @@ static Obj FuncEQ_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) */ static Obj FuncLEN_GF2VEC(Obj self, Obj list) { + RequireGF2VecRep(SELF_NAME, list); return INTOBJ_INT(LEN_GF2VEC(list)); } @@ -1692,6 +1717,7 @@ static Obj FuncLEN_GF2VEC(Obj self, Obj list) */ static Obj FuncELM0_GF2VEC(Obj self, Obj list, Obj pos) { + RequireGF2VecRep(SELF_NAME, list); UInt p = GetSmallInt(SELF_NAME, pos); if (LEN_GF2VEC(list) < p) { return Fail; @@ -1712,6 +1738,7 @@ static Obj FuncELM0_GF2VEC(Obj self, Obj list, Obj pos) */ static Obj FuncELM_GF2VEC(Obj self, Obj list, Obj pos) { + RequireGF2VecRep(SELF_NAME, list); UInt p = GetSmallInt(SELF_NAME, pos); if (LEN_GF2VEC(list) < p) { ErrorMayQuit("List Element: [%d] must have an assigned value", @@ -1743,6 +1770,8 @@ static Obj FuncELMS_GF2VEC(Obj self, Obj list, Obj poss) Int i; // loop variable Obj apos; + RequireGF2VecRep(SELF_NAME, list); + // get the length of lenList = LEN_GF2VEC(list); @@ -1830,6 +1859,8 @@ static Obj FuncELMS_GF2VEC(Obj self, Obj list, Obj poss) static Obj FuncASS_GF2VEC(Obj self, Obj list, Obj pos, Obj elm) { + RequireGF2VecRep(SELF_NAME, list); + // check that is mutable RequireMutable("List Assignment", list, "list"); @@ -1875,6 +1906,7 @@ static Obj FuncASS_GF2VEC(Obj self, Obj list, Obj pos, Obj elm) */ static Obj FuncPLAIN_GF2MAT(Obj self, Obj list) { + RequireGF2MatRep(SELF_NAME, list); PlainGF2Mat(list); return 0; } @@ -1892,6 +1924,8 @@ static Obj FuncPLAIN_GF2MAT(Obj self, Obj list) */ static Obj FuncASS_GF2MAT(Obj self, Obj list, Obj pos, Obj elm) { + RequireGF2MatRep(SELF_NAME, list); + // check that is mutable RequireMutable("List Assignment", list, "list"); @@ -1939,6 +1973,7 @@ static Obj FuncASS_GF2MAT(Obj self, Obj list, Obj pos, Obj elm) */ static Obj FuncELM_GF2MAT(Obj self, Obj mat, Obj row) { + RequireGF2MatRep(SELF_NAME, mat); UInt r = GetSmallInt(SELF_NAME, row); if (LEN_GF2MAT(mat) < r) { ErrorMayQuit("row index %d exceeds %d, the number of rows", r, @@ -1955,6 +1990,7 @@ static Obj FuncELM_GF2MAT(Obj self, Obj mat, Obj row) */ static Obj FuncSWAP_ROWS_GF2MAT(Obj self, Obj mat, Obj row1, Obj row2) { + RequireGF2MatRep(SELF_NAME, mat); RequireMutable(SELF_NAME, mat, "mat"); UInt r1 = GetSmallInt(SELF_NAME, row1); @@ -1984,6 +2020,7 @@ static Obj FuncSWAP_ROWS_GF2MAT(Obj self, Obj mat, Obj row1, Obj row2) */ static Obj FuncSWAP_COLS_GF2MAT(Obj self, Obj mat, Obj col1, Obj col2) { + RequireGF2MatRep(SELF_NAME, mat); UInt c1 = GetSmallInt(SELF_NAME, col1); UInt c2 = GetSmallInt(SELF_NAME, col2); UInt m = LEN_GF2MAT(mat); @@ -2032,6 +2069,8 @@ static Obj FuncSWAP_COLS_GF2MAT(Obj self, Obj mat, Obj col1, Obj col2) */ static Obj FuncUNB_GF2VEC(Obj self, Obj list, Obj pos) { + RequireGF2VecRep(SELF_NAME, list); + // check that is mutable RequireMutable("List Unbind", list, "vector"); @@ -2069,6 +2108,8 @@ static Obj FuncUNB_GF2VEC(Obj self, Obj list, Obj pos) */ static Obj FuncUNB_GF2MAT(Obj self, Obj list, Obj pos) { + RequireGF2MatRep(SELF_NAME, list); + // check that is mutable RequireMutable("List Unbind", list, "matrix"); @@ -2108,6 +2149,8 @@ static Obj FuncZERO_GF2VEC(Obj self, Obj mat) Obj zero; UInt len; + RequireGF2VecRep(SELF_NAME, mat); + // create a new GF2 vector len = LEN_GF2VEC(mat); NEW_GF2VEC(zero, TYPE_LIST_GF2VEC, len); @@ -2141,6 +2184,8 @@ static Obj FuncINV_GF2MAT_MUTABLE(Obj self, Obj mat) { UInt len; + RequireGF2MatRep(SELF_NAME, mat); + len = LEN_GF2MAT(mat); if (len != 0) { if (len != LEN_GF2VEC(ELM_GF2MAT(mat, 1))) { @@ -2162,6 +2207,8 @@ static Obj FuncINV_GF2MAT_SAME_MUTABILITY(Obj self, Obj mat) { UInt len; + RequireGF2MatRep(SELF_NAME, mat); + len = LEN_GF2MAT(mat); if (len != 0) { if (len != LEN_GF2VEC(ELM_GF2MAT(mat, 1))) { @@ -2183,6 +2230,8 @@ static Obj FuncINV_GF2MAT_IMMUTABLE(Obj self, Obj mat) { UInt len; + RequireGF2MatRep(SELF_NAME, mat); + len = LEN_GF2MAT(mat); if (len != 0) { if (len != LEN_GF2VEC(ELM_GF2MAT(mat, 1))) { @@ -2203,6 +2252,7 @@ static Obj FuncINV_PLIST_GF2VECS_DESTRUCTIVE(Obj self, Obj list) { UInt len, i; Obj row; + RequirePlainList(SELF_NAME, list); len = LEN_PLIST(list); for (i = 1; i <= len; i++) { row = ELM_PLIST(list, i); @@ -2242,6 +2292,9 @@ static Obj FuncSUM_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) Obj sum; // sum, result UInt ll, lr; + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); + ll = LEN_GF2VEC(vl); lr = LEN_GF2VEC(vr); @@ -2269,6 +2322,9 @@ static Obj FuncSUM_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) */ static Obj FuncMULT_VECTOR_GF2VECS_2(Obj self, Obj vl, Obj mul) { + RequireGF2VecRep(SELF_NAME, vl); + RequireFFE(SELF_NAME, mul); + if (EQ(mul, GF2One)) return (Obj)0; else if (EQ(mul, GF2Zero)) { @@ -2289,6 +2345,8 @@ static Obj FuncMULT_VECTOR_GF2VECS_2(Obj self, Obj vl, Obj mul) */ static Obj FuncPROD_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) { + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); return ProdGF2VecGF2Vec(vl, vr); } @@ -2305,6 +2363,8 @@ static Obj FuncPROD_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) */ static Obj FuncPROD_GF2VEC_GF2MAT(Obj self, Obj vl, Obj vr) { + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2MatRep(SELF_NAME, vr); return ProdGF2VecGF2Mat(vl, vr); } @@ -2320,6 +2380,8 @@ static Obj FuncPROD_GF2VEC_GF2MAT(Obj self, Obj vl, Obj vr) */ static Obj FuncPROD_GF2MAT_GF2MAT(Obj self, Obj ml, Obj mr) { + RequireGF2MatRep(SELF_NAME, ml); + RequireGF2MatRep(SELF_NAME, mr); UInt lenl = LEN_GF2MAT(ml); UInt lenm; if (lenl >= 128) { @@ -2344,6 +2406,8 @@ static Obj FuncPROD_GF2MAT_GF2MAT(Obj self, Obj ml, Obj mr) */ static Obj FuncPROD_GF2MAT_GF2MAT_SIMPLE(Obj self, Obj ml, Obj mr) { + RequireGF2MatRep(SELF_NAME, ml); + RequireGF2MatRep(SELF_NAME, mr); return ProdGF2MatGF2MatSimple(ml, mr); } @@ -2362,6 +2426,10 @@ static Obj FuncPROD_GF2MAT_GF2MAT_SIMPLE(Obj self, Obj ml, Obj mr) static Obj FuncPROD_GF2MAT_GF2MAT_ADVANCED( Obj self, Obj ml, Obj mr, Obj greaselevel, Obj blocksize) { + RequireGF2MatRep(SELF_NAME, ml); + RequireGF2MatRep(SELF_NAME, mr); + RequireSmallInt(SELF_NAME, greaselevel); + RequireSmallInt(SELF_NAME, blocksize); return ProdGF2MatGF2MatAdvanced(ml, mr, INT_INTOBJ(greaselevel), INT_INTOBJ(blocksize)); } @@ -2379,6 +2447,8 @@ static Obj FuncPROD_GF2MAT_GF2MAT_ADVANCED( */ static Obj FuncPROD_GF2MAT_GF2VEC(Obj self, Obj vl, Obj vr) { + RequireGF2MatRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); return ProdGF2MatGF2Vec(vl, vr); } @@ -2389,6 +2459,10 @@ static Obj FuncPROD_GF2MAT_GF2VEC(Obj self, Obj vl, Obj vr) */ static Obj FuncADDCOEFFS_GF2VEC_GF2VEC_MULT(Obj self, Obj vl, Obj vr, Obj mul) { + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); + RequireFFE(SELF_NAME, mul); + // do nothing if is zero if (EQ(mul, GF2Zero)) { return INTOBJ_INT(RightMostOneGF2Vec(vl)); @@ -2409,6 +2483,8 @@ static Obj FuncADDCOEFFS_GF2VEC_GF2VEC_MULT(Obj self, Obj vl, Obj vr, Obj mul) */ static Obj FuncADDCOEFFS_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) { + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); return AddCoeffsGF2VecGF2Vec(vl, vr); } @@ -2425,6 +2501,8 @@ static Obj FuncSHRINKCOEFFS_GF2VEC(Obj self, Obj vec) UInt * ptr; UInt off; + RequireGF2VecRep(SELF_NAME, vec); + // get length and number of blocks len = LEN_GF2VEC(vec); if (len == 0) { @@ -2522,11 +2600,14 @@ static UInt PositionNonZeroGF2Vec(Obj vec, UInt from) static Obj FuncPOSITION_NONZERO_GF2VEC(Obj self, Obj vec, Obj zero) { + RequireGF2VecRep(SELF_NAME, vec); return INTOBJ_INT(PositionNonZeroGF2Vec(vec, 0)); } static Obj FuncPOSITION_NONZERO_GF2VEC3(Obj self, Obj vec, Obj zero, Obj from) { + RequireGF2VecRep(SELF_NAME, vec); + RequireNonnegativeSmallInt(SELF_NAME, from); return INTOBJ_INT(PositionNonZeroGF2Vec(vec, INT_INTOBJ(from))); } @@ -2538,12 +2619,8 @@ static Obj FuncCOPY_SECTION_GF2VECS( Int ito = GetPositiveSmallInt(SELF_NAME, to); Int ihowmany = GetSmallInt(SELF_NAME, howmany); - if (!IS_GF2VEC_REP(src)) { - RequireArgument(SELF_NAME, src, "must be a GF2 vector"); - } - if (!IS_GF2VEC_REP(dest)) { - RequireArgument(SELF_NAME, dest, "must be a GF2 vector"); - } + RequireGF2VecRep(SELF_NAME, src); + RequireGF2VecRep(SELF_NAME, dest); UInt lens = LEN_GF2VEC(src); UInt lend = LEN_GF2VEC(dest); @@ -2566,6 +2643,9 @@ static Obj FuncCOPY_SECTION_GF2VECS( static Obj FuncAPPEND_GF2VEC(Obj self, Obj vecl, Obj vecr) { UInt lenl, lenr; + RequireGF2VecRep(SELF_NAME, vecl); + RequireGF2VecRep(SELF_NAME, vecr); + RequireMutable(SELF_NAME, vecl, "vector"); lenl = LEN_GF2VEC(vecl); lenr = LEN_GF2VEC(vecr); if (True == DoFilter(IsLockedRepresentationVector, vecl) && lenr > 0) { @@ -2586,6 +2666,7 @@ static Obj FuncAPPEND_GF2VEC(Obj self, Obj vecl, Obj vecr) static Obj FuncSHALLOWCOPY_GF2VEC(Obj self, Obj vec) { + RequireGF2VecRep(SELF_NAME, vec); return ShallowCopyVecGF2(vec); } @@ -2603,6 +2684,8 @@ static Obj FuncSUM_GF2MAT_GF2MAT(Obj self, Obj matl, Obj matr) Obj vl, vr, sv; UInt i; Obj rtype; + RequireGF2MatRep(SELF_NAME, matl); + RequireGF2MatRep(SELF_NAME, matr); ll = LEN_GF2MAT(matl); lr = LEN_GF2MAT(matr); if (ll > lr) { @@ -2695,10 +2778,11 @@ static Obj FuncTRANSPOSED_GF2MAT(Obj self, Obj mat) UInt imod, nrb, nstart; UInt i, j, k, n; - if (TNUM_OBJ(mat) != T_POSOBJ) { - ErrorMayQuit("TRANSPOSED_GF2MAT: Need compressed matrix over GF(2)", - 0, 0); - } + RequireGF2MatRep(SELF_NAME, mat); + + if (LEN_GF2MAT(mat) == 0) + return TRY_NEXT_METHOD; + // type for mat typ = TYPE_LIST_GF2MAT; @@ -2780,6 +2864,7 @@ static Obj FuncNUMBER_GF2VEC(Obj self, Obj vec) Obj zahl; // the long number UInt * num2; mp_limb_t * vp; + RequireGF2VecRep(SELF_NAME, vec); len = LEN_GF2VEC(vec); if (len == 0) return INTOBJ_INT(1); @@ -2842,6 +2927,8 @@ static Obj FuncNUMBER_GF2VEC(Obj self, Obj vec) */ static Obj FuncLT_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) { + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); return (Cmp_GF2VEC_GF2VEC(vl, vr) < 0) ? True : False; } @@ -2876,6 +2963,8 @@ static Int Cmp_GF2MAT_GF2MAT(Obj ml, Obj mr) static Obj FuncEQ_GF2MAT_GF2MAT(Obj self, Obj ml, Obj mr) { + RequireGF2MatRep(SELF_NAME, ml); + RequireGF2MatRep(SELF_NAME, mr); if (ELM_PLIST(ml, 1) != ELM_PLIST(mr, 1)) return False; return (0 == Cmp_GF2MAT_GF2MAT(ml, mr)) ? True : False; @@ -2888,6 +2977,8 @@ static Obj FuncEQ_GF2MAT_GF2MAT(Obj self, Obj ml, Obj mr) static Obj FuncLT_GF2MAT_GF2MAT(Obj self, Obj ml, Obj mr) { + RequireGF2MatRep(SELF_NAME, ml); + RequireGF2MatRep(SELF_NAME, mr); return (Cmp_GF2MAT_GF2MAT(ml, mr) < 0) ? True : False; } @@ -2931,6 +3022,8 @@ static Obj FuncDIST_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) UInt * ptL; // bit field of UInt * ptR; // bit field of UInt * end; // pointer used to zero out end bit + RequireGF2VecRep(SELF_NAME, vl); + RequireGF2VecRep(SELF_NAME, vr); // get and check the length len = LEN_GF2VEC(vl); @@ -2938,6 +3031,8 @@ static Obj FuncDIST_GF2VEC_GF2VEC(Obj self, Obj vl, Obj vr) ErrorMayQuit("DIST_GF2VEC_GF2VEC: vectors must have the same length", 0, 0); } + if (len == 0) + return INTOBJ_INT(0); // calculate the offsets ptL = BLOCKS_GF2VEC(vl); @@ -3010,6 +3105,10 @@ static Obj FuncDIST_VEC_CLOS_VEC( Obj sum; // sum vector UInt len; + RequirePlainList(SELF_NAME, veclis); + RequireGF2VecRep(SELF_NAME, vec); + RequirePlainList(SELF_NAME, d); + len = LEN_GF2VEC(vec); // get space for sum vector @@ -3123,6 +3222,9 @@ static Obj FuncA_CLOS_VEC( Obj best; // best vector UInt len; + RequirePlainList(SELF_NAME, veclis); + RequireGF2VecRep(SELF_NAME, vec); + len = LEN_GF2VEC(vec); RequireNonnegativeSmallInt(SELF_NAME, cnt); @@ -3155,6 +3257,9 @@ static Obj FuncA_CLOS_VEC_COORDS( Obj res; // length 2 plist for results UInt len, len2, i; + RequirePlainList(SELF_NAME, veclis); + RequireGF2VecRep(SELF_NAME, vec); + len = LEN_GF2VEC(vec); len2 = LEN_PLIST(veclis); @@ -3293,6 +3398,7 @@ static Obj FuncCOSET_LEADERS_INNER_GF2( static Obj FuncRIGHTMOST_NONZERO_GF2VEC(Obj self, Obj vec) { + RequireGF2VecRep(SELF_NAME, vec); return INTOBJ_INT(RightMostOneGF2Vec(vec)); } @@ -3362,6 +3468,7 @@ static void ResizeGF2Vec(Obj vec, UInt newlen) static Obj FuncRESIZE_GF2VEC(Obj self, Obj vec, Obj newlen) { + RequireGF2VecRep(SELF_NAME, vec); RequireMutable(SELF_NAME, vec, "vector"); RequireNonnegativeSmallInt(SELF_NAME, newlen); ResizeGF2Vec(vec, INT_INTOBJ(newlen)); @@ -3421,6 +3528,7 @@ static void ShiftLeftGF2Vec(Obj vec, UInt amount) static Obj FuncSHIFT_LEFT_GF2VEC(Obj self, Obj vec, Obj amount) { + RequireGF2VecRep(SELF_NAME, vec); RequireMutable(SELF_NAME, vec, "vector"); RequireNonnegativeSmallInt(SELF_NAME, amount); ShiftLeftGF2Vec(vec, INT_INTOBJ(amount)); @@ -3484,8 +3592,10 @@ static void ShiftRightGF2Vec(Obj vec, UInt amount) static Obj FuncSHIFT_RIGHT_GF2VEC(Obj self, Obj vec, Obj amount, Obj zero) { + RequireGF2VecRep(SELF_NAME, vec); RequireMutable(SELF_NAME, vec, "vector"); RequireNonnegativeSmallInt(SELF_NAME, amount); + RequireFFE(SELF_NAME, zero); ShiftRightGF2Vec(vec, INT_INTOBJ(amount)); return (Obj)0; } @@ -3546,6 +3656,9 @@ static void AddShiftedVecGF2VecGF2(Obj vec1, Obj vec2, UInt len2, UInt off) static Obj FuncADD_GF2VEC_GF2VEC_SHIFTED(Obj self, Obj vec1, Obj vec2, Obj len2, Obj off) { + RequireGF2VecRep(SELF_NAME, vec1); + RequireGF2VecRep(SELF_NAME, vec2); + RequireMutable(SELF_NAME, vec1, "vector"); RequireNonnegativeSmallInt(SELF_NAME, off); RequireNonnegativeSmallInt(SELF_NAME, len2); Int off1 = INT_INTOBJ(off); @@ -3619,8 +3732,8 @@ FuncPROD_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) Obj prod; UInt last; - RequireSmallInt(SELF_NAME, len1); - RequireSmallInt(SELF_NAME, len2); + RequireNonnegativeSmallInt(SELF_NAME, len1); + RequireNonnegativeSmallInt(SELF_NAME, len2); len2a = INT_INTOBJ(len2); if (len2a > LEN_GF2VEC(vec2)) ErrorMayQuit("PROD_COEFFS_GF2VEC: must not be more than the " @@ -3686,6 +3799,9 @@ FuncREDUCE_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) { UInt last; Int len2a; + RequireGF2VecRep(SELF_NAME, vec1); + RequireGF2VecRep(SELF_NAME, vec2); + RequireMutable(SELF_NAME, vec1, "vector"); RequireNonnegativeSmallInt(SELF_NAME, len1); RequireNonnegativeSmallInt(SELF_NAME, len2); if (INT_INTOBJ(len1) > LEN_GF2VEC(vec1)) @@ -3729,10 +3845,13 @@ static Obj FuncQUOTREM_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) { Int len2a; - Int len1a = INT_INTOBJ(len1); + Int len1a; Obj quotv, remv, ret; + RequireGF2VecRep(SELF_NAME, vec1); + RequireGF2VecRep(SELF_NAME, vec2); RequireNonnegativeSmallInt(SELF_NAME, len1); RequireNonnegativeSmallInt(SELF_NAME, len2); + len1a = INT_INTOBJ(len1); if (INT_INTOBJ(len1) > LEN_GF2VEC(vec1)) ErrorMayQuit("QuotremCoeffs: given length of left argt " "(%d)\nis longer than the argt (%d)", @@ -3791,6 +3910,7 @@ static Obj FuncSEMIECHELON_LIST_GF2VECS(Obj self, Obj mat) UInt i, len; UInt width; Obj row; + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) return TRY_NEXT_METHOD; @@ -3825,6 +3945,7 @@ static Obj FuncSEMIECHELON_LIST_GF2VECS_TRANSFORMATIONS(Obj self, Obj mat) UInt i, len; UInt width; Obj row; + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) return TRY_NEXT_METHOD; @@ -3855,6 +3976,7 @@ static Obj FuncTRIANGULIZE_LIST_GF2VECS(Obj self, Obj mat) UInt i, len; UInt width; Obj row; + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) return TRY_NEXT_METHOD; @@ -3886,6 +4008,7 @@ static Obj FuncRANK_LIST_GF2VECS(Obj self, Obj mat) UInt i, len; UInt width; Obj row; + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) return TRY_NEXT_METHOD; @@ -3916,6 +4039,7 @@ static Obj FuncDETERMINANT_LIST_GF2VECS(Obj self, Obj mat) UInt i, len; UInt width; Obj row; + RequirePlainList(SELF_NAME, mat); len = LEN_PLIST(mat); if (!len) return TRY_NEXT_METHOD; @@ -3948,6 +4072,9 @@ static Obj FuncKRONECKERPRODUCT_GF2MAT_GF2MAT(Obj self, Obj matl, Obj matr) UInt * data; const UInt * datar; + RequireGF2MatRep(SELF_NAME, matl); + RequireGF2MatRep(SELF_NAME, matr); + nrowl = LEN_GF2MAT(matl); nrowr = LEN_GF2MAT(matr); nrowp = nrowl * nrowr; @@ -4036,6 +4163,7 @@ static Obj FuncKRONECKERPRODUCT_GF2MAT_GF2MAT(Obj self, Obj matl, Obj matr) */ static Obj FuncMAT_ELM_GF2MAT(Obj self, Obj mat, Obj row, Obj col) { + RequireGF2MatRep(SELF_NAME, mat); UInt r = GetPositiveSmallInt(SELF_NAME, row); UInt c = GetPositiveSmallInt(SELF_NAME, col); @@ -4063,6 +4191,7 @@ static Obj FuncMAT_ELM_GF2MAT(Obj self, Obj mat, Obj row, Obj col) static Obj FuncSET_MAT_ELM_GF2MAT(Obj self, Obj mat, Obj row, Obj col, Obj elm) { + RequireGF2MatRep(SELF_NAME, mat); UInt r = GetPositiveSmallInt(SELF_NAME, row); UInt c = GetPositiveSmallInt(SELF_NAME, col); @@ -4203,6 +4332,7 @@ static Int InitKernel(StructInitInfo * module) InitCopyGVar("TYPE_LIST_GF2VEC_LOCKED", &TYPE_LIST_GF2VEC_LOCKED); ImportFuncFromLibrary("IsGF2VectorRep", &IsGF2VectorRep); + ImportFuncFromLibrary("IsGF2MatrixRep", &IsGF2MatrixRep); InitCopyGVar("TYPE_LIST_GF2MAT", &TYPE_LIST_GF2MAT); InitCopyGVar("TYPE_LIST_GF2MAT_IMM", &TYPE_LIST_GF2MAT_IMM); diff --git a/src/vecgf2.h b/src/vecgf2.h index ddeac8639a..8471236efd 100644 --- a/src/vecgf2.h +++ b/src/vecgf2.h @@ -20,6 +20,13 @@ #define IS_GF2VEC_REP(obj) \ (TNUM_OBJ(obj) == T_DATOBJ && DoFilter(IsGF2VectorRep, obj) == True) +/**************************************************************************** +** +*F IS_GF2MAT_REP( ) . . . . . . check that is in GF2 matrix rep +*/ +#define IS_GF2MAT_REP(obj) \ + (TNUM_OBJ(obj) == T_POSOBJ && DoFilter(IsGF2MatrixRep, obj) == True) + /**************************************************************************** ** @@ -234,6 +241,7 @@ extern Obj TYPE_LIST_GF2MAT_IMM; extern Obj IsGF2VectorRep; +extern Obj IsGF2MatrixRep; Obj ShallowCopyVecGF2(Obj vec); diff --git a/tst/testinstall/kernel/vec8bit.tst b/tst/testinstall/kernel/vec8bit.tst index 6e951a3ef0..b9fe3df7e4 100644 --- a/tst/testinstall/kernel/vec8bit.tst +++ b/tst/testinstall/kernel/vec8bit.tst @@ -2,11 +2,1198 @@ # Tests for functions defined in src/vec8bit.c # gap> START_TEST("kernel/vec8bit.tst"); +gap> q := 5;; +gap> z := 0*Z(q);; +gap> o := Z(q)^0;; +gap> t := Z(q);; +gap> V8 := function(list) +> local v; +> v := ShallowCopy(list); +> CONV_VEC8BIT(v, q); +> return v; +> end;; +gap> M8 := function(rows) +> local m, i; +> m := List(rows, ShallowCopy); +> for i in [1 .. Length(m)] do +> CONV_VEC8BIT(m[i], q); +> od; +> CONV_MAT8BIT(m, q); +> return m; +> end;; +gap> IM8 := function(rows) +> local m; +> m := M8(rows); +> MakeImmutable(m); +> return m; +> end;; +gap> ZeroRowMat8 := function() +> local m; +> m := []; +> CONV_MAT8BIT(m, q); +> return m; +> end;; +gap> Mx08 := n -> M8(List([1 .. n], i -> []));; +gap> Veclis8 := function(rows) +> local f, fdi, fdip, veclis, row, mults, j, mult; +> f := AsSSortedList(GF(q)); +> fdi := []; +> for j in [2 .. Length(f)] do +> fdi[j - 1] := f[j] - f[j - 1]; +> od; +> Add(fdi, -Last(f)); +> fdip := List(fdi, x -> Position(fdi, x)); +> veclis := []; +> for row in rows do +> mults := []; +> mults[Length(fdi) + 1] := false; +> for j in [1 .. Length(fdi)] do +> if fdip[j] < j then +> mult := mults[fdip[j]]; +> else +> mult := fdi[j] * row; +> fi; +> mults[j] := mult; +> od; +> Add(veclis, mults); +> od; +> return veclis; +> end;; +gap> empty := V8([]);; +gap> one := V8([o]);; +gap> oneZero := V8([z]);; +gap> pair := V8([o, t]);; +gap> pair2 := V8([t, o]);; +gap> f5 := AsSSortedList(GF(q));; # +# CONV_VEC8BIT +# +gap> v := [];; CONV_VEC8BIT(v, q); v; +< mutable compressed vector length 0 over GF(5) > + +# bad arguments +gap> CONV_VEC8BIT(fail, q); +Error, CONV_VEC8BIT: must be a small list (not the value 'fail') +gap> CONV_VEC8BIT(v, fail); +Error, CONV_VEC8BIT: must be a positive small integer (not the value 'fail\ +') + +# +# COPY_VEC8BIT +# +gap> v := [];; w := COPY_VEC8BIT(v, q); v; +< mutable compressed vector length 0 over GF(5) > +[ ] + +# bad arguments +gap> COPY_VEC8BIT(fail, q); +Error, COPY_VEC8BIT: must be a small list (not the value 'fail') +gap> COPY_VEC8BIT(v, fail); +Error, COPY_VEC8BIT: must be a positive small integer (not the value 'fail\ +') + +# +# PLAIN_VEC8BIT +# +gap> v := V8([]);; PLAIN_VEC8BIT(v);; IsPlistRep(v); Length(v); +true +0 + +# bad arguments +gap> PLAIN_VEC8BIT(fail); +Error, PLAIN_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fa\ +il') + +# +# LEN_VEC8BIT +# +gap> LEN_VEC8BIT(empty); +0 +gap> LEN_VEC8BIT(pair); +2 + +# bad arguments +gap> LEN_VEC8BIT(fail); +Error, LEN_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fail\ +') + +# +# ELM0_VEC8BIT +# +gap> ELM0_VEC8BIT(empty, 1); +fail +gap> ELM0_VEC8BIT(one, 1); +Z(5)^0 + +# bad arguments +gap> ELM0_VEC8BIT(fail, 1); +Error, ELM0_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fai\ +l') +gap> ELM0_VEC8BIT(empty, fail); +Error, ELM0_VEC8BIT: must be a positive small integer (not the value 'fa\ +il') + +# +# ELM_VEC8BIT +# +gap> ELM_VEC8BIT(one, 1); +Z(5)^0 + +# bad arguments +gap> ELM_VEC8BIT(fail, 1); +Error, ELM_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fail\ +') +gap> ELM_VEC8BIT(one, fail); +Error, ELM_VEC8BIT: must be a positive small integer (not the value 'fai\ +l') + +# +# ELMS_VEC8BIT +# +gap> ELMS_VEC8BIT(empty, []) = empty; +true +gap> ELMS_VEC8BIT(pair, [2]); # = V8([t])); +[ Z(5) ] + +# bad arguments +gap> ELMS_VEC8BIT(fail, []); +Error, ELMS_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fai\ +l') +gap> ELMS_VEC8BIT(empty, fail); +Error, ELMS_VEC8BIT: must be a plain list (not the value 'fail') + +# +# ELMS_VEC8BIT_RANGE +# +gap> ELMS_VEC8BIT_RANGE(one, [1 .. 1]); +Error, ELMS_VEC8BIT_RANGE: must be a range (not a strictly-sorted plai\ +n list of cyclotomics) +gap> ELMS_VEC8BIT_RANGE(pair, [1 .. 2]) = pair; +true + +# bad arguments +gap> ELMS_VEC8BIT_RANGE(fail, [1 .. 1]); +Error, ELMS_VEC8BIT_RANGE: must belong to Is8BitVectorRep (not the valu\ +e 'fail') +gap> ELMS_VEC8BIT_RANGE(one, fail); +Error, ELMS_VEC8BIT_RANGE: must be a range (not the value 'fail') + +# +# ASS_VEC8BIT +# +gap> v := V8([]);; ASS_VEC8BIT(v, 1, z);; v = V8([z]); +true +gap> v := [Z(23), Z(23)];; ConvertToVectorRep(v);; ASS_VEC8BIT(v, 1, Z(23^5));; +gap> Is8BitVectorRep(v); +false +gap> v; +[ z, Z(23) ] + +# bad arguments +gap> v := V8([z, z]);; +gap> ASS_VEC8BIT(fail, 1, z); +Error, ASS_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fail\ +') +gap> ASS_VEC8BIT(v, fail, z); +Error, ASS_VEC8BIT: must be a positive small integer (not the value 'fai\ +l') +gap> ASS_VEC8BIT(v, 1, fail);; +gap> IsPlistRep(v); +true +gap> v; +[ fail, 0*Z(5) ] + +# +# UNB_VEC8BIT +# +gap> v := V8([o]);; UNB_VEC8BIT(v, 1);; v = empty; +true + +# bad arguments +gap> UNB_VEC8BIT(fail, 1); +Error, UNB_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fail\ +') +gap> UNB_VEC8BIT(v, fail); +Error, UNB_VEC8BIT: must be a positive small integer (not the value 'fai\ +l') + +# +# Q_VEC8BIT +# +gap> Q_VEC8BIT(empty); +5 + +# bad arguments +gap> Q_VEC8BIT(fail); +Error, Q_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fail') + +# +# SHALLOWCOPY_VEC8BIT +# +gap> v := SHALLOWCOPY_VEC8BIT(empty);; v = empty and not IsIdenticalObj(v, empty); +true + +# bad arguments +gap> SHALLOWCOPY_VEC8BIT(fail); +Error, SHALLOWCOPY_VEC8BIT: must belong to Is8BitVectorRep (not the val\ +ue 'fail') + +# +# SUM_VEC8BIT_VEC8BIT +# +gap> SUM_VEC8BIT_VEC8BIT(empty, empty); +< mutable compressed vector length 0 over GF(5) > +gap> SUM_VEC8BIT_VEC8BIT(one, oneZero); +[ Z(5)^0 ] + +# bad arguments +gap> SUM_VEC8BIT_VEC8BIT(fail, empty); +Error, SUM_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the value\ + 'fail') +gap> SUM_VEC8BIT_VEC8BIT(empty, fail); +Error, SUM_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the value\ + 'fail') + +# +# DIFF_VEC8BIT_VEC8BIT +# +gap> DIFF_VEC8BIT_VEC8BIT(empty, empty); +< mutable compressed vector length 0 over GF(5) > +gap> DIFF_VEC8BIT_VEC8BIT(one, oneZero); +[ Z(5)^0 ] + +# bad arguments +gap> DIFF_VEC8BIT_VEC8BIT(fail, empty); +Error, DIFF_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the valu\ +e 'fail') +gap> DIFF_VEC8BIT_VEC8BIT(empty, fail); +Error, DIFF_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the valu\ +e 'fail') + +# +# PROD_VEC8BIT_FFE +# +gap> PROD_VEC8BIT_FFE(empty, o); +< mutable compressed vector length 0 over GF(5) > +gap> PROD_VEC8BIT_FFE(one, z); +[ 0*Z(5) ] + +# bad arguments +gap> PROD_VEC8BIT_FFE(fail, o); +Error, PROD_VEC8BIT_FFE: must belong to Is8BitVectorRep (not the value '\ +fail') +gap> PROD_VEC8BIT_FFE(empty, fail); +Error, PROD_VEC8BIT_FFE: must be a finite field element (not the value '\ +fail') + +# +# PROD_FFE_VEC8BIT +# +gap> PROD_FFE_VEC8BIT(o, empty); +< mutable compressed vector length 0 over GF(5) > +gap> PROD_FFE_VEC8BIT(z, one); +[ 0*Z(5) ] + +# bad arguments +gap> PROD_FFE_VEC8BIT(fail, empty); +Error, PROD_FFE_VEC8BIT: must be a finite field element (not the value '\ +fail') +gap> PROD_FFE_VEC8BIT(o, fail); +Error, PROD_FFE_VEC8BIT: must belong to Is8BitVectorRep (not the value '\ +fail') + +# +# AINV_VEC8BIT_MUTABLE +# +gap> AINV_VEC8BIT_MUTABLE(empty); +< mutable compressed vector length 0 over GF(5) > +gap> AINV_VEC8BIT_MUTABLE(oneZero); +[ 0*Z(5) ] + +# bad arguments +gap> AINV_VEC8BIT_MUTABLE(fail); +Error, AINV_VEC8BIT_MUTABLE: must belong to Is8BitVectorRep (not the val\ +ue 'fail') + +# +# AINV_VEC8BIT_IMMUTABLE +# +gap> AINV_VEC8BIT_IMMUTABLE(empty); +< immutable compressed vector length 0 over GF(5) > +gap> AINV_VEC8BIT_IMMUTABLE(oneZero); +[ 0*Z(5) ] + +# bad arguments +gap> AINV_VEC8BIT_IMMUTABLE(fail); +Error, AINV_VEC8BIT_IMMUTABLE: must belong to Is8BitVectorRep (not the v\ +alue 'fail') + +# +# AINV_VEC8BIT_SAME_MUTABILITY +# +gap> AINV_VEC8BIT_SAME_MUTABILITY(empty); +< mutable compressed vector length 0 over GF(5) > +gap> AINV_VEC8BIT_SAME_MUTABILITY(oneZero); +[ 0*Z(5) ] + +# bad arguments +gap> AINV_VEC8BIT_SAME_MUTABILITY(fail); +Error, AINV_VEC8BIT_SAME_MUTABILITY: must belong to Is8BitVectorRep (not\ + the value 'fail') + +# +# ZERO_VEC8BIT +# +gap> ZERO_VEC8BIT(empty); +< mutable compressed vector length 0 over GF(5) > +gap> ZERO_VEC8BIT(pair); +[ 0*Z(5), 0*Z(5) ] + +# bad arguments +gap> ZERO_VEC8BIT(fail); +Error, ZERO_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fail\ +') + +# +# ZERO_VEC8BIT_2 +# +gap> ZERO_VEC8BIT_2(q, 0); +< mutable compressed vector length 0 over GF(5) > +gap> ZERO_VEC8BIT_2(q, 2); +[ 0*Z(5), 0*Z(5) ] + +# bad arguments +gap> ZERO_VEC8BIT_2(fail, 0); +Error, ZERO_VEC8BIT_2: must be a positive small integer (not the value 'fa\ +il') +gap> ZERO_VEC8BIT_2(q, fail); +Error, ZERO_VEC8BIT_2: must be a non-negative small integer (not the val\ +ue 'fail') + +# +# EQ_VEC8BIT_VEC8BIT +# +gap> EQ_VEC8BIT_VEC8BIT(empty, empty); +true +gap> EQ_VEC8BIT_VEC8BIT(empty, one); +false + +# bad arguments +gap> EQ_VEC8BIT_VEC8BIT(fail, empty); +Error, EQ_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the value \ +'fail') +gap> EQ_VEC8BIT_VEC8BIT(empty, fail); +Error, EQ_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the value \ +'fail') + +# +# LT_VEC8BIT_VEC8BIT +# +gap> LT_VEC8BIT_VEC8BIT(empty, one); +true +gap> LT_VEC8BIT_VEC8BIT(one, empty); +false + +# bad arguments +gap> LT_VEC8BIT_VEC8BIT(fail, one); +Error, LT_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the value \ +'fail') +gap> LT_VEC8BIT_VEC8BIT(empty, fail); +Error, LT_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the value \ +'fail') + +# +# PROD_VEC8BIT_VEC8BIT +# +gap> PROD_VEC8BIT_VEC8BIT(empty, empty); +0*Z(5) +gap> PROD_VEC8BIT_VEC8BIT(one, one); +Z(5)^0 + +# bad arguments +gap> PROD_VEC8BIT_VEC8BIT(fail, empty); +Error, PROD_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the valu\ +e 'fail') +gap> PROD_VEC8BIT_VEC8BIT(empty, fail); +Error, PROD_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the valu\ +e 'fail') + +# +# DISTANCE_VEC8BIT_VEC8BIT +# +gap> DISTANCE_VEC8BIT_VEC8BIT(empty, empty); +0 +gap> DISTANCE_VEC8BIT_VEC8BIT(one, oneZero); +1 + +# bad arguments +gap> DISTANCE_VEC8BIT_VEC8BIT(fail, empty); +Error, DISTANCE_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the \ +value 'fail') +gap> DISTANCE_VEC8BIT_VEC8BIT(empty, fail); +Error, DISTANCE_VEC8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the \ +value 'fail') + +# +# ADD_ROWVECTOR_VEC8BITS_5 +# +gap> v := V8([o, z]);; ADD_ROWVECTOR_VEC8BITS_5(v, V8([z, o]), o, 2, 2);; v = V8([o, o]); +true + +# bad arguments +gap> ADD_ROWVECTOR_VEC8BITS_5(fail, V8([z, o]), o, 2, 2); +Error, ADD_ROWVECTOR_VEC8BITS_5: must belong to Is8BitVectorRep (not the \ +value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_5(v, fail, o, 2, 2); +Error, ADD_ROWVECTOR_VEC8BITS_5: must belong to Is8BitVectorRep (not the \ +value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_5(v, V8([z, o]), fail, 2, 2); +Error, ADD_ROWVECTOR_VEC8BITS_5: must be a finite field element (not the\ + value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_5(v, V8([z, o]), o, fail, 2); +Error, ADD_ROWVECTOR_VEC8BITS_5: must be a positive small integer (not \ +the value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_5(v, V8([z, o]), o, 2, fail); +Error, ADD_ROWVECTOR_VEC8BITS_5: must be a positive small integer (not th\ +e value 'fail') + +# +# ADD_ROWVECTOR_VEC8BITS_3 +# +gap> v := V8([]);; ADD_ROWVECTOR_VEC8BITS_3(v, empty, o);; v = empty; +true + +# bad arguments +gap> ADD_ROWVECTOR_VEC8BITS_3(fail, empty, o); +Error, ADD_ROWVECTOR_VEC8BITS_3: must belong to Is8BitVectorRep (not the \ +value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_3(v, fail, o); +Error, ADD_ROWVECTOR_VEC8BITS_3: must belong to Is8BitVectorRep (not the \ +value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_3(v, empty, fail); +Error, ADD_ROWVECTOR_VEC8BITS_3: must be a finite field element (not the\ + value 'fail') + +# +# ADD_ROWVECTOR_VEC8BITS_2 +# +gap> v := V8([]);; ADD_ROWVECTOR_VEC8BITS_2(v, empty);; v = empty; +true + +# bad arguments +gap> ADD_ROWVECTOR_VEC8BITS_2(fail, empty); +Error, ADD_ROWVECTOR_VEC8BITS_2: must belong to Is8BitVectorRep (not the \ +value 'fail') +gap> ADD_ROWVECTOR_VEC8BITS_2(v, fail); +Error, ADD_ROWVECTOR_VEC8BITS_2: must belong to Is8BitVectorRep (not the \ +value 'fail') + +# +# MULT_VECTOR_VEC8BITS +# +gap> v := V8([]);; MULT_VECTOR_VEC8BITS(v, o);; v = empty; +true + +# bad arguments +gap> MULT_VECTOR_VEC8BITS(fail, o); +Error, MULT_VECTOR_VEC8BITS: must belong to Is8BitVectorRep (not the val\ +ue 'fail') +gap> MULT_VECTOR_VEC8BITS(v, fail); +Error, MULT_VECTOR_VEC8BITS: must be a finite field element (not the val\ +ue 'fail') + +# +# POSITION_NONZERO_VEC8BIT +# +gap> POSITION_NONZERO_VEC8BIT(empty, z); +1 +gap> POSITION_NONZERO_VEC8BIT(one, z); +1 + +# bad arguments +gap> POSITION_NONZERO_VEC8BIT(fail, z); +Error, POSITION_NONZERO_VEC8BIT: must belong to Is8BitVectorRep (not th\ +e value 'fail') +gap> POSITION_NONZERO_VEC8BIT(empty, fail); +1 + +# +# POSITION_NONZERO_VEC8BIT3 +# +gap> POSITION_NONZERO_VEC8BIT3(empty, z, 1); +1 +gap> POSITION_NONZERO_VEC8BIT3(V8([z, o]), z, 2); +3 + +# bad arguments +gap> POSITION_NONZERO_VEC8BIT3(fail, z, 1); +Error, POSITION_NONZERO_VEC8BIT3: must belong to Is8BitVectorRep (not t\ +he value 'fail') +gap> POSITION_NONZERO_VEC8BIT3(empty, fail, 1); +1 +gap> POSITION_NONZERO_VEC8BIT3(empty, z, fail); +Error, POSITION_NONZERO_VEC8BIT3: must be a non-negative small integer \ +(not the value 'fail') + +# +# APPEND_VEC8BIT +# +gap> v := V8([]);; APPEND_VEC8BIT(v, one);; v = one; +true + +# bad arguments +gap> APPEND_VEC8BIT(fail, one); +Error, APPEND_VEC8BIT: must belong to Is8BitVectorRep (not the value 'f\ +ail') +gap> APPEND_VEC8BIT(v, fail); +Error, APPEND_VEC8BIT: must belong to Is8BitVectorRep (not the value 'f\ +ail') + +# +# NUMBER_VEC8BIT +# +gap> NUMBER_VEC8BIT(empty); +1 +gap> NUMBER_VEC8BIT(one); +1 + +# bad arguments +gap> NUMBER_VEC8BIT(fail); +Error, NUMBER_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fa\ +il') + +# +# PROD_VEC8BIT_MATRIX +# +gap> PROD_VEC8BIT_MATRIX(one, [fail]); +"TRY_NEXT_METHOD" +gap> PROD_VEC8BIT_MATRIX(one, [one]); +[ Z(5)^0 ] + +# bad arguments +gap> PROD_VEC8BIT_MATRIX(fail, [fail]); +Error, PROD_VEC8BIT_MATRIX: must belong to Is8BitVectorRep (not the valu\ +e 'fail') +gap> PROD_VEC8BIT_MATRIX(one, fail); +Error, PROD_VEC8BIT_MATRIX: must be a plain list (not the value 'fail') + +# +# CONV_MAT8BIT +# +gap> m := [V8([]), V8([])];; CONV_MAT8BIT(m, q);; EQ_MAT8BIT_MAT8BIT(m, Mx08(2)); +true + +# bad arguments +gap> CONV_MAT8BIT(fail, q); +Error, CONV_MAT8BIT: must be a plain list (not the value 'fail') +gap> CONV_MAT8BIT(m, fail); +Error, CONV_MAT8BIT: must be a plain list (not a positional object) + +# +# PLAIN_MAT8BIT +# +gap> m := Mx08(2);; PLAIN_MAT8BIT(m);; IsPlistRep(m) and m = [[], []]; +true + +# bad arguments +gap> PLAIN_MAT8BIT(fail); +Error, PLAIN_MAT8BIT: must belong to Is8BitMatrixRep (not the value 'fai\ +l') + +# +# PROD_VEC8BIT_MAT8BIT +# +gap> PROD_VEC8BIT_MAT8BIT(empty, ZeroRowMat8()); +Error, PROD_VEC8BIT_MAT8BIT: compressed 8bit matrices with empty rows are not \ +supported +gap> PROD_VEC8BIT_MAT8BIT(empty, Mx08(2)); +< mutable compressed vector length 0 over GF(5) > + +# bad arguments +gap> PROD_VEC8BIT_MAT8BIT(fail, ZeroRowMat8()); +Error, PROD_VEC8BIT_MAT8BIT: must belong to Is8BitVectorRep (not the val\ +ue 'fail') +gap> PROD_VEC8BIT_MAT8BIT(empty, fail); +Error, PROD_VEC8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the val\ +ue 'fail') + +# +# PROD_MAT8BIT_VEC8BIT +# +gap> PROD_MAT8BIT_VEC8BIT(ZeroRowMat8(), empty); +Error, PROD_MAT8BIT_VEC8BIT: compressed 8bit matrices with empty rows are not \ +supported +gap> PROD_MAT8BIT_VEC8BIT(Mx08(2), empty); +[ 0*Z(5), 0*Z(5) ] + +# bad arguments +gap> PROD_MAT8BIT_VEC8BIT(fail, empty); +Error, PROD_MAT8BIT_VEC8BIT: must belong to Is8BitMatrixRep (not the val\ +ue 'fail') +gap> PROD_MAT8BIT_VEC8BIT(ZeroRowMat8(), fail); +Error, PROD_MAT8BIT_VEC8BIT: must belong to Is8BitVectorRep (not the val\ +ue 'fail') + +# +# PROD_MAT8BIT_MAT8BIT +# +gap> PROD_MAT8BIT_MAT8BIT(ZeroRowMat8(), ZeroRowMat8()); +Error, PROD_MAT8BIT_MAT8BIT: compressed 8bit matrices with empty rows are not \ +supported +gap> PROD_MAT8BIT_MAT8BIT(M8([[o], [z]]), Mx08(1)) = Mx08(2); +true + +# bad arguments +gap> PROD_MAT8BIT_MAT8BIT(fail, ZeroRowMat8()); +Error, PROD_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the va\ +lue 'fail') +gap> PROD_MAT8BIT_MAT8BIT(ZeroRowMat8(), fail); +Error, PROD_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the va\ +lue 'fail') + +# +# INV_MAT8BIT_MUTABLE +# +gap> INV_MAT8BIT_MUTABLE(ZeroRowMat8()); +Error, INV_MAT8BIT_MUTABLE: compressed 8bit matrices with empty rows are not s\ +upported +gap> INV_MAT8BIT_MUTABLE(M8([[o]])) = M8([[o]]); +true + +# bad arguments +gap> INV_MAT8BIT_MUTABLE(fail); +Error, INV_MAT8BIT_MUTABLE: must belong to Is8BitMatrixRep (not the valu\ +e 'fail') + +# +# INV_MAT8BIT_SAME_MUTABILITY +# +gap> INV_MAT8BIT_SAME_MUTABILITY(ZeroRowMat8()); +Error, INV_MAT8BIT_SAME_MUTABILITY: compressed 8bit matrices with empty rows a\ +re not supported +gap> INV_MAT8BIT_SAME_MUTABILITY(M8([[o]])) = M8([[o]]); +true + +# bad arguments +gap> INV_MAT8BIT_SAME_MUTABILITY(fail); +Error, INV_MAT8BIT_SAME_MUTABILITY: must belong to Is8BitMatrixRep (not \ +the value 'fail') + +# +# INV_MAT8BIT_IMMUTABLE +# +gap> INV_MAT8BIT_IMMUTABLE(ZeroRowMat8()); +Error, INV_MAT8BIT_IMMUTABLE: compressed 8bit matrices with empty rows are not\ + supported +gap> INV_MAT8BIT_IMMUTABLE(IM8([[o]])) = IM8([[o]]); +true + +# bad arguments +gap> INV_MAT8BIT_IMMUTABLE(fail); +Error, INV_MAT8BIT_IMMUTABLE: must belong to Is8BitMatrixRep (not the va\ +lue 'fail') + +# +# ASS_MAT8BIT +# +gap> ASS_MAT8BIT(ZeroRowMat8(), 1, empty); +Error, ASS_MAT8BIT: compressed 8bit matrices with empty rows are not supported +gap> m := Mx08(1);; ASS_MAT8BIT(m, 2, empty);; m = Mx08(2); +true + +# bad arguments +gap> ASS_MAT8BIT(fail, 1, empty); +Error, ASS_MAT8BIT: must belong to Is8BitMatrixRep (not the value 'fail'\ +) +gap> ASS_MAT8BIT(ZeroRowMat8(), fail, empty); +Error, ASS_MAT8BIT: compressed 8bit matrices with empty rows are not supported +gap> ASS_MAT8BIT(ZeroRowMat8(), 1, fail); +Error, ASS_MAT8BIT: compressed 8bit matrices with empty rows are not supported + +# +# ELM_MAT8BIT +# +gap> ELM_MAT8BIT(Mx08(2), 1); +< mutable compressed vector length 0 over GF(5) > + +# bad arguments +gap> ELM_MAT8BIT(fail, 1); +Error, ELM_MAT8BIT: must belong to Is8BitMatrixRep (not the value 'fail'\ +) +gap> ELM_MAT8BIT(Mx08(2), fail); +Error, ELM_MAT8BIT: must be a positive small integer (not the value 'fai\ +l') + +# +# SWAP_ROWS_MAT8BIT +# +gap> m := Mx08(2);; SWAP_ROWS_MAT8BIT(m, 1, 2);; m = Mx08(2); +true + +# bad arguments +gap> SWAP_ROWS_MAT8BIT(fail, 1, 2); +Error, SWAP_ROWS_MAT8BIT: must belong to Is8BitMatrixRep (not the value \ +'fail') +gap> SWAP_ROWS_MAT8BIT(m, fail, 2); +Error, SWAP_ROWS_MAT8BIT: must be a small integer (not the value 'fail'\ +) +gap> SWAP_ROWS_MAT8BIT(m, 1, fail); +Error, SWAP_ROWS_MAT8BIT: must be a small integer (not the value 'fail'\ +) + +# +# SWAP_COLS_MAT8BIT +# +gap> m := ZeroRowMat8();; SWAP_COLS_MAT8BIT(m, 1, 1);; EQ_MAT8BIT_MAT8BIT(m, ZeroRowMat8()); +true + +# bad arguments +gap> SWAP_COLS_MAT8BIT(fail, 1, 1); +Error, SWAP_COLS_MAT8BIT: must belong to Is8BitMatrixRep (not the value \ +'fail') +gap> SWAP_COLS_MAT8BIT(m, fail, 1); +Error, SWAP_COLS_MAT8BIT: must be a small integer (not the value 'fail'\ +) +gap> SWAP_COLS_MAT8BIT(m, 1, fail); +Error, SWAP_COLS_MAT8BIT: must be a small integer (not the value 'fail'\ +) + +# +# SUM_MAT8BIT_MAT8BIT +# +gap> SUM_MAT8BIT_MAT8BIT(ZeroRowMat8(), ZeroRowMat8()); +Error, SUM_MAT8BIT_MAT8BIT: compressed 8bit matrices with empty rows are not s\ +upported +gap> SUM_MAT8BIT_MAT8BIT(Mx08(2), Mx08(2)) = Mx08(2); +true + +# bad arguments +gap> SUM_MAT8BIT_MAT8BIT(fail, ZeroRowMat8()); +Error, SUM_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the value\ + 'fail') +gap> SUM_MAT8BIT_MAT8BIT(ZeroRowMat8(), fail); +Error, SUM_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the value\ + 'fail') + +# +# DIFF_MAT8BIT_MAT8BIT +# +gap> DIFF_MAT8BIT_MAT8BIT(ZeroRowMat8(), ZeroRowMat8()); +Error, DIFF_MAT8BIT_MAT8BIT: compressed 8bit matrices with empty rows are not \ +supported +gap> DIFF_MAT8BIT_MAT8BIT(Mx08(2), Mx08(2)) = Mx08(2); +true + +# bad arguments +gap> DIFF_MAT8BIT_MAT8BIT(fail, ZeroRowMat8()); +Error, DIFF_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the valu\ +e 'fail') +gap> DIFF_MAT8BIT_MAT8BIT(ZeroRowMat8(), fail); +Error, DIFF_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the valu\ +e 'fail') + +# +# ADD_COEFFS_VEC8BIT_3 +# +gap> v := V8([]);; ADD_COEFFS_VEC8BIT_3(v, empty, o); +0 +gap> v; +< mutable compressed vector length 0 over GF(5) > + +# bad arguments +gap> ADD_COEFFS_VEC8BIT_3(fail, empty, o); +Error, ADD_COEFFS_VEC8BIT_3: must belong to Is8BitVectorRep (not the va\ +lue 'fail') +gap> ADD_COEFFS_VEC8BIT_3(v, fail, o); +Error, ADD_COEFFS_VEC8BIT_3: must belong to Is8BitVectorRep (not the va\ +lue 'fail') +gap> ADD_COEFFS_VEC8BIT_3(v, empty, fail); +Error, ADD_COEFFS_VEC8BIT_3: must be a finite field element (not the va\ +lue 'fail') + +# +# ADD_COEFFS_VEC8BIT_2 +# +gap> v := V8([]);; ADD_COEFFS_VEC8BIT_2(v, empty); +0 +gap> v; +< mutable compressed vector length 0 over GF(5) > + +# bad arguments +gap> ADD_COEFFS_VEC8BIT_2(fail, empty); +Error, ADD_COEFFS_VEC8BIT_2: must belong to Is8BitVectorRep (not the va\ +lue 'fail') +gap> ADD_COEFFS_VEC8BIT_2(v, fail); +Error, ADD_COEFFS_VEC8BIT_2: must belong to Is8BitVectorRep (not the va\ +lue 'fail') + +# +# SHIFT_VEC8BIT_LEFT +# +gap> v := V8([]);; SHIFT_VEC8BIT_LEFT(v, 3);; v = empty; +true + +# bad arguments +gap> SHIFT_VEC8BIT_LEFT(fail, 3); +Error, SHIFT_VEC8BIT_LEFT: must belong to Is8BitVectorRep (not the value\ + 'fail') +gap> SHIFT_VEC8BIT_LEFT(v, fail); +Error, SHIFT_VEC8BIT_LEFT: must be a non-negative small integer (not \ +the value 'fail') + +# +# SHIFT_VEC8BIT_RIGHT +# +gap> v := V8([]);; SHIFT_VEC8BIT_RIGHT(v, 3, z);; v = V8([z, z, z]); +true + +# bad arguments +gap> SHIFT_VEC8BIT_RIGHT(fail, 3, z); +Error, SHIFT_VEC8BIT_RIGHT: must belong to Is8BitVectorRep (not the valu\ +e 'fail') +gap> SHIFT_VEC8BIT_RIGHT(v, fail, z); +Error, SHIFT_VEC8BIT_RIGHT: must be a non-negative small integer (not\ + the value 'fail') +gap> SHIFT_VEC8BIT_RIGHT(v, 3, fail); +Error, SHIFT_VEC8BIT_RIGHT: must be a finite field element (not the val\ +ue 'fail') + +# +# RESIZE_VEC8BIT +# +gap> v := V8([]);; RESIZE_VEC8BIT(v, 2);; v = V8([z, z]); +true + +# bad arguments +gap> RESIZE_VEC8BIT(fail, 2); +Error, RESIZE_VEC8BIT: must belong to Is8BitVectorRep (not the value 'fa\ +il') +gap> RESIZE_VEC8BIT(v, fail); +Error, RESIZE_VEC8BIT: must be a non-negative small integer (not the\ + value 'fail') + +# +# RIGHTMOST_NONZERO_VEC8BIT +# +gap> RIGHTMOST_NONZERO_VEC8BIT(empty); +0 +gap> RIGHTMOST_NONZERO_VEC8BIT(V8([z, o])); +2 + +# bad arguments +gap> RIGHTMOST_NONZERO_VEC8BIT(fail); +Error, RIGHTMOST_NONZERO_VEC8BIT: must belong to Is8BitVectorRep (not th\ +e value 'fail') + +# +# PROD_COEFFS_VEC8BIT +# +gap> PROD_COEFFS_VEC8BIT(empty, 0, empty, 0); +< mutable compressed vector length 0 over GF(5) > +gap> PROD_COEFFS_VEC8BIT(one, 1, one, 1); +[ Z(5)^0 ] + +# bad arguments +gap> PROD_COEFFS_VEC8BIT(fail, 0, empty, 0); +Error, PROD_COEFFS_VEC8BIT: must belong to Is8BitVectorRep (not the value\ + 'fail') +gap> PROD_COEFFS_VEC8BIT(empty, fail, empty, 0); +Error, PROD_COEFFS_VEC8BIT: must be a non-negative small integer (not the\ + value 'fail') +gap> PROD_COEFFS_VEC8BIT(empty, 0, fail, 0); +Error, PROD_COEFFS_VEC8BIT: must belong to Is8BitVectorRep (not the value\ + 'fail') +gap> PROD_COEFFS_VEC8BIT(empty, 0, empty, fail); +Error, PROD_COEFFS_VEC8BIT: must be a non-negative small integer (not the\ + value 'fail') + +# +# REDUCE_COEFFS_VEC8BIT +# +gap> s := MAKE_SHIFTED_COEFFS_VEC8BIT(V8([o]), 1);; +gap> v := V8([o]);; REDUCE_COEFFS_VEC8BIT(v, 1, s); +0 +gap> v; +< mutable compressed vector length 0 over GF(5) > + +# bad arguments +gap> REDUCE_COEFFS_VEC8BIT(fail, 1, s); +Error, REDUCE_COEFFS_VEC8BIT: must belong to Is8BitVectorRep (not the val\ +ue 'fail') +gap> REDUCE_COEFFS_VEC8BIT(v, fail, s); +Error, REDUCE_COEFFS_VEC8BIT: must be a non-negative small integer (not t\ +he value 'fail') +gap> REDUCE_COEFFS_VEC8BIT(v, 1, fail); +Error, REDUCE_COEFFS_VEC8BIT: must be a plain list (not the value \ +'fail') + +# +# QUOTREM_COEFFS_VEC8BIT +# +gap> s := MAKE_SHIFTED_COEFFS_VEC8BIT(V8([o]), 1);; +gap> QUOTREM_COEFFS_VEC8BIT(empty, 0, s); +[ < mutable compressed vector length 0 over GF(5) >, + < mutable compressed vector length 0 over GF(5) > ] + +# bad arguments +gap> QUOTREM_COEFFS_VEC8BIT(fail, 0, s); +Error, QUOTREM_COEFFS_VEC8BIT: must belong to Is8BitVectorRep (not the va\ +lue 'fail') +gap> QUOTREM_COEFFS_VEC8BIT(empty, fail, s); +Error, QUOTREM_COEFFS_VEC8BIT: must be a non-negative small integer (not \ +the value 'fail') +gap> QUOTREM_COEFFS_VEC8BIT(empty, 0, fail); +Error, QUOTREM_COEFFS_VEC8BIT: must be a plain list (not the value\ + 'fail') + +# +# MAKE_SHIFTED_COEFFS_VEC8BIT +# +gap> s := MAKE_SHIFTED_COEFFS_VEC8BIT(V8([o]), 1);; s[4]; +1 +gap> s[5]; +Z(5)^0 + +# bad arguments +gap> MAKE_SHIFTED_COEFFS_VEC8BIT(fail, 1); +Error, MAKE_SHIFTED_COEFFS_VEC8BIT: must belong to Is8BitVectorRep (not t\ +he value 'fail') +gap> MAKE_SHIFTED_COEFFS_VEC8BIT(V8([o]), fail); +Error, MAKE_SHIFTED_COEFFS_VEC8BIT: must be a non-negative small integer \ +(not the value 'fail') + +# +# DISTANCE_DISTRIB_VEC8BITS +# +gap> d := [0, 0];; DISTANCE_DISTRIB_VEC8BITS(Veclis8([one]), oneZero, d);; d; +[ 1, 4 ] + +# bad arguments +gap> DISTANCE_DISTRIB_VEC8BITS(fail, oneZero, d); +Error, DISTANCE_DISTRIB_VEC8BITS: must be a plain list (not the value\ + 'fail') +gap> DISTANCE_DISTRIB_VEC8BITS(Veclis8([one]), fail, d); +Error, DISTANCE_DISTRIB_VEC8BITS: must belong to Is8BitVectorRep (not th\ +e value 'fail') +gap> DISTANCE_DISTRIB_VEC8BITS(Veclis8([one]), oneZero, fail); +Error, DISTANCE_DISTRIB_VEC8BITS: must be a plain list (not the value 'fai\ +l') + +# +# A_CLOSEST_VEC8BIT +# +gap> A_CLOSEST_VEC8BIT(Veclis8([one]), one, 0, 0); +[ Z(5)^0 ] + +# bad arguments +gap> A_CLOSEST_VEC8BIT(fail, one, 0, 0); +Error, A_CLOSEST_VEC8BIT: must be a plain list (not the value 'fail') +gap> A_CLOSEST_VEC8BIT(Veclis8([one]), fail, 0, 0); +Error, A_CLOSEST_VEC8BIT: must belong to Is8BitVectorRep (not the value \ +'fail') +gap> A_CLOSEST_VEC8BIT(Veclis8([one]), one, fail, 0); +Error, A_CLOSEST_VEC8BIT: must be a non-negative small integer (not the \ +value 'fail') +gap> A_CLOSEST_VEC8BIT(Veclis8([one]), one, 0, fail); +Error, A_CLOSEST_VEC8BIT: must be a non-negative small integer (not the\ + value 'fail') + +# +# A_CLOSEST_VEC8BIT_COORDS +# +gap> A_CLOSEST_VEC8BIT_COORDS(Veclis8([one]), one, 0, 0); +[ [ Z(5)^0 ], [ 1 ] ] + +# bad arguments +gap> A_CLOSEST_VEC8BIT_COORDS(fail, one, 0, 0); +Error, A_CLOSEST_VEC8BIT_COORDS: must be a plain list (not the value \ +'fail') +gap> A_CLOSEST_VEC8BIT_COORDS(Veclis8([one]), fail, 0, 0); +Error, A_CLOSEST_VEC8BIT_COORDS: must belong to Is8BitVectorRep (not the\ + value 'fail') +gap> A_CLOSEST_VEC8BIT_COORDS(Veclis8([one]), one, fail, 0); +Error, A_CLOSEST_VEC8BIT_COORDS: must be a non-negative small integer (n\ +ot the value 'fail') +gap> A_CLOSEST_VEC8BIT_COORDS(Veclis8([one]), one, 0, fail); +Error, A_CLOSEST_VEC8BIT_COORDS: must be a non-negative small integer (\ +not the value 'fail') + +# +# COSET_LEADERS_INNER_8BITS +# +gap> leaders := [Immutable(oneZero)];; leaders[6] := false;; + +#gap> COSET_LEADERS_INNER_8BITS(Veclis8([one]), 1, 1, leaders, f5); +#4 +#gap> leaders[2]; +#[ Z(5)^0 ] +# +# bad arguments +gap> COSET_LEADERS_INNER_8BITS(fail, 1, 1, leaders, f5); +Error, COSET_LEADERS_INNER_8BITS: must be a plain list (not the value\ + 'fail') +gap> COSET_LEADERS_INNER_8BITS(Veclis8([one]), fail, 1, leaders, f5); +Error, COSET_LEADERS_INNER_8BITS: must be a small integer (not the va\ +lue 'fail') +gap> COSET_LEADERS_INNER_8BITS(Veclis8([one]), 1, fail, leaders, f5); +Error, COSET_LEADERS_INNER_8BITS: must be a small integer (not the va\ +lue 'fail') +gap> COSET_LEADERS_INNER_8BITS(Veclis8([one]), 1, 1, fail, f5); +Error, COSET_LEADERS_INNER_8BITS: must be a plain list (not the valu\ +e 'fail') +gap> COSET_LEADERS_INNER_8BITS(Veclis8([one]), 1, 1, leaders, fail); +Error, COSET_LEADERS_INNER_8BITS: must be a plain list (not the value \ +'fail') + +# +# SEMIECHELON_LIST_VEC8BITS +# +gap> s := SEMIECHELON_LIST_VEC8BITS([one]);; s.heads = [1] and s.vectors = [one]; +true + +# bad arguments +gap> SEMIECHELON_LIST_VEC8BITS(fail); +Error, SEMIECHELON_LIST_VEC8BITS: must be a plain list (not the value 'f\ +ail') + +# +# SEMIECHELON_LIST_VEC8BITS_TRANSFORMATIONS +# +gap> s := SEMIECHELON_LIST_VEC8BITS_TRANSFORMATIONS([one]);; s.heads = [1] and s.vectors = [one] and s.coeffs = [one]; +true + +# bad arguments +gap> SEMIECHELON_LIST_VEC8BITS_TRANSFORMATIONS(fail); +Error, SEMIECHELON_LIST_VEC8BITS_TRANSFORMATIONS: must be a plain list (\ +not the value 'fail') + +# +# TRIANGULIZE_LIST_VEC8BITS +# +gap> m := [one];; TRIANGULIZE_LIST_VEC8BITS(m);; m = [one]; +true + +# bad arguments +gap> TRIANGULIZE_LIST_VEC8BITS(fail); +Error, TRIANGULIZE_LIST_VEC8BITS: must be a plain list (not the value 'f\ +ail') + +# +# RANK_LIST_VEC8BITS +# +gap> RANK_LIST_VEC8BITS([one]); +1 + +# bad arguments +gap> RANK_LIST_VEC8BITS(fail); +Error, RANK_LIST_VEC8BITS: must be a plain list (not the value 'fail') + +# +# DETERMINANT_LIST_VEC8BITS +# +gap> DETERMINANT_LIST_VEC8BITS([one]); +Z(5)^0 + +# bad arguments +gap> DETERMINANT_LIST_VEC8BITS(fail); +Error, DETERMINANT_LIST_VEC8BITS: must be a plain list (not the value 'f\ +ail') + +# +# EQ_MAT8BIT_MAT8BIT +# +gap> EQ_MAT8BIT_MAT8BIT(Mx08(2), Mx08(2)) and EQ_MAT8BIT_MAT8BIT(ZeroRowMat8(), ZeroRowMat8()); +true + +# bad arguments +gap> EQ_MAT8BIT_MAT8BIT(fail, Mx08(2)); +Error, EQ_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the value \ +'fail') +gap> EQ_MAT8BIT_MAT8BIT(Mx08(2), fail); +Error, EQ_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the value \ +'fail') + +# +# LT_MAT8BIT_MAT8BIT +# +gap> LT_MAT8BIT_MAT8BIT(ZeroRowMat8(), Mx08(1)) and not LT_MAT8BIT_MAT8BIT(Mx08(1), ZeroRowMat8()); +true + +# bad arguments +gap> LT_MAT8BIT_MAT8BIT(fail, Mx08(1)); +Error, LT_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the value \ +'fail') +gap> LT_MAT8BIT_MAT8BIT(ZeroRowMat8(), fail); +Error, LT_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep (not the value \ +'fail') + +# +# TRANSPOSED_MAT8BIT +# +gap> TRANSPOSED_MAT8BIT(ZeroRowMat8()); +Error, TRANSPOSED_MAT8BIT: compressed 8bit matrices with empty rows are not su\ +pported +gap> EQ_MAT8BIT_MAT8BIT(TRANSPOSED_MAT8BIT(Mx08(2)), ZeroRowMat8()); +true + +# bad arguments gap> TRANSPOSED_MAT8BIT(fail); Error, TRANSPOSED_MAT8BIT: must belong to Is8BitMatrixRep (not the value\ 'fail') +# +# KRONECKERPRODUCT_MAT8BIT_MAT8BIT +# +gap> KRONECKERPRODUCT_MAT8BIT_MAT8BIT(ZeroRowMat8(), ZeroRowMat8()); +Error, KRONECKERPRODUCT_MAT8BIT_MAT8BIT: compressed 8bit matrices with empty r\ +ows are not supported +gap> KRONECKERPRODUCT_MAT8BIT_MAT8BIT(Mx08(2), M8([[o]])) = Mx08(2); +true + +# bad arguments +gap> KRONECKERPRODUCT_MAT8BIT_MAT8BIT(fail, ZeroRowMat8()); +Error, KRONECKERPRODUCT_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep\ + (not the value 'fail') +gap> KRONECKERPRODUCT_MAT8BIT_MAT8BIT(ZeroRowMat8(), fail); +Error, KRONECKERPRODUCT_MAT8BIT_MAT8BIT: must belong to Is8BitMatrixRep\ + (not the value 'fail') + +# +# MAT_ELM_MAT8BIT +# +gap> MAT_ELM_MAT8BIT(M8([[o]]), 1, 1); +Z(5)^0 + +# bad arguments +gap> MAT_ELM_MAT8BIT(fail, 1, 1); +Error, MAT_ELM_MAT8BIT: must belong to Is8BitMatrixRep (not the value 'f\ +ail') +gap> MAT_ELM_MAT8BIT(M8([[o]]), fail, 1); +Error, MAT_ELM_MAT8BIT: must be a positive small integer (not the value \ +'fail') +gap> MAT_ELM_MAT8BIT(M8([[o]]), 1, fail); +Error, MAT_ELM_MAT8BIT: must be a positive small integer (not the value \ +'fail') + +# +# SET_MAT_ELM_MAT8BIT +# +gap> m := M8([[z]]);; SET_MAT_ELM_MAT8BIT(m, 1, 1, o);; m = M8([[o]]); +true + +# bad arguments +gap> SET_MAT_ELM_MAT8BIT(fail, 1, 1, o); +Error, SET_MAT_ELM_MAT8BIT: must belong to Is8BitMatrixRep (not the valu\ +e 'fail') +gap> SET_MAT_ELM_MAT8BIT(m, fail, 1, o); +Error, SET_MAT_ELM_MAT8BIT: must be a positive small integer (not the va\ +lue 'fail') +gap> SET_MAT_ELM_MAT8BIT(m, 1, fail, o); +Error, SET_MAT_ELM_MAT8BIT: must be a positive small integer (not the va\ +lue 'fail') +gap> SET_MAT_ELM_MAT8BIT(m, 1, 1, fail); +Error, Attempt to convert locked compressed vector to plain list + # gap> STOP_TEST("kernel/vec8bit.tst"); diff --git a/tst/testinstall/kernel/vecgf2.tst b/tst/testinstall/kernel/vecgf2.tst index 7c4a838349..c3021d52cb 100644 --- a/tst/testinstall/kernel/vecgf2.tst +++ b/tst/testinstall/kernel/vecgf2.tst @@ -2,10 +2,981 @@ # Tests for functions defined in src/vecgf2.c # gap> START_TEST("kernel/vecgf2.tst"); +gap> z := 0*Z(2);; +gap> o := Z(2)^0;; +gap> V2 := function(list) +> local v; +> v := ShallowCopy(list); +> CONV_GF2VEC(v); +> return v; +> end;; +gap> M2 := function(rows) +> local m, i; +> m := List(rows, ShallowCopy); +> for i in [1 .. Length(m)] do +> CONV_GF2VEC(m[i]); +> od; +> CONV_GF2MAT(m); +> return m; +> end;; +gap> Mx02 := n -> M2(List([1 .. n], i -> []));; +gap> Veclis2 := function(rows) +> local f, fdi, fdip, veclis, row, mults, j, mult; +> f := AsSSortedList(GF(2)); +> fdi := []; +> for j in [2 .. Length(f)] do +> fdi[j - 1] := f[j] - f[j - 1]; +> od; +> Add(fdi, -Last(f)); +> fdip := List(fdi, x -> Position(fdi, x)); +> veclis := []; +> for row in rows do +> mults := []; +> mults[Length(fdi) + 1] := false; +> for j in [1 .. Length(fdi)] do +> if fdip[j] < j then +> mult := mults[fdip[j]]; +> else +> mult := fdi[j] * row; +> fi; +> mults[j] := mult; +> od; +> Add(veclis, mults); +> od; +> return veclis; +> end;; +gap> empty := V2([]);; +gap> one := V2([o]);; +gap> oneZero := V2([z]);; # +# CONV_GF2VEC +# +gap> v := [];; CONV_GF2VEC(v); v; + + +# bad arguments +gap> CONV_GF2VEC(fail); +Error, CONV_GF2VEC: must be a small list (not the value 'fail') + +# +# COPY_GF2VEC +# +gap> v := COPY_GF2VEC([]); + + +# bad arguments +gap> COPY_GF2VEC(fail); +Error, COPY_GF2VEC: argument must be a list of GF2 elements + +# +# PLAIN_GF2VEC +# +gap> v := V2([]);; PLAIN_GF2VEC(v);; IsPlistRep(v) and Length(v) = 0; +true + +# bad arguments +gap> PLAIN_GF2VEC(fail); +Error, PLAIN_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# PLAIN_GF2MAT +# +gap> m := Mx02(2);; PLAIN_GF2MAT(m);; IsPlistRep(m) and m = [[], []]; +true + +# bad arguments +gap> PLAIN_GF2MAT(fail); +Error, PLAIN_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# EQ_GF2VEC_GF2VEC +# +gap> EQ_GF2VEC_GF2VEC(empty, empty); +true +gap> EQ_GF2VEC_GF2VEC(empty, one); +false + +# bad arguments +gap> EQ_GF2VEC_GF2VEC(fail, empty); +Error, EQ_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> EQ_GF2VEC_GF2VEC(empty, fail); +Error, EQ_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# LT_GF2VEC_GF2VEC +# +gap> LT_GF2VEC_GF2VEC(oneZero, one); +true +gap> LT_GF2VEC_GF2VEC(one, oneZero); +false + +# bad arguments +gap> LT_GF2VEC_GF2VEC(fail, one); +Error, LT_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> LT_GF2VEC_GF2VEC(oneZero, fail); +Error, LT_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# EQ_GF2MAT_GF2MAT +# +gap> EQ_GF2MAT_GF2MAT(Mx02(2), Mx02(2)); +true +gap> EQ_GF2MAT_GF2MAT(Mx02(1), Mx02(2)); +false + +# bad arguments +gap> EQ_GF2MAT_GF2MAT(fail, Mx02(2)); +Error, EQ_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> EQ_GF2MAT_GF2MAT(Mx02(2), fail); +Error, EQ_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# LT_GF2MAT_GF2MAT +# +gap> LT_GF2MAT_GF2MAT(Mx02(1), Mx02(2)); +true +gap> LT_GF2MAT_GF2MAT(Mx02(2), Mx02(1)); +false + +# bad arguments +gap> LT_GF2MAT_GF2MAT(fail, Mx02(2)); +Error, LT_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> LT_GF2MAT_GF2MAT(Mx02(1), fail); +Error, LT_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# LEN_GF2VEC +# +gap> LEN_GF2VEC(empty); +0 +gap> LEN_GF2VEC(V2([o, z])); +2 + +# bad arguments +gap> LEN_GF2VEC(fail); +Error, LEN_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# ELM0_GF2VEC +# +gap> ELM0_GF2VEC(empty, 1); +fail +gap> ELM0_GF2VEC(one, 1); +Z(2)^0 + +# bad arguments +gap> ELM0_GF2VEC(fail, 1); +Error, ELM0_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> ELM0_GF2VEC(empty, fail); +Error, ELM0_GF2VEC: must be a small integer (not the value 'fail') + +# +# ELM_GF2VEC +# +gap> ELM_GF2VEC(one, 1); +Z(2)^0 + +# bad arguments +gap> ELM_GF2VEC(fail, 1); +Error, ELM_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> ELM_GF2VEC(one, fail); +Error, ELM_GF2VEC: must be a small integer (not the value 'fail') + +# +# ELMS_GF2VEC +# +gap> ELMS_GF2VEC(empty, []) = empty; +true +gap> ELMS_GF2VEC(V2([o, z]), [1]); + + +# bad arguments +gap> ELMS_GF2VEC(fail, []); +Error, ELMS_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> ELMS_GF2VEC(empty, fail); +Error, Length: must be a list (not the value 'fail') + +# +# ASS_GF2VEC +# +gap> v := V2([]);; ASS_GF2VEC(v, 1, z);; v = oneZero; +true + +# bad arguments +gap> ASS_GF2VEC(fail, 1, z); +Error, ASS_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> ASS_GF2VEC(v, fail, z); +Error, ASS_GF2VEC: must be a small integer (not the value 'fail') +gap> ASS_GF2VEC(v, 1, fail); + +# +# ELM_GF2MAT +# +gap> ELM_GF2MAT(Mx02(2), 1); + + +# bad arguments +gap> ELM_GF2MAT(fail, 1); +Error, ELM_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> ELM_GF2MAT(Mx02(2), fail); +Error, ELM_GF2MAT: must be a small integer (not the value 'fail') + +# +# ASS_GF2MAT +# +gap> m := M2([[]]);; ASS_GF2MAT(m, 2, empty);; m = Mx02(2); +true + +# bad arguments +gap> ASS_GF2MAT(fail, 2, empty); +Error, ASS_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> ASS_GF2MAT(m, fail, empty); +Error, ASS_GF2MAT: must be a small integer (not the value 'fail') +gap> ASS_GF2MAT(m, 2, fail); + +# +# SWAP_ROWS_GF2MAT +# +gap> m := M2([[o], [z]]);; SWAP_ROWS_GF2MAT(m, 1, 2);; m = M2([[z], [o]]); +true + +# bad arguments +gap> SWAP_ROWS_GF2MAT(fail, 1, 2); +Error, SWAP_ROWS_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> SWAP_ROWS_GF2MAT(m, fail, 2); +Error, SWAP_ROWS_GF2MAT: must be a small integer (not the value 'fail') +gap> SWAP_ROWS_GF2MAT(m, 1, fail); +Error, SWAP_ROWS_GF2MAT: must be a small integer (not the value 'fail') + +# +# SWAP_COLS_GF2MAT +# +gap> m := M2([[o, z]]);; SWAP_COLS_GF2MAT(m, 1, 2);; m = M2([[z, o]]); +true + +# bad arguments +gap> SWAP_COLS_GF2MAT(fail, 1, 2); +Error, SWAP_COLS_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> SWAP_COLS_GF2MAT(m, fail, 2); +Error, SWAP_COLS_GF2MAT: must be a small integer (not the value 'fail') +gap> SWAP_COLS_GF2MAT(m, 1, fail); +Error, SWAP_COLS_GF2MAT: must be a small integer (not the value 'fail') + +# +# UNB_GF2VEC +# +gap> v := V2([o]);; UNB_GF2VEC(v, 1);; v = empty; +true + +# bad arguments +gap> UNB_GF2VEC(fail, 1); +Error, UNB_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> UNB_GF2VEC(v, fail); +Error, UNB_GF2VEC: must be a small integer (not the value 'fail') + +# +# UNB_GF2MAT +# +gap> m := M2([[]]);; UNB_GF2MAT(m, 1);; m = []; +true + +# bad arguments +gap> UNB_GF2MAT(fail, 1); +Error, UNB_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> UNB_GF2MAT(m, fail); +Error, UNB_GF2MAT: must be a small integer (not the value 'fail') + +# +# ZERO_GF2VEC +# +gap> ZERO_GF2VEC(empty); + +gap> ZERO_GF2VEC(V2([o, z])); + + +# bad arguments +gap> ZERO_GF2VEC(fail); +Error, ZERO_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# ZERO_GF2VEC_2 +# +gap> ZERO_GF2VEC_2(0); + +gap> ZERO_GF2VEC_2(2); + + +# bad arguments +gap> ZERO_GF2VEC_2(fail); +Error, ZERO_GF2VEC_2: must be a non-negative small integer (not the valu\ +e 'fail') + +# +# INV_GF2MAT_MUTABLE +# +gap> INV_GF2MAT_MUTABLE(M2([[o]])) = M2([[o]]); +true + +# bad arguments +gap> INV_GF2MAT_MUTABLE(fail); +Error, INV_GF2MAT_MUTABLE: must be a GF2 matrix (not the value 'fail') + +# +# INV_GF2MAT_SAME_MUTABILITY +# +gap> INV_GF2MAT_SAME_MUTABILITY(M2([[o]])) = M2([[o]]); +true + +# bad arguments +gap> INV_GF2MAT_SAME_MUTABILITY(fail); +Error, INV_GF2MAT_SAME_MUTABILITY: must be a GF2 matrix (not the value '\ +fail') + +# +# INV_GF2MAT_IMMUTABLE +# +gap> INV_GF2MAT_IMMUTABLE(Immutable(M2([[o]]))) = Immutable(M2([[o]])); +true + +# bad arguments +gap> INV_GF2MAT_IMMUTABLE(fail); +Error, INV_GF2MAT_IMMUTABLE: must be a GF2 matrix (not the value 'fail') + +# +# INV_PLIST_GF2VECS_DESTRUCTIVE +# +gap> m := [one];; INV_PLIST_GF2VECS_DESTRUCTIVE(m) = [one] and m = [one]; +true + +# bad arguments +gap> INV_PLIST_GF2VECS_DESTRUCTIVE(fail); +Error, INV_PLIST_GF2VECS_DESTRUCTIVE: must be a plain list (not the val\ +ue 'fail') + +# +# SUM_GF2VEC_GF2VEC +# +gap> SUM_GF2VEC_GF2VEC(empty, empty); + +gap> SUM_GF2VEC_GF2VEC(one, one); + + +# bad arguments +gap> SUM_GF2VEC_GF2VEC(fail, empty); +Error, SUM_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> SUM_GF2VEC_GF2VEC(empty, fail); +Error, SUM_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# PROD_GF2VEC_GF2VEC +# +gap> PROD_GF2VEC_GF2VEC(one, one); +Z(2)^0 + +# bad arguments +gap> PROD_GF2VEC_GF2VEC(fail, one); +Error, PROD_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> PROD_GF2VEC_GF2VEC(one, fail); +Error, PROD_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# PROD_GF2VEC_GF2MAT +# +gap> PROD_GF2VEC_GF2MAT(empty, Mx02(2)); + + +# bad arguments +gap> PROD_GF2VEC_GF2MAT(fail, Mx02(2)); +Error, PROD_GF2VEC_GF2MAT: must be a GF2 vector (not the value 'fail') +gap> PROD_GF2VEC_GF2MAT(empty, fail); +Error, PROD_GF2VEC_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# PROD_GF2MAT_GF2VEC +# +gap> PROD_GF2MAT_GF2VEC(Mx02(2), empty); + + +# bad arguments +gap> PROD_GF2MAT_GF2VEC(fail, empty); +Error, PROD_GF2MAT_GF2VEC: must be a GF2 matrix (not the value 'fail') +gap> PROD_GF2MAT_GF2VEC(Mx02(2), fail); +Error, PROD_GF2MAT_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# PROD_GF2MAT_GF2MAT +# +gap> PROD_GF2MAT_GF2MAT(M2([[o], [z]]), Mx02(1)) = Mx02(2); +true + +# bad arguments +gap> PROD_GF2MAT_GF2MAT(fail, Mx02(1)); +Error, PROD_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> PROD_GF2MAT_GF2MAT(M2([[o], [z]]), fail); +Error, PROD_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# PROD_GF2MAT_GF2MAT_SIMPLE +# +gap> PROD_GF2MAT_GF2MAT_SIMPLE(M2([[o], [z]]), Mx02(1)) = Mx02(2); +true + +# bad arguments +gap> PROD_GF2MAT_GF2MAT_SIMPLE(fail, Mx02(1)); +Error, PROD_GF2MAT_GF2MAT_SIMPLE: must be a GF2 matrix (not the value 'fa\ +il') +gap> PROD_GF2MAT_GF2MAT_SIMPLE(M2([[o], [z]]), fail); +Error, PROD_GF2MAT_GF2MAT_SIMPLE: must be a GF2 matrix (not the value 'fa\ +il') + +# +# PROD_GF2MAT_GF2MAT_ADVANCED +# +gap> PROD_GF2MAT_GF2MAT_ADVANCED(M2([[o]]), M2([[o]]), 1, 1) = M2([[o]]); +true + +# bad arguments +gap> PROD_GF2MAT_GF2MAT_ADVANCED(fail, M2([[o]]), 1, 1); +Error, PROD_GF2MAT_GF2MAT_ADVANCED: must be a GF2 matrix (not the value '\ +fail') +gap> PROD_GF2MAT_GF2MAT_ADVANCED(M2([[o]]), fail, 1, 1); +Error, PROD_GF2MAT_GF2MAT_ADVANCED: must be a GF2 matrix (not the value '\ +fail') +gap> PROD_GF2MAT_GF2MAT_ADVANCED(M2([[o]]), M2([[o]]), fail, 1); +Error, PROD_GF2MAT_GF2MAT_ADVANCED: must be a small integer (not\ + the value 'fail') +gap> PROD_GF2MAT_GF2MAT_ADVANCED(M2([[o]]), M2([[o]]), 1, fail); +Error, PROD_GF2MAT_GF2MAT_ADVANCED: must be a small integer (not t\ +he value 'fail') + +# +# ADDCOEFFS_GF2VEC_GF2VEC_MULT +# +gap> v := V2([]);; ADDCOEFFS_GF2VEC_GF2VEC_MULT(v, empty, z); +0 +gap> v; + + +# bad arguments +gap> ADDCOEFFS_GF2VEC_GF2VEC_MULT(fail, empty, z); +Error, ADDCOEFFS_GF2VEC_GF2VEC_MULT: must be a GF2 vector (not the value \ +'fail') +gap> ADDCOEFFS_GF2VEC_GF2VEC_MULT(v, fail, z); +Error, ADDCOEFFS_GF2VEC_GF2VEC_MULT: must be a GF2 vector (not the value \ +'fail') +gap> ADDCOEFFS_GF2VEC_GF2VEC_MULT(v, empty, fail); +Error, ADDCOEFFS_GF2VEC_GF2VEC_MULT: must be a finite field element (not\ + the value 'fail') + +# +# ADDCOEFFS_GF2VEC_GF2VEC +# +gap> v := V2([]);; ADDCOEFFS_GF2VEC_GF2VEC(v, empty); +0 +gap> v; + + +# bad arguments +gap> ADDCOEFFS_GF2VEC_GF2VEC(fail, empty); +Error, ADDCOEFFS_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail\ +') +gap> ADDCOEFFS_GF2VEC_GF2VEC(v, fail); +Error, ADDCOEFFS_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail\ +') + +# +# SHRINKCOEFFS_GF2VEC +# +gap> v := V2([o, z]);; SHRINKCOEFFS_GF2VEC(v); +1 +gap> v; + + +# bad arguments +gap> SHRINKCOEFFS_GF2VEC(fail); +Error, SHRINKCOEFFS_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# POSITION_NONZERO_GF2VEC +# +gap> POSITION_NONZERO_GF2VEC(empty, z); +1 +gap> POSITION_NONZERO_GF2VEC(one, z); +1 + +# bad arguments +gap> POSITION_NONZERO_GF2VEC(fail, z); +Error, POSITION_NONZERO_GF2VEC: must be a GF2 vector (not the value 'fai\ +l') +gap> POSITION_NONZERO_GF2VEC(empty, fail); +1 + +# +# POSITION_NONZERO_GF2VEC3 +# +gap> POSITION_NONZERO_GF2VEC3(empty, z, 1); +1 +gap> POSITION_NONZERO_GF2VEC3(V2([z, o]), z, 2); +3 + +# bad arguments +gap> POSITION_NONZERO_GF2VEC3(fail, z, 1); +Error, POSITION_NONZERO_GF2VEC3: must be a GF2 vector (not the value 'fa\ +il') +gap> POSITION_NONZERO_GF2VEC3(empty, fail, 1); +1 +gap> POSITION_NONZERO_GF2VEC3(empty, z, fail); +Error, POSITION_NONZERO_GF2VEC3: must be a non-negative small integer (\ +not the value 'fail') + +# +# MULT_VECTOR_GF2VECS_2 +# +gap> v := V2([o]);; MULT_VECTOR_GF2VECS_2(v, o);; v = one; +true + +# bad arguments +gap> MULT_VECTOR_GF2VECS_2(fail, o); +Error, MULT_VECTOR_GF2VECS_2: must be a GF2 vector (not the value 'fail') +gap> MULT_VECTOR_GF2VECS_2(v, fail); +Error, MULT_VECTOR_GF2VECS_2: must be a finite field element (not the va\ +lue 'fail') + +# +# APPEND_GF2VEC +# +gap> v := V2([]);; APPEND_GF2VEC(v, one);; v = one; +true + +# bad arguments +gap> APPEND_GF2VEC(fail, one); +Error, APPEND_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> APPEND_GF2VEC(v, fail); +Error, APPEND_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# SHALLOWCOPY_GF2VEC +# +gap> v := SHALLOWCOPY_GF2VEC(empty);; v = empty and not IsIdenticalObj(v, empty); +true + +# bad arguments +gap> SHALLOWCOPY_GF2VEC(fail); +Error, SHALLOWCOPY_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# NUMBER_GF2VEC +# +gap> NUMBER_GF2VEC(empty); +1 +gap> NUMBER_GF2VEC(one); +1 + +# bad arguments +gap> NUMBER_GF2VEC(fail); +Error, NUMBER_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# TRANSPOSED_GF2MAT +# +gap> TRANSPOSED_GF2MAT(Mx02(2)); +Error, row index 1 exceeds 0, the number of rows + +# bad arguments gap> TRANSPOSED_GF2MAT(fail); -Error, TRANSPOSED_GF2MAT: Need compressed matrix over GF(2) +Error, TRANSPOSED_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# DIST_GF2VEC_GF2VEC +# +gap> DIST_GF2VEC_GF2VEC(empty, empty); +0 +gap> DIST_GF2VEC_GF2VEC(one, one); +0 + +# bad arguments +gap> DIST_GF2VEC_GF2VEC(fail, empty); +Error, DIST_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> DIST_GF2VEC_GF2VEC(empty, fail); +Error, DIST_GF2VEC_GF2VEC: must be a GF2 vector (not the value 'fail') + +# +# DIST_VEC_CLOS_VEC +# +gap> d := [0, 0];; DIST_VEC_CLOS_VEC(Veclis2([one]), oneZero, d);; d; +[ 1, 1 ] + +# bad arguments +gap> DIST_VEC_CLOS_VEC(fail, oneZero, d); +Error, DIST_VEC_CLOS_VEC: must be a plain list (not the value 'fail') +gap> DIST_VEC_CLOS_VEC(Veclis2([one]), fail, d); +Error, DIST_VEC_CLOS_VEC: must be a GF2 vector (not the value 'fail') +gap> DIST_VEC_CLOS_VEC(Veclis2([one]), oneZero, fail); +Error, DIST_VEC_CLOS_VEC: must be a plain list (not the value 'fail') + +# +# SUM_GF2MAT_GF2MAT +# +gap> SUM_GF2MAT_GF2MAT(Mx02(2), Mx02(2)) = Mx02(2); +true + +# bad arguments +gap> SUM_GF2MAT_GF2MAT(fail, Mx02(2)); +Error, SUM_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> SUM_GF2MAT_GF2MAT(Mx02(2), fail); +Error, SUM_GF2MAT_GF2MAT: must be a GF2 matrix (not the value 'fail') + +# +# A_CLOS_VEC +# +gap> A_CLOS_VEC(Veclis2([one]), one, 0, 0); + + +# bad arguments +gap> A_CLOS_VEC(fail, one, 0, 0); +Error, A_CLOS_VEC: must be a plain list (not the value 'fail') +gap> A_CLOS_VEC(Veclis2([one]), fail, 0, 0); +Error, A_CLOS_VEC: must be a GF2 vector (not the value 'fail') +gap> A_CLOS_VEC(Veclis2([one]), one, fail, 0); +Error, A_CLOS_VEC: must be a non-negative small integer (not the value '\ +fail') +gap> A_CLOS_VEC(Veclis2([one]), one, 0, fail); +Error, A_CLOS_VEC: must be a non-negative small integer (not the value \ +'fail') + +# +# A_CLOS_VEC_COORDS +# +gap> A_CLOS_VEC_COORDS(Veclis2([one]), one, 0, 0); +[ , [ 1 ] ] + +# bad arguments +gap> A_CLOS_VEC_COORDS(fail, one, 0, 0); +Error, A_CLOS_VEC_COORDS: must be a plain list (not the value 'fail') +gap> A_CLOS_VEC_COORDS(Veclis2([one]), fail, 0, 0); +Error, A_CLOS_VEC_COORDS: must be a GF2 vector (not the value 'fail') +gap> A_CLOS_VEC_COORDS(Veclis2([one]), one, fail, 0); +Error, A_CLOS_VEC_COORDS: must be a non-negative small integer (not the \ +value 'fail') +gap> A_CLOS_VEC_COORDS(Veclis2([one]), one, 0, fail); +Error, A_CLOS_VEC_COORDS: must be a non-negative small integer (not the\ + value 'fail') + +# +# COSET_LEADERS_INNER_GF2 +# +gap> leaders := [Immutable(oneZero)];; leaders[3] := false;; +gap> COSET_LEADERS_INNER_GF2(Veclis2([one]), 1, 1, leaders); +1 +gap> leaders[2]; + + +# bad arguments +gap> COSET_LEADERS_INNER_GF2(fail, 1, 1, leaders); +Error, COSET_LEADERS_INNER_GF2: must be a plain list (not the value '\ +fail') +gap> COSET_LEADERS_INNER_GF2(Veclis2([one]), fail, 1, leaders); +Error, COSET_LEADERS_INNER_GF2: must be a small integer (not the valu\ +e 'fail') +gap> COSET_LEADERS_INNER_GF2(Veclis2([one]), 1, fail, leaders); +Error, COSET_LEADERS_INNER_GF2: must be a small integer (not the valu\ +e 'fail') +gap> COSET_LEADERS_INNER_GF2(Veclis2([one]), 1, 1, fail); +Error, COSET_LEADERS_INNER_GF2: must be a plain list (not the value \ +'fail') + +# +# CONV_GF2MAT +# +gap> m := [V2([]), V2([])];; CONV_GF2MAT(m);; m = Mx02(2); +true + +# bad arguments +gap> CONV_GF2MAT(fail); +Error, CONV_GF2MAT: must be a small list (not the value 'fail') + +# +# PROD_GF2VEC_ANYMAT +# +gap> PROD_GF2VEC_ANYMAT(one, [fail]); +"TRY_NEXT_METHOD" +gap> PROD_GF2VEC_ANYMAT(one, [one]); + + +# bad arguments +gap> PROD_GF2VEC_ANYMAT(fail, [fail]); +Error, PROD_GF2VEC_ANYMAT: must be a GF2 vector (not the value 'fail') +gap> PROD_GF2VEC_ANYMAT(one, fail); +Error, PROD_GF2VEC_ANYMAT: must be a plain list (not the value 'fail') + +# +# RIGHTMOST_NONZERO_GF2VEC +# +gap> RIGHTMOST_NONZERO_GF2VEC(empty); +0 +gap> RIGHTMOST_NONZERO_GF2VEC(V2([z, o])); +2 + +# bad arguments +gap> RIGHTMOST_NONZERO_GF2VEC(fail); +Error, RIGHTMOST_NONZERO_GF2VEC: must be a GF2 vector (not the value 'fa\ +il') + +# +# RESIZE_GF2VEC +# +gap> v := V2([]);; RESIZE_GF2VEC(v, 2);; v = V2([z, z]); +true + +# bad arguments +gap> RESIZE_GF2VEC(fail, 2); +Error, RESIZE_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> RESIZE_GF2VEC(v, fail); +Error, RESIZE_GF2VEC: must be a non-negative small integer (not the v\ +alue 'fail') + +# +# SHIFT_LEFT_GF2VEC +# +gap> v := V2([]);; SHIFT_LEFT_GF2VEC(v, 3);; v = empty; +true + +# bad arguments +gap> SHIFT_LEFT_GF2VEC(fail, 3); +Error, SHIFT_LEFT_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> SHIFT_LEFT_GF2VEC(v, fail); +Error, SHIFT_LEFT_GF2VEC: must be a non-negative small integer (not t\ +he value 'fail') + +# +# SHIFT_RIGHT_GF2VEC +# +gap> v := V2([]);; SHIFT_RIGHT_GF2VEC(v, 3, z);; v = V2([z, z, z]); +true + +# bad arguments +gap> SHIFT_RIGHT_GF2VEC(fail, 3, z); +Error, SHIFT_RIGHT_GF2VEC: must be a GF2 vector (not the value 'fail') +gap> SHIFT_RIGHT_GF2VEC(v, fail, z); +Error, SHIFT_RIGHT_GF2VEC: must be a non-negative small integer (not \ +the value 'fail') +gap> SHIFT_RIGHT_GF2VEC(v, 3, fail); +Error, SHIFT_RIGHT_GF2VEC: must be a finite field element (not the valu\ +e 'fail') + +# +# ADD_GF2VEC_GF2VEC_SHIFTED +# +gap> v := V2([]);; ADD_GF2VEC_GF2VEC_SHIFTED(v, one, 0, 1);; v = oneZero; +true + +# bad arguments +gap> ADD_GF2VEC_GF2VEC_SHIFTED(fail, one, 0, 1); +Error, ADD_GF2VEC_GF2VEC_SHIFTED: must be a GF2 vector (not the value '\ +fail') +gap> ADD_GF2VEC_GF2VEC_SHIFTED(v, fail, 0, 1); +Error, ADD_GF2VEC_GF2VEC_SHIFTED: must be a GF2 vector (not the value '\ +fail') +gap> ADD_GF2VEC_GF2VEC_SHIFTED(v, one, fail, 1); +Error, ADD_GF2VEC_GF2VEC_SHIFTED: must be a non-negative small integer \ +(not the value 'fail') +gap> ADD_GF2VEC_GF2VEC_SHIFTED(v, one, 0, fail); +Error, ADD_GF2VEC_GF2VEC_SHIFTED: must be a non-negative small integer (\ +not the value 'fail') + +# +# PROD_COEFFS_GF2VEC +# +gap> PROD_COEFFS_GF2VEC(empty, 0, empty, 0); + +gap> PROD_COEFFS_GF2VEC(one, 1, one, 1); + + +# bad arguments +gap> PROD_COEFFS_GF2VEC(fail, 0, empty, 0); + +gap> PROD_COEFFS_GF2VEC(empty, fail, empty, 0); +Error, PROD_COEFFS_GF2VEC: must be a non-negative small integer (not th\ +e value 'fail') +gap> PROD_COEFFS_GF2VEC(empty, 0, fail, 0); + +gap> PROD_COEFFS_GF2VEC(empty, 0, empty, fail); +Error, PROD_COEFFS_GF2VEC: must be a non-negative small integer (not th\ +e value 'fail') + +# +# REDUCE_COEFFS_GF2VEC +# +gap> v := V2([o]);; w := V2([o, z]);; +gap> REDUCE_COEFFS_GF2VEC(v, 1, w, 1); +0 +gap> v; + + +# bad arguments +gap> REDUCE_COEFFS_GF2VEC(fail, 1, w, 1); +Error, REDUCE_COEFFS_GF2VEC: must be a GF2 vector (not the value 'fail'\ +) +gap> REDUCE_COEFFS_GF2VEC(v, fail, w, 1); +Error, REDUCE_COEFFS_GF2VEC: must be a non-negative small integer (not \ +the value 'fail') +gap> REDUCE_COEFFS_GF2VEC(v, 1, fail, 1); +Error, REDUCE_COEFFS_GF2VEC: must be a GF2 vector (not the value 'fail'\ +) +gap> REDUCE_COEFFS_GF2VEC(v, 1, w, fail); +Error, REDUCE_COEFFS_GF2VEC: must be a non-negative small integer (not \ +the value 'fail') + +# +# QUOTREM_COEFFS_GF2VEC +# +gap> QUOTREM_COEFFS_GF2VEC(empty, 0, w, 1); +[ , ] + +# bad arguments +gap> QUOTREM_COEFFS_GF2VEC(fail, 0, w, 1); +Error, QUOTREM_COEFFS_GF2VEC: must be a GF2 vector (not the value 'fail\ +') +gap> QUOTREM_COEFFS_GF2VEC(empty, fail, w, 1); +Error, QUOTREM_COEFFS_GF2VEC: must be a non-negative small integer (not\ + the value 'fail') +gap> QUOTREM_COEFFS_GF2VEC(empty, 0, fail, 1); +Error, QUOTREM_COEFFS_GF2VEC: must be a GF2 vector (not the value 'fail\ +') +gap> QUOTREM_COEFFS_GF2VEC(empty, 0, w, fail); +Error, QUOTREM_COEFFS_GF2VEC: must be a non-negative small integer (not\ + the value 'fail') + +# +# SEMIECHELON_LIST_GF2VECS +# +gap> s := SEMIECHELON_LIST_GF2VECS([one]);; s.heads = [1] and s.vectors = [one]; +true + +# bad arguments +gap> SEMIECHELON_LIST_GF2VECS(fail); +Error, SEMIECHELON_LIST_GF2VECS: must be a plain list (not the value 'fa\ +il') + +# +# SEMIECHELON_LIST_GF2VECS_TRANSFORMATIONS +# +gap> s := SEMIECHELON_LIST_GF2VECS_TRANSFORMATIONS([one]);; +gap> s.heads; +[ 1 ] +gap> s.vectors = [one]; +true +gap> s.coeffs = [one]; +true + +# bad arguments +gap> SEMIECHELON_LIST_GF2VECS_TRANSFORMATIONS(fail); +Error, SEMIECHELON_LIST_GF2VECS_TRANSFORMATIONS: must be a plain list (n\ +ot the value 'fail') + +# +# TRIANGULIZE_LIST_GF2VECS +# +gap> m := [one];; TRIANGULIZE_LIST_GF2VECS(m);; m = [one]; +true + +# bad arguments +gap> TRIANGULIZE_LIST_GF2VECS(fail); +Error, TRIANGULIZE_LIST_GF2VECS: must be a plain list (not the value 'fa\ +il') + +# +# DETERMINANT_LIST_GF2VECS +# +gap> DETERMINANT_LIST_GF2VECS([one]); +Z(2)^0 + +# bad arguments +gap> DETERMINANT_LIST_GF2VECS(fail); +Error, DETERMINANT_LIST_GF2VECS: must be a plain list (not the value 'fa\ +il') + +# +# RANK_LIST_GF2VECS +# +gap> RANK_LIST_GF2VECS([one]); +1 + +# bad arguments +gap> RANK_LIST_GF2VECS(fail); +Error, RANK_LIST_GF2VECS: must be a plain list (not the value 'fail') + +# +# KRONECKERPRODUCT_GF2MAT_GF2MAT +# +gap> KRONECKERPRODUCT_GF2MAT_GF2MAT(Mx02(2), M2([[o]])) = Mx02(2); +true + +# bad arguments +gap> KRONECKERPRODUCT_GF2MAT_GF2MAT(fail, M2([[o]])); +Error, KRONECKERPRODUCT_GF2MAT_GF2MAT: must be a GF2 matrix (not the va\ +lue 'fail') +gap> KRONECKERPRODUCT_GF2MAT_GF2MAT(Mx02(2), fail); +Error, KRONECKERPRODUCT_GF2MAT_GF2MAT: must be a GF2 matrix (not the va\ +lue 'fail') + +# +# COPY_SECTION_GF2VECS +# +gap> src := V2([o, o]);; dst := V2([z, z, z]);; COPY_SECTION_GF2VECS(src, dst, 1, 2, 2);; dst = V2([z, o, o]); +true + +# bad arguments +gap> COPY_SECTION_GF2VECS(fail, dst, 1, 2, 2); +Error, COPY_SECTION_GF2VECS: must be a GF2 vector (not the value 'fail') +gap> COPY_SECTION_GF2VECS(src, fail, 1, 2, 2); +Error, COPY_SECTION_GF2VECS: must be a GF2 vector (not the value 'fail'\ +) +gap> COPY_SECTION_GF2VECS(src, dst, fail, 2, 2); +Error, COPY_SECTION_GF2VECS: must be a positive small integer (not the \ +value 'fail') +gap> COPY_SECTION_GF2VECS(src, dst, 1, fail, 2); +Error, COPY_SECTION_GF2VECS: must be a positive small integer (not the va\ +lue 'fail') +gap> COPY_SECTION_GF2VECS(src, dst, 1, 2, fail); +Error, COPY_SECTION_GF2VECS: must be a small integer (not the value \ +'fail') + +# +# MAT_ELM_GF2MAT +# +gap> MAT_ELM_GF2MAT(M2([[o]]), 1, 1); +Z(2)^0 + +# bad arguments +gap> MAT_ELM_GF2MAT(fail, 1, 1); +Error, MAT_ELM_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> MAT_ELM_GF2MAT(M2([[o]]), fail, 1); +Error, MAT_ELM_GF2MAT: must be a positive small integer (not the value '\ +fail') +gap> MAT_ELM_GF2MAT(M2([[o]]), 1, fail); +Error, MAT_ELM_GF2MAT: must be a positive small integer (not the value '\ +fail') + +# +# SET_MAT_ELM_GF2MAT +# +gap> m := M2([[z]]);; SET_MAT_ELM_GF2MAT(m, 1, 1, o);; m = M2([[o]]); +true + +# bad arguments +gap> SET_MAT_ELM_GF2MAT(fail, 1, 1, o); +Error, SET_MAT_ELM_GF2MAT: must be a GF2 matrix (not the value 'fail') +gap> SET_MAT_ELM_GF2MAT(m, fail, 1, o); +Error, SET_MAT_ELM_GF2MAT: must be a positive small integer (not the val\ +ue 'fail') +gap> SET_MAT_ELM_GF2MAT(m, 1, fail, o); +Error, SET_MAT_ELM_GF2MAT: must be a positive small integer (not the val\ +ue 'fail') +gap> SET_MAT_ELM_GF2MAT(m, 1, 1, fail); +Error, SET_MAT_ELM_GF2MAT: assigned element must be a GF(2) element (not the v\ +alue 'fail') # gap> STOP_TEST("kernel/vecgf2.tst"); From fb67a5c24f91ca31d1bae6cee2812de93c40cb17 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 22 May 2026 09:49:46 +0200 Subject: [PATCH 10/50] Document SemiSimpleType field restriction (#6408) Resolves #2570 Co-authored-by: Codex --- lib/alglie.gd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/alglie.gd b/lib/alglie.gd index 31cc718ee0..7200f28451 100644 --- a/lib/alglie.gd +++ b/lib/alglie.gd @@ -514,6 +514,11 @@ DeclareAttribute( "LieSolvableRadical", IsAlgebra and IsLieAlgebra ); ## Lie algebras. ## Then returns the type of L, i.e., ## a string containing the types of the simple summands of L. +## The field of L must not have characteristic 2 or 3, and the +## Killing form of L must be nondegenerate. +## If L has characteristic 0, the structure constants of L +## must be rational numbers; Lie algebras over arbitrary characteristic +## 0 fields are not supported. ## L:= SimpleLieAlgebra( "E", 8, Rationals );; ## gap> b:= BasisVectors( Basis( L ) );; From 36f7f08a97a81feb16b799a7e2fe6c750591d49a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 22 May 2026 09:51:03 +0200 Subject: [PATCH 11/50] Clarify IsomorphismPcGroup docs (#6405) If input group is infinite or not solvable, fail is returned. --- lib/grp.gd | 8 ++++---- lib/grpfp.gi | 2 +- lib/pcgs.gd | 2 +- lib/pcgsspec.gi | 3 +++ tst/testinstall/grppc.tst | 25 +++++++++++++++++++++++++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/grp.gd b/lib/grp.gd index f9127d72c0..2a83f80eba 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -4250,8 +4250,8 @@ DeclareGlobalFunction( "AllSmallNonabelianSimpleGroups" ); ## returns an isomorphism from G onto an isomorphic pc group. ## The series chosen for this pc representation depends on ## the method chosen. -## G must be a polycyclic group of any kind, for example a solvable -## permutation group. +## G must be a finite polycyclic group of any kind, for example a solvable +## permutation group. If G is finite but not solvable, fail is returned. ## G := Group( (1,2,3), (3,4,1) );; ## gap> iso := IsomorphismPcGroup( G ); @@ -4278,8 +4278,8 @@ DeclareAttribute( "IsomorphismPcGroup", IsGroup ); ## returns an isomorphism from G onto an isomorphic pc group ## whose family pcgs is a special pcgs. ## (This can be beneficial to the runtime of calculations.) -## G may be a polycyclic group of any kind, for example a solvable -## permutation group. +## G must be a finite polycyclic group of any kind, for example a solvable +## permutation group. If G is finite but not solvable, fail is returned. ## ## ## <#/GAPDoc> diff --git a/lib/grpfp.gi b/lib/grpfp.gi index 0546a1f18a..3eaee5e44e 100644 --- a/lib/grpfp.gi +++ b/lib/grpfp.gi @@ -4332,7 +4332,7 @@ local s, a, hom; fi; hom:=EpimorphismSolvableQuotient(G,s); if Size(Image(hom))<>s then - Error("group is not solvable"); + return fail; else SetIsInjective(hom, true); fi; diff --git a/lib/pcgs.gd b/lib/pcgs.gd index cf2c0a8338..e1cf7172d8 100644 --- a/lib/pcgs.gd +++ b/lib/pcgs.gd @@ -782,7 +782,7 @@ DeclareAttribute( "RefinedPcGroup", IsPcGroup ); ## ## ## isomorphic -## returns an isomorphism from G onto an isomorphic pc group +## returns an isomorphism from a pc group G onto an isomorphic pc group ## whose family pcgs is a prime order pcgs. ## ## diff --git a/lib/pcgsspec.gi b/lib/pcgsspec.gi index e8ff00d776..01cc3fdc62 100644 --- a/lib/pcgsspec.gi +++ b/lib/pcgsspec.gi @@ -752,6 +752,9 @@ InstallMethod( IsomorphismSpecialPcGroup, "generic method for groups", function(G) local iso; iso:=IsomorphismPcGroup(G); + if iso = fail then + return fail; + fi; return iso*IsomorphismSpecialPcGroup(Range(iso)); end); diff --git a/tst/testinstall/grppc.tst b/tst/testinstall/grppc.tst index 873257c589..b2501dfc65 100644 --- a/tst/testinstall/grppc.tst +++ b/tst/testinstall/grppc.tst @@ -1,17 +1,25 @@ #@local F,G,S,c,cl,f,g,g1,g10,g3,gens,h,hh,i,m,n,pcgs,r,rws,sys,u,v,x,y,iso gap> START_TEST("grppc.tst"); + +# gap> Display(TrivialGroup(IsPcGroup)); trivial pc-group + +# gap> Display(CyclicGroup(IsPcGroup, 10)); pc-group with 2 pc-generators and relations: g1^2 = g2 g2^5 = id all generators commute, the groups is abelian + +# gap> Display(SymmetricGroup(IsPcGroup, 3)); pc-group with 2 pc-generators and relations: g1^2 = id g2^3 = id g2^g1 = g2^2 + +# gap> h:=Group((1,2,3,4),(1,2));; gap> m:=IsomorphismPcGroup(h);; gap> hh:=Image(m,h);; @@ -30,6 +38,8 @@ all other pairs of generators commute gap> pcgs:=Pcgs(hh);; gap> ForAll(pcgs,i->PreImagesRepresentative(m,i) in h); true + +# gap> g:=WreathProduct(Group((1,2,3),(1,2)),Group((1,2,3,4,5,6,7)));; gap> i:=IsomorphismPcGroup(g);; gap> g:=Range(i);; @@ -183,6 +193,21 @@ true gap> IsIdenticalObj( Range( iso ), ImagesSource( iso ) ); true +# +gap> G:=AlternatingGroup(5);; +gap> IsomorphismPcGroup(G); +fail +gap> IsomorphismSpecialPcGroup(G); +fail +gap> G:=Range(IsomorphismFpGroup(G));; +gap> IsomorphismPcGroup(G); +fail +gap> IsomorphismSpecialPcGroup(G); +fail +gap> IsomorphismPcGroup(FreeGroup(1)); +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 3rd choice method found for `IsomorphismPcGroup' on 1 arguments + # gap> G:= AbelianGroup( IsPcGroup, [ 3, 3, 3 ] );; gap> S:= AbelianGroup( IsPcGroup, [ 3, 3 ] );; From 7d9c9f044cdc1b54b19e1f3e6cd527d0fed7fa5a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 22 May 2026 09:54:23 +0200 Subject: [PATCH 12/50] Reformat and refactor StructureDescription code (#6403) Mostly avoid putting to many things on one line, for better readability and more accurate code coverage tracking. Also remove obsolete restrictions for perfect group orders 86016, 368640, 737280 --- lib/grpnames.gi | 229 ++++++++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 104 deletions(-) diff --git a/lib/grpnames.gi b/lib/grpnames.gi index 11dcafd25e..695923570d 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -893,9 +893,11 @@ InstallMethod( DecompositionTypesOfGroup, # abelian special case if IsAbelian(G) then AG := AbelianInvariants(G); - if Length(AG) = 1 then DTypes := Set([AG[1]]); else + if Length(AG) = 1 then + DTypes := Set([AG[1]]); + else T := ["x"]; - for a in AG do Add(T,a); od; + Append(T, AG); DTypes := Set([T]); fi; return DTypes; @@ -942,7 +944,9 @@ InstallMethod( DecompositionTypesOfGroup, od; # default: a non-split extension - if Length(DTypes) = 0 then DTypes := Set([["non-split",Size(G)]]); fi; + if Length(DTypes) = 0 then + DTypes := Set([["non-split",Size(G)]]); + fi; return DTypes; end ); @@ -999,9 +1003,8 @@ function(G) gens := DoComputeDihedralGenerators(G); if gens = fail then return false; - else - SetDihedralGenerators(G, gens); fi; + SetDihedralGenerators(G, gens); return true; end); @@ -1198,27 +1201,31 @@ InstallMethod( IsAlternatingGroup, function ( G ) - local n, ids, info; + local info; if not IsFinite(G) then TryNextMethod(); fi; - if IsNaturalAlternatingGroup(G) then return true;fi; - if Size(G) < 60 then + if IsNaturalAlternatingGroup(G) then + return true; + elif Size(G) < 60 then if Size(G) = 1 then - SetAlternatingDegree(G,0); return true; + SetAlternatingDegree(G,0); + return true; elif Size(G) = 3 then - SetAlternatingDegree(G,3); return true; + SetAlternatingDegree(G,3); + return true; elif Size(G) = 12 and Size(DerivedSubgroup(G)) = 4 then - SetAlternatingDegree(G,4); return true; - else return false; fi; + SetAlternatingDegree(G,4); + return true; + fi; + elif IsSimpleGroup(G) then + info := IsomorphismTypeInfoFiniteSimpleGroup(G); + if info.series = "A" then + SetAlternatingDegree(G,info.parameter); + return true; + fi; fi; - - if not IsSimpleGroup(G) then return false; fi; - - info := IsomorphismTypeInfoFiniteSimpleGroup(G); - if info.series = "A" - then SetAlternatingDegree(G,info.parameter); return true; - else return false; fi; + return false; end ); ############################################################################# @@ -1272,7 +1279,9 @@ InstallMethod( IsSymmetricGroup, if not IsFinite(G) then TryNextMethod(); fi; # special treatment of small cases - if Size(G)<=2 then SetSymmetricDegree(G,Size(G)); return true; + if Size(G)<=2 then + SetSymmetricDegree(G,Size(G)); + return true; elif Size(G)=6 and not IsAbelian(G) then SetSymmetricDegree(G,3); return true; @@ -1407,15 +1416,15 @@ InstallGlobalFunction( LinearGroupParameters, if not IsPosInt(N) then Error(" must be positive integer"); fi; - # Formeln: + # Formulas: # |GL(n, q)| = Product(q^n - q^k : k in [0..n-1]) # |SL(n, q)| = |GL(n, q)| / (q - 1) # |PSL(n, q)| = |SL(n, q)| / gcd(n, q - 1) - # mit q = p^e f"ur p prim, e >= 1, n >= 1. + # where q = p^e for p prime, e >= 1, n >= 1. - # Betrachte N = |GL(n,q)|. Dann gilt f"ur n >= 2 - # (1) nu_p(N) = e * Binomial(n,2) und - # (2) (q - 1)^n teilt N. + # Consider N = |GL(n,q)|. Then we have for n >= 2 + # (1) nu_p(N) = e * Binomial(n,2) and + # (2) (q - 1)^n divides N. npeGL := [ ]; npeSL := [ ]; npePSL := [ ]; if N = 1 then return rec( npeGL := npeGL, npeSL := npeSL, npePSL := npePSL ); @@ -1470,8 +1479,9 @@ InstallMethod( IsPSL, # more than one npe-triple should only # occur in the cases |G| in [60, 168, 20160] - if Length(npes) > 1 and not( Size(G) in [60, 168, 20160] ) - then Error("algebraic panic! probably npe does not work"); fi; + if Length(npes) > 1 and not( Size(G) in [60, 168, 20160] ) then + Error("algebraic panic! probably npe does not work"); + fi; # set the parameters npe := npes[1]; @@ -1483,12 +1493,10 @@ InstallMethod( IsPSL, # PSL(2, 2) if npes[1] = [2, 2, 1] then if IsAbelian(G) then return false; fi; - SetParametersOfGroupViewedAsPSL(G,npe); return true; # PSL(2, 3) elif npes[1] = [2, 3, 1] then if Size(DerivedSubgroup(G)) <> 4 then return false; fi; - SetParametersOfGroupViewedAsPSL(G,npe); return true; # PSL(3, 4) / PSL(4, 2) \cong A_8 elif npes = [ [ 4, 2, 1 ], [ 3, 2, 2 ] ] then @@ -1497,13 +1505,13 @@ InstallMethod( IsPSL, else npe := npes[2]; fi; - SetParametersOfGroupViewedAsPSL(G,npe); return true; # other cases - else - if not IsSimpleGroup(G) then return false; fi; - SetParametersOfGroupViewedAsPSL(G,npe); return true; + elif not IsSimpleGroup(G) then + return false; fi; + SetParametersOfGroupViewedAsPSL(G,npe); + return true; end ); ############################################################################# @@ -1563,12 +1571,10 @@ InstallMethod( IsSL, # SL(2, 2) if npes = [2, 2, 1] then if IsAbelian(G) then return false; fi; - SetParametersOfGroupViewedAsSL(G,npes); return true; # SL(2, 3) elif npes = [2, 3, 1] then if Size(DerivedSubgroup(G)) <> 8 then return false; fi; - SetParametersOfGroupViewedAsSL(G,npes); return true; # other cases, in which the contained PSL is simple else @@ -1583,8 +1589,9 @@ InstallMethod( IsSL, then return false; fi; if IsomorphismGroups(G,SL(npes[1],npes[2]^npes[3])) = fail then return false; fi; - SetParametersOfGroupViewedAsSL(G,npes); return true; fi; + SetParametersOfGroupViewedAsSL(G,npes); + return true; end ); ############################################################################# @@ -1649,7 +1656,6 @@ InstallMethod( IsGL, # GL(2, 2) if npes = [2, 2, 1] then if IsAbelian(G) then return false; fi; - SetParametersOfGroupViewedAsGL(G,npes); return true; # GL(2, 3) elif npes = [2, 3, 1] then @@ -1668,7 +1674,6 @@ InstallMethod( IsGL, # elements of order 4 in one case, and 2 in the other; this is also # how e.g. IdGroup distinguishes them if Number(G, g -> Order(g) = 2) < 13 then return false; fi; - SetParametersOfGroupViewedAsGL(G,npes); return true; # other cases, in which contained PSL is simple else @@ -1687,8 +1692,9 @@ InstallMethod( IsGL, then return false; fi; if IsomorphismGroups(G,GL(npes[1],npes[2]^npes[3])) = fail then return false; fi; - SetParametersOfGroupViewedAsGL(G,npes); return true; fi; + SetParametersOfGroupViewedAsGL(G,npes); + return true; end ); ############################################################################# @@ -1728,23 +1734,21 @@ InstallMethod( GLUnderlyingField, BindGlobal( "SD_insertsep", # function to join parts of name function ( strs, sep, brack ) - local short, s, i; - - short := ValueOption("short") = true; + local s, i; if strs = [] then return ""; fi; strs := Filtered(strs,str->str<>""); if Length(strs) > 1 then for i in [1..Length(strs)] do - if Intersection(strs[i],brack) <> "" - then strs[i] := Concatenation("(",strs[i],")"); fi; + if Intersection(strs[i],brack) <> "" then + strs[i] := Concatenation("(",strs[i],")"); + fi; od; fi; - s := strs[1]; - for i in [2..Length(strs)] do - s := Concatenation(s,sep,strs[i]); - od; - if short then RemoveCharacters(s," "); fi; + s := JoinStringsWithSeparator(strs,sep); + if ValueOption("short") = true then + RemoveCharacters(s," "); + fi; return s; end); @@ -1759,27 +1763,29 @@ BindGlobal( "SD_cyclic", BindGlobal( "SD_cycsaspowers", # function to write C2 x C2 x C2 as 2^3, etc. function ( name, cycsizes ) - local short, g, d, k, j, n; + local g, d, k, j, n; - short := ValueOption("short") = true; - if not short then return name; fi; + if ValueOption("short") <> true then + return name; + fi; RemoveCharacters(name," "); - cycsizes := Collected(cycsizes); - for n in cycsizes do - d := n[1]; k := n[2]; - g := SD_cyclic(d); - if d = 0 then - d := "Z"; - else - d := String(d); - fi; - if k > 1 then - for j in Reversed([2..k]) do - name := ReplacedString(name,SD_insertsep(List([1..j],i->g),"x",""), - Concatenation(d,"^",String(j))); - od; - fi; - od; + cycsizes := Collected(cycsizes); + for n in cycsizes do + d := n[1]; + k := n[2]; + g := SD_cyclic(d); + if d = 0 then + d := "Z"; + else + d := String(d); + fi; + if k > 1 then + for j in Reversed([2..k]) do + name := ReplacedString(name,SD_insertsep(List([1..j],i->g),"x",""), + Concatenation(d,"^",String(j))); + od; + fi; + od; RemoveCharacters(name,"C"); return name; end); @@ -1810,11 +1816,14 @@ BindGlobal( "StructureDescriptionForFiniteSimpleGroups", # for simple groups parameter; # parameters of G in series # special case abelian group - if IsAbelian(G) then return StructureDescriptionForAbelianGroups(G); fi; + if IsAbelian(G) then + return StructureDescriptionForAbelianGroups(G); + fi; # special case alternating group - if IsAlternatingGroup(G) - then return Concatenation("A",String(AlternatingDegree(G))); fi; + if IsAlternatingGroup(G) then + return Concatenation("A",String(AlternatingDegree(G))); + fi; # special case PSL if IsPSL(G) then @@ -1913,30 +1922,39 @@ BindGlobal( "StructureDescriptionForFiniteGroups", # for finite groups fi; # special case trivial group - if IsTrivial(G) then return "1"; fi; + if IsTrivial(G) then + return "1"; + fi; # special case abelian group - if IsAbelian(G) then return StructureDescriptionForAbelianGroups(G); fi; + if IsAbelian(G) then + return StructureDescriptionForAbelianGroups(G); + fi; # special case alternating group - if IsAlternatingGroup(G) - then return Concatenation("A",String(AlternatingDegree(G))); fi; + if IsAlternatingGroup(G) then + return Concatenation("A",String(AlternatingDegree(G))); + fi; # special case symmetric group - if IsSymmetricGroup(G) - then return Concatenation("S",String(SymmetricDegree(G))); fi; + if IsSymmetricGroup(G) then + return Concatenation("S",String(SymmetricDegree(G))); + fi; # special case dihedral group - if IsDihedralGroup(G) and Size(G) > 6 - then return Concatenation("D",String(Size(G))); fi; + if IsDihedralGroup(G) and Size(G) > 6 then + return Concatenation("D",String(Size(G))); + fi; # special case quaternion group - if IsQuaternionGroup(G) - then return Concatenation("Q",String(Size(G))); fi; + if IsQuaternionGroup(G) then + return Concatenation("Q",String(Size(G))); + fi; # special case quasidihedral group - if IsQuasiDihedralGroup(G) - then return Concatenation("QD",String(Size(G))); fi; + if IsQuasiDihedralGroup(G) then + return Concatenation("QD",String(Size(G))); + fi; # special case PSL if IsPSL(G) then @@ -1975,7 +1993,9 @@ BindGlobal( "StructureDescriptionForFiniteGroups", # for finite groups cycsizes := Filtered(cycsizes,n->n<>1); cycname := SD_cycsaspowers(SD_insertsep(List(cycsizes, SD_cyclic), " x ",":."), cycsizes); - else cycname := ""; fi; + else + cycname := ""; + fi; noncyclics := Difference(Gs,cyclics); noncycname := SD_insertsep(List(noncyclics,StructureDescription), " x ",":."); @@ -2049,32 +2069,33 @@ BindGlobal( "StructureDescriptionForFiniteGroups", # for finite groups # non-splitting, non-simple group if not IsTrivial(Centre(G)) then cname := SD_insertsep([StructureDescription(Centre(G)), - StructureDescription(G/Centre(G))]," . ","x:."); + StructureDescription(G/Centre(G))], + " . ","x:."); fi; if not IsPerfectGroup(G) then dname := SD_insertsep([StructureDescription(DerivedSubgroup(G)), StructureDescription(G/DerivedSubgroup(G))], " . ","x:."); fi; - if IsBound(cname) and IsBound(dname) and cname <> dname - then return Concatenation(cname," = ",dname); - elif IsBound(cname) then return cname; - elif IsBound(dname) then return dname; - elif not IsTrivial(FrattiniSubgroup(G)) - then return SD_insertsep([StructureDescription(FrattiniSubgroup(G)), - StructureDescription(G/FrattiniSubgroup(G))], - " . ","x:."); - elif IsPosInt(NrPerfectGroups(Size(G))) - and not Size(G) in [ 86016, 368640, 737280 ] - # this does not happen for Size(G)<10^6 - then - id := PerfectIdentification(G); - return Concatenation("PerfectGroup(",String(id[1]),",", - String(id[2]),")"); - else return Concatenation(""); + if IsBound(cname) and IsBound(dname) and cname <> dname then + return Concatenation(cname," = ",dname); + elif IsBound(cname) then + return cname; + elif IsBound(dname) then + return dname; + elif not IsTrivial(FrattiniSubgroup(G)) then + return SD_insertsep([StructureDescription(FrattiniSubgroup(G)), + StructureDescription(G/FrattiniSubgroup(G))], + " . ","x:."); + elif IsPosInt(NrPerfectGroups(Size(G))) then + id := PerfectIdentification(G); + return Concatenation("PerfectGroup(",String(id[1]),",", + String(id[2]),")"); + else + return Concatenation(""); fi; end ); From 1c6c7ffb8484f46b95d63e4ae1fb1ea1a030f0ef Mon Sep 17 00:00:00 2001 From: Michael Young Date: Sat, 23 May 2026 11:43:07 +0100 Subject: [PATCH 13/50] Add new logo to banner (B&W) (#6357) --- lib/init.g | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/init.g b/lib/init.g index 03601c810a..a4b64c169d 100644 --- a/lib/init.g +++ b/lib/init.g @@ -434,7 +434,7 @@ function( prefix, values, suffix ) end); BindGlobal( "ShowKernelInformation", function() - local sysdate, btop, vert, bbot, config, str, gap; + local sysdate, btop, bmid, bbot, config, str, gap; if GAPInfo.Date <> "today" then sysdate := " of "; @@ -447,19 +447,24 @@ BindGlobal( "ShowKernelInformation", function() fi; if GAPInfo.TermEncoding = "UTF-8" then - btop := "┌───────┐\c"; vert := "│"; bbot := "└───────┘\c"; + btop := " ● G"; + bmid := "● ● A"; + bbot := " ● P"; else - btop := "*********"; vert := "*"; bbot := btop; + btop := " o G"; + bmid := "o o A"; + bbot := " o P"; fi; if IsHPCGAP then gap := "HPC-GAP"; else gap := "GAP"; fi; - Print( " ",btop," ",gap," ", GAPInfo.BuildVersion, + Print( " ",btop," ",gap," ", GAPInfo.BuildVersion, sysdate, "\n", - " ",vert," GAP ",vert," https://www.gap-system.org\n", - " ",bbot," Architecture: ", GAPInfo.Architecture, "\n" ); + " ",bmid," https://www.gap-system.org\n", + " ",bbot," Architecture: ", GAPInfo.Architecture, "\n", + "\n" ); if IsHPCGAP then Print( " Maximum concurrent threads: ", GAPInfo.KernelInfo.NUM_CPUS, "\n"); From 707c955cb05a381f027b49f80c36a8c58de48501 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 23 May 2026 12:45:10 +0200 Subject: [PATCH 14/50] Switch banner to fully compact mode ... as discussed on PR #6357 --- lib/init.g | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/init.g b/lib/init.g index a4b64c169d..82c828d242 100644 --- a/lib/init.g +++ b/lib/init.g @@ -463,8 +463,7 @@ BindGlobal( "ShowKernelInformation", function() Print( " ",btop," ",gap," ", GAPInfo.BuildVersion, sysdate, "\n", " ",bmid," https://www.gap-system.org\n", - " ",bbot," Architecture: ", GAPInfo.Architecture, "\n", - "\n" ); + " ",bbot," Architecture: ", GAPInfo.Architecture, "\n" ); if IsHPCGAP then Print( " Maximum concurrent threads: ", GAPInfo.KernelInfo.NUM_CPUS, "\n"); From 8a57deac61f41684a2e553326f685a0aeb440174 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 26 May 2026 14:36:33 +0200 Subject: [PATCH 15/50] Turn LoadPackageDocumentation into a unary function (#6411) This undocumented function accepted more than one argument, but ignored any beyond the first. Apparently this was introduced in the GAP 4.5 days for compatibility reasons? But compatibility with what? No package known to me calls this. For reference in GAP 4.4 it had two arguments (but also was undocumented, and not called by any outside code). --- lib/package.gi | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/package.gi b/lib/package.gi index a4b404027e..b23272e685 100644 --- a/lib/package.gi +++ b/lib/package.gi @@ -1396,15 +1396,8 @@ InstallGlobalFunction( RereadPackage, function( arg ) ## #F LoadPackageDocumentation( ) ## -## In versions before 4.5, a second argument was required. -## For the sake of backwards compatibility, we do not forbid a second -## argument, but we ignore it. -## (In later versions, we may forbid the second argument.) -## -InstallGlobalFunction( LoadPackageDocumentation, function( arg ) - local info, short, pkgdoc, long, sixfile; - - info:= arg[1]; +InstallGlobalFunction( LoadPackageDocumentation, function( info ) + local short, pkgdoc, long, sixfile; # Load all books for the package. for pkgdoc in info.PackageDoc do From b49098af514632adc27536d534009552939d244f Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Tue, 26 May 2026 05:37:37 -0700 Subject: [PATCH 16/50] doc: describe OrbitStabilizer return value (closes #6324) (#6410) The OrbitStabilizer entry in the reference manual only documented the algorithm, not what the operation returns. Adds: - A short sentence explicitly stating the return value is an immutable record with `orbit` (the orbit as a list) and `stabilizer` (the point stabilizer subgroup of G). - A small example block using the same `g:=Group((1,3,2),(2,4,3));;` setup already used by the adjacent `Stabilizer` example, so the rendered output is identical to verified output already in this file. --- lib/oprt.gd | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/oprt.gd b/lib/oprt.gd index 20bae46045..e75a76cc81 100644 --- a/lib/oprt.gd +++ b/lib/oprt.gd @@ -1550,8 +1550,22 @@ OrbitsishOperation( "OrbitLengthsDomain", OrbitsishReq, false, NewAttribute ); ## ## computes the orbit and the stabilizer of pnt simultaneously in a ## single orbit-stabilizer algorithm. +## Returns an immutable record with components orbit (the orbit as +## a list) and stabilizer (the point stabilizer, a subgroup of +## G). ##

## The stabilizer will have G as its parent. +## g:=Group((1,3,2),(2,4,3));; +## gap> orbstab:=OrbitStabilizer(g,[1,2],OnSets); +## rec( +## orbit := [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 3, 4 ], +## [ 2, 4 ] ], stabilizer := Group([ (1,2)(3,4) ]) ) +## gap> orbstab.orbit; +## [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 3, 4 ], [ 2, 4 ] ] +## gap> orbstab.stabilizer; +## Group([ (1,2)(3,4) ]) +## ]]> ## ## ## <#/GAPDoc> From 2fd8c101d204a2c434dcdf3ba7ce36e9b23eea37 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 27 May 2026 08:07:19 +0200 Subject: [PATCH 17/50] Run --bare testinstall test in CI (#6354) --- .github/workflows/CI.yml | 2 +- dev/ci.sh | 4 ++++ tst/testinstall/maxsub.tst | 4 ++++ tst/testinstall/package.tst | 11 +++++++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ca0f05b997..0159bdcfb8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -47,7 +47,7 @@ jobs: test-suites: [ # base test: fast first test - "testinstall", + "testinstall-bare", "teststandard", diff --git a/dev/ci.sh b/dev/ci.sh index e45ca39268..170a346368 100755 --- a/dev/ci.sh +++ b/dev/ci.sh @@ -422,6 +422,10 @@ GAPInput ;; + testinstall-bare) + $GAP $(gap_cover_arg) --bare $SRCDIR/tst/testinstall.g + ;; + *) if [[ ! -f $SRCDIR/tst/${TEST_SUITE}.g ]] then diff --git a/tst/testinstall/maxsub.tst b/tst/testinstall/maxsub.tst index 036381d657..e04103b67b 100644 --- a/tst/testinstall/maxsub.tst +++ b/tst/testinstall/maxsub.tst @@ -9,12 +9,14 @@ gap> SortedList(List(msc, IndexInParent)); [ 2, 3, 4 ] # +#@if IsPackageMarkedForLoading( "primgrp", "" ) gap> G := GL(2,4);; gap> msc:=MaximalSubgroupClassReps(G);; gap> ForAll(msc, H -> Parent(H) = G); true gap> SortedList(List(msc, IndexInParent)); [ 3, 5, 6, 10 ] +#@fi # gap> G := GL(2,5);; @@ -25,10 +27,12 @@ gap> SortedList(List(msc, IndexInParent)); [ 2, 5, 6, 10 ] # +#@if IsPackageMarkedForLoading( "primgrp", "" ) gap> G := AlternatingGroup(5);; gap> msc := MaximalSubgroupClassReps(G);; gap> SortedList(List(msc, H -> Index(G, H))); [ 5, 6, 10 ] +#@fi # gap> STOP_TEST("maxsub.tst"); diff --git a/tst/testinstall/package.tst b/tst/testinstall/package.tst index 48df3fbf39..1ccd238478 100644 --- a/tst/testinstall/package.tst +++ b/tst/testinstall/package.tst @@ -435,9 +435,11 @@ false gap> IsPackageLoaded("mockpkg", ">=2.0"); false +# # instruct GAP to load the package, and record all its declarations # the help book of mockpkg might already have been loaded in other tests # -> we suppress a warning about this +#@if IsPackageMarkedForLoading( "gapdoc", "" ) gap> old_warning_level := InfoLevel( InfoWarning );; gap> SetInfoLevel( InfoWarning, 0 ); gap> PackageVariablesInfo("mockpkg", "0.1");; @@ -481,9 +483,14 @@ gap> IsDateFormatValid := function( datestring ) > end;; gap> IsDateFormatValid( GAPInfo.Date ); true +#@else +gap> LoadPackage("mockpkg", false); +oops, should not print here +true +#@fi # Test the Cite() command (output changed with GAPDoc 1.6.6 and again with 1.6.7) -#@if CompareVersionNumbers(InstalledPackageVersion("gapdoc"), "1.6.7") +#@if IsPackageMarkedForLoading( "gapdoc", "1.6.7" ) gap> Cite("mockpkg"); Please use one of the following samples to cite mockpkg version from this installation @@ -538,7 +545,7 @@ rg/}}}, } -#@else +#@elif IsPackageMarkedForLoading( "gapdoc", "" ) gap> Cite("mockpkg"); Please use one of the following samples to cite mockpkg version from this installation From 06bb20bf5b603a6ae5a0dbb4dc68dc779ab2bd97 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 27 May 2026 15:34:33 +0200 Subject: [PATCH 18/50] Prepare release notes for GAP 4.16.0 (#6414) --- CHANGES.md | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 6f4c6c84a9..48c602ec6b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,194 @@ # GAP - history of changes +## GAP 4.16.0 (May 2026) + +The following gives an overview of the changes compared to the previous +release. This list is not complete, many more internal or minor changes +were made, but we tried to only list those changes which we think might +affect some users directly. + +### New features + +- [#6384](https://github.com/gap-system/gap/pull/6384) Add `EnumeratorOfPartitionsSet` enumerator +- [#6322](https://github.com/gap-system/gap/pull/6322) Add `IsGenericMatrixRep` matrix object type +- [#6311](https://github.com/gap-system/gap/pull/6311) Add `PositionNonZeroInRow` for matrices and matrix objects +- [#6277](https://github.com/gap-system/gap/pull/6277) Add `DirectSumGModule` +- [#6268](https://github.com/gap-system/gap/pull/6268) Add `IsSquareMat` and `IsAntisymmetricMat` +- [#6262](https://github.com/gap-system/gap/pull/6262) Add `UserHomeShorten` as counterpart of `UserHomeExpand` +- [#6261](https://github.com/gap-system/gap/pull/6261) Add `WhereDepth` user preference to control depth of initial stack trace in break loops +- [#6259](https://github.com/gap-system/gap/pull/6259) Add `IsSymmetricMatrix` (and `IsSymmetricMat` as a synonym) +- [#6232](https://github.com/gap-system/gap/pull/6232) Add `RandomMatrix`, `RandomInvertibleMatrix`; and fix a problem with a new feature for matrix groups +- [#6213](https://github.com/gap-system/gap/pull/6213) Add `ConformalSymplecticGroup` +- [#5980](https://github.com/gap-system/gap/pull/5980) Add `AddMatrix`, `MultMatrix` (plus explicit left/right side variants) for in-place modification of matrices +- [#3357](https://github.com/gap-system/gap/pull/3357) Add `FoldLeft`, `FoldLeftX`; and `ForAllX`, `ForAnyX`, `FilteredX`, `NumberX`, `PerformX` to complement `ListX`, `SetX`, `SumX`, `ProductX` + +### Performance improvements + +- [#6398](https://github.com/gap-system/gap/pull/6398) Speed up conversion from integers to finite field elements +- [#6329](https://github.com/gap-system/gap/pull/6329) Speed up `CopySubMatrix`, `CopySubVector`, `ExtractSubMatrix`, `ExtractSubVector` for plist matrices/vectors +- [#6289](https://github.com/gap-system/gap/pull/6289) Make the meataxe faster by using `AddMatrix`, `AddVector`, `MultMatrix`, `MultVector` +- [#6276](https://github.com/gap-system/gap/pull/6276) Faster high-level Meataxe functions for irreducible modules (e.g. `MTX.IsomorphismModules`, `MTX.Indecomposition`, `MTX.BasisModuleEndomorphisms`, `MTX.BasisModuleHomomorphisms`) +- [#6267](https://github.com/gap-system/gap/pull/6267) Improve conjugation test for subgroups with different orders +- [#6265](https://github.com/gap-system/gap/pull/6265) Speed up `IsSubset` for cyclotomic domains (such as `Integers`, `PositiveIntegers`, `GaussianRationals` etc.) +- [#6114](https://github.com/gap-system/gap/pull/6114) Enhance support for very long transversals in a permutation group by forcing down huge index steps through an intermediate subgroup + +### Improved and extended functionality + +- [#6357](https://github.com/gap-system/gap/pull/6357) Update the GAP banner to reflect the new GAP logo +- [#6338](https://github.com/gap-system/gap/pull/6338) Improve `CosetLeadersMatFFE` documentation +- [#6334](https://github.com/gap-system/gap/pull/6334) Translating a range by adding an integer now produces another range (instead of a plain list) when possible +- [#6320](https://github.com/gap-system/gap/pull/6320) Add a manual section on how to write code for matrix objects +- [#6309](https://github.com/gap-system/gap/pull/6309) Allow `CopySubVector` on plain row vectors, fix `CopySubMatrix` +- [#6292](https://github.com/gap-system/gap/pull/6292) Document new `PackageInfo.g` fields `Dependencies.TestPackages` and `Dependencies.NeededSystemPackages`, and teach `ValidatePackageInfo` about them +- [#6280](https://github.com/gap-system/gap/pull/6280) Implement `MultVectorRight` for lists +- [#6257](https://github.com/gap-system/gap/pull/6257) Improve break-loop stack traces to be more consistent, provide more information and to indicate the current environment selected via `DownEnv`/`UpEnv` +- [#6211](https://github.com/gap-system/gap/pull/6211) Improve documentation for nice monomorphisms +- [#6183](https://github.com/gap-system/gap/pull/6183) Transfer more properties (such as `IsNaturalSL`, `InvariantQuadraticForm` etc.) when conjugating matrix groups + +### Removed or obsolete functionality + +- [#6067](https://github.com/gap-system/gap/pull/6067) Deprecate `InstallValue` for anything but plain objects (i.e., plain GAP lists, records or strings) and warn if it is done anyway + +### Changes related to handling of packages + +- [#6191](https://github.com/gap-system/gap/pull/6191) Remove unused "PC STACK" variables for from the left collectors (this breaks compatibility with polycyclic version 2.16 and older; use 2.17 or newer instead) + +### Changes in the documentation + +- [#6410](https://github.com/gap-system/gap/pull/6410) Document `OrbitStabilizer` return value +- [#6408](https://github.com/gap-system/gap/pull/6408) Document `SemiSimpleType` field restriction +- [#6405](https://github.com/gap-system/gap/pull/6405) Clarify `IsomorphismPcGroup` docs +- [#6370](https://github.com/gap-system/gap/pull/6370) Improve documentation of `OnTuplesSets`, `OnSetsDisjointSets`, `OnSetsTuples` +- [#6361](https://github.com/gap-system/gap/pull/6361) Simplify the list of `Matrix` argument variants in the manual +- [#6348](https://github.com/gap-system/gap/pull/6348) Clarify `CompatiblePairs` documentation +- [#6337](https://github.com/gap-system/gap/pull/6337) Clarify `IrreducibleModules` description to say 'at most' dim +- [#6260](https://github.com/gap-system/gap/pull/6260) Document `DirectProductElement` +- [#6220](https://github.com/gap-system/gap/pull/6220) Correct the documentation of `NewFamily` +- [#6198](https://github.com/gap-system/gap/pull/6198) Document setter for mutable attributes +- [#6174](https://github.com/gap-system/gap/pull/6174) Document objects with memory +- [#6171](https://github.com/gap-system/gap/pull/6171) Improve documentation of `InverseGeneralMapping` +- [#6169](https://github.com/gap-system/gap/pull/6169) Fix the definition of `PClassPGroup` +- [#6162](https://github.com/gap-system/gap/pull/6162) Only show authors in `Cite`, not maintainers + +### Fixed bugs that could lead to incorrect results + +- [#6382](https://github.com/gap-system/gap/pull/6382) Fix `Irr` for natural symmetric groups when the conjugacy classes are ordered differently in the group and its character table +- [#6358](https://github.com/gap-system/gap/pull/6358) Fix `HexSHA256` to always return 64 hex digits and not drop leading zero digits +- [#6341](https://github.com/gap-system/gap/pull/6341) Fix return value of `PartitionsGreatestLE(0, m)` and improve its documentation +- [#6340](https://github.com/gap-system/gap/pull/6340) Fix `MinimalGeneratingSet` for pc groups which sometimes returned incorrect (non-minimal) results +- [#6325](https://github.com/gap-system/gap/pull/6325) Fix garbled result produced by `CosetLeadersMatFFE` +- [#6303](https://github.com/gap-system/gap/pull/6303) Fix `CopySubVector` for GF(2) vectors to not produce invalid results for certain inputs +- [#6253](https://github.com/gap-system/gap/pull/6253) Fix `ShortestVectors` with `"positive"` argument returning a potentially incomplete list +- [#6245](https://github.com/gap-system/gap/pull/6245) Fix `PreImagesRepresentative` for group homomorphisms with `OnLines` action +- [#6206](https://github.com/gap-system/gap/pull/6206) Fix two bugs in `IsomorphismPermGroupForMatrixGroup` +- [#6203](https://github.com/gap-system/gap/pull/6203) Fix `FieldOfMatrixGroup` for certain classical matrix groups in dimension up to 2, and fix related problems with their invariant forms +- [#6170](https://github.com/gap-system/gap/pull/6170) Fix `IsomorphismPermGroup` for trivial f. p. (sub)group +- [#6160](https://github.com/gap-system/gap/pull/6160) Fix a bug in `RepresentativesPerfectSubgroups` that could lead to the omission of subgroups + +### Fixed bugs that could lead to crashes + +- [#6326](https://github.com/gap-system/gap/pull/6326) Fix crash in `CosetLeadersMatFFE` + +### Fixed bugs that could lead to unexpected errors + +- [#6196](https://github.com/gap-system/gap/pull/6196) Fix an inconsistency problem in `IsFinite` for matrix groups over cycl. fields. +- [#6159](https://github.com/gap-system/gap/pull/6159) Fix a potential error message about data types when computing extensions + +### Other fixed bugs + +- [#6355](https://github.com/gap-system/gap/pull/6355) Reset the options stack after an error also when the break loop is disabled (`-T` command line option) +- [#6218](https://github.com/gap-system/gap/pull/6218) Change `CoverageLineByLine` to produce output compatible with that produced by the `--coverage` command line option + +### Other changes + +- [#6230](https://github.com/gap-system/gap/pull/6230) Make `RestrictedMapping` of a group homomorphism use the same `Range` as the original morphism + +### Package distribution + +#### New packages redistributed with GAP + +- [**ClassicalMaximals**](https://gap-packages.github.io/ClassicalMaximals/) 1.1: Maximal subgroups of classical groups, by Maximilian Hauck, Max Horn, Tristan Pfersdorff, Christian Seeger, Sergio Siccha +- [**LocalNR**](https://gap-packages.github.io/LocalNR) 2.1.0: Package of local nearrings, by Iryna Raievska, Maryna Raievska, Yaroslav Sysak +- [**ModularGroup**](https://ag-weitze-schmithusen.github.io/ModularGroup) 2.0.2: Finite-index subgroups of (P)SL(2,Integers), by Sebastian Engelhardt, Luca Leon Junk, Hannah Wagmann, Gabriela Weitze-Schmithüsen +- [**nofoma**](https://gap-packages.github.io/nofoma) 1.0.1: Normal forms of matrices, by Meinolf Geck, Alia Bonnet +- [**Origami**](https://AG-Weitze-Schmithusen.github.io/Origami/) 2.0.3: Computing Veech groups of origamis, by Leo Emmerich, Sebastian Engelhardt, Simon Ertl, Luca Leon Junk, Pascal Kattler, Alexander Rogovskyy, Pascal Schumann, Andrea Thevis, Hannah Wagmann, Gabriela Weitze-Schmithüsen +- [**PackageMaker**](https://gap-packages.github.io/PackageMaker) 1.0.1: A GAP package for creating new GAP packages, by Max Horn + +#### Updated packages redistributed with GAP + +The GAP 4.16.0 distribution contains 172 packages, of which 68 have been +updated since GAP 4.15.1. The full list of updated packages is given below: + +- [**4ti2Interface**](https://homalg-project.github.io/pkg/4ti2Interface): 2024.11-01 -> 2025.12-01 +- [**Alnuth**](https://gap-packages.github.io/alnuth): 3.2.1 -> 4.0.0 +- [**ANUPQ**](https://gap-packages.github.io/anupq/): 3.3.2 -> 3.3.3 +- [**AtlasRep**](https://www.math.rwth-aachen.de/~Thomas.Breuer/atlasrep): 2.1.9 -> 2.1.11 +- [**AutoDoc**](https://gap-packages.github.io/AutoDoc): 2025.10.16 -> 2026.05.11 +- [**AutPGrp**](https://gap-packages.github.io/autpgrp/): 1.11.1 -> 1.12.0 +- [**Browse**](https://www.math.rwth-aachen.de/~Browse): 1.8.21 -> 1.8.22 +- [**CAP**](https://homalg-project.github.io/pkg/CAP): 2025.09-04 -> 2026.05-08 +- [**CaratInterface**](https://www.math.uni-bielefeld.de/~gaehler/gap/packages.php): 2.3.7 -> 2.3.9 +- [**CddInterface**](https://homalg-project.github.io/CddInterface): 2025.06.24 -> 2026.03.02 +- [**Cryst**](https://www.math.uni-bielefeld.de/~gaehler/gap/packages.php): 4.1.30 -> 4.1.31 +- [**CrystCat**](https://www.math.uni-bielefeld.de/~gaehler/gap/packages.php): 1.1.10 -> 1.1.11 +- [**curlInterface**](https://gap-packages.github.io/curlInterface/): 2.4.2 -> 2.4.3 +- [**cvec**](https://gap-packages.github.io/cvec): 2.8.4 -> 2.8.5 +- [**datastructures**](https://gap-packages.github.io/datastructures): 0.4.0 -> 0.4.1 +- [**Digraphs**](https://digraphs.github.io/Digraphs): 1.13.1 -> 1.14.0 +- [**ExamplesForHomalg**](https://homalg-project.github.io/pkg/ExamplesForHomalg): 2023.10-01 -> 2025.12-01 +- [**ferret**](https://gap-packages.github.io/ferret/): 1.0.15 -> 1.0.16 +- [**FORMAT**](https://gap-packages.github.io/format/): 1.4.4 -> 1.4.5 +- [**Forms**](https://gap-packages.github.io/forms): 1.2.13 -> 1.3.0 +- [**FPLSA**](https://gap-packages.github.io/FPLSA): 1.2.7 -> 1.2.8 +- [**GAPDoc**](https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc): 1.6.7 -> 1.6.10 +- [**Gauss**](https://homalg-project.github.io/pkg/Gauss): 2024.11-01 -> 2025.12-01 +- [**GaussForHomalg**](https://homalg-project.github.io/pkg/GaussForHomalg): 2024.08-01 -> 2026.04-01 +- [**GeneralizedMorphismsForCAP**](https://homalg-project.github.io/pkg/GeneralizedMorphismsForCAP): 2025.08-01 -> 2025.12-01 +- [**GradedModules**](https://homalg-project.github.io/pkg/GradedModules): 2024.12-01 -> 2026.04-01 +- [**GradedRingForHomalg**](https://homalg-project.github.io/pkg/GradedRingForHomalg): 2024.07-01 -> 2026.04-01 +- [**groupoids**](https://gap-packages.github.io/groupoids/): 1.79 -> 1.81 +- [**GUAVA**](https://gap-packages.github.io/guava): 3.20 -> 3.21 +- [**HAP**](https://gap-packages.github.io/hap): 1.70 -> 1.75 +- [**HAPcryst**](https://gap-packages.github.io/hapcryst/): 0.1.15 -> 0.2.0 +- [**HeLP**](https://gap-packages.github.io/HeLP): 4.0 -> 4.1 +- [**homalg**](https://homalg-project.github.io/pkg/homalg): 2024.01-01 -> 2025.12-01 +- [**HomalgToCAS**](https://homalg-project.github.io/pkg/HomalgToCAS): 2025.08-01 -> 2026.04-01 +- [**IBNP**](https://gap-packages.github.io/ibnp/): 0.17 -> 0.18 +- [**IO_ForHomalg**](https://homalg-project.github.io/pkg/IO_ForHomalg): 2023.02-04 -> 2025.12-01 +- [**json**](https://gap-packages.github.io/json/): 2.2.3 -> 2.4.0 +- [**LinearAlgebraForCAP**](https://homalg-project.github.io/pkg/LinearAlgebraForCAP): 2025.09-01 -> 2026.05-04 +- [**LocalizeRingForHomalg**](https://homalg-project.github.io/pkg/LocalizeRingForHomalg): 2023.10-01 -> 2026.04-01 +- [**lpres**](https://gap-packages.github.io/lpres): 1.1.1 -> 1.1.2 +- [**matgrp**](https://www.math.colostate.edu/~hulpke/matgrp): 0.72 -> 0.73 +- [**MatricesForHomalg**](https://homalg-project.github.io/pkg/MatricesForHomalg): 2025.09-01 -> 2026.04-01 +- [**ModIsom**](https://gap-packages.github.io/modisom/): 3.0.0 -> 3.1.0 +- [**ModulePresentationsForCAP**](https://homalg-project.github.io/pkg/ModulePresentationsForCAP): 2025.09-01 -> 2026.04-01 +- [**Modules**](https://homalg-project.github.io/pkg/Modules): 2024.12-01 -> 2026.04-01 +- [**MonoidalCategories**](https://homalg-project.github.io/pkg/MonoidalCategories): 2025.08-02 -> 2026.05-02 +- [**NConvex**](https://homalg-project.github.io/pkg/NConvex): 2024.12-01 -> 2025.12-02 +- [**NormalizInterface**](https://gap-packages.github.io/NormalizInterface): 1.4.1 -> 1.5.1 +- [**orb**](https://gap-packages.github.io/orb): 5.0.1 -> 5.1.0 +- [**Polycyclic**](https://gap-packages.github.io/polycyclic/): 2.17 -> 2.18 +- [**polymaking**](https://gap-packages.github.io/polymaking/): 0.8.7 -> 0.8.9 +- [**PrimGrp**](https://gap-packages.github.io/primgrp/): 4.0.1 -> 4.0.2 +- [**qpa**](https://gap-packages.github.io/qpa): 1.35 -> 1.37 +- [**RCWA**](https://gap-packages.github.io/rcwa/): 4.8.0 -> 4.9.0 +- [**recog**](https://gap-packages.github.io/recog): 1.4.4 -> 1.5.1 +- [**RingsForHomalg**](https://homalg-project.github.io/pkg/RingsForHomalg): 2024.11-02 -> 2025.12-01 +- [**SCO**](https://homalg-project.github.io/pkg/SCO): 2023.08-01 -> 2025.12-01 +- [**Semigroups**](https://semigroups.github.io/Semigroups): 5.5.4 -> 5.6.3 +- [**singular**](https://gap-packages.github.io/singular/): 2025.08.26 -> 2026.05.05 +- [**SmallClassNr**](https://stertooy.github.io/SmallClassNr): 1.4.2 -> 1.5.1 +- [**ToolsForHomalg**](https://homalg-project.github.io/pkg/ToolsForHomalg): 2025.05-01 -> 2026.04-01 +- [**TwistedConjugacy**](https://stertooy.github.io/TwistedConjugacy): 3.1.1 -> 3.3.2 +- [**typeset**](https://gap-packages.github.io/typeset/): 1.2.3 -> 1.2.4 +- [**utils**](https://gap-packages.github.io/utils): 0.92 -> 0.95 +- [**walrus**](https://gap-packages.github.io/walrus): 0.9991 -> 0.9992 +- [**Wedderga**](https://gap-packages.github.io/wedderga): 4.11.1 -> 4.11.3 +- [**XMod**](https://gap-packages.github.io/xmod/): 2.95 -> 2.98 +- [**ZeroMQInterface**](https://gap-packages.github.io/ZeroMQInterface/): 0.17 -> 0.18 + + ## GAP 4.15.1 (October 2025) The following gives an overview of the changes compared to the previous From f14734d8c50b54fcfb7ffcd2fbc63e6dfe1db52e Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 27 May 2026 15:44:06 +0200 Subject: [PATCH 19/50] Start work on GAP 4.17 --- CITATION | 14 +++++++------- configure.ac | 2 +- doc/versiondata | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CITATION b/CITATION index 906d89e6a5..bcd784c127 100644 --- a/CITATION +++ b/CITATION @@ -2,23 +2,23 @@ Please use one of the following samples to cite GAP version from this installati Text: -[GAP] GAP – Groups, Algorithms, and Programming, Version 4.16dev, +[GAP] GAP – Groups, Algorithms, and Programming, Version 4.17dev, The GAP Group (this year), https://www.gap-system.org. HTML:

[GAP] - GAP – Groups, Algorithms, and Programming, Version 4.16dev, + GAP – Groups, Algorithms, and Programming, Version 4.17dev, The GAP Group (this year), https://www.gap-system.org.

BibXML: - + <C>GAP</C> – <C>G</C>roups, <C>A</C>lgorithms, - and <C>P</C>rogramming, <C>V</C>ersion 4.16dev + and Programming, Version 4.17dev https://www.gap-system.org this year GAP @@ -28,8 +28,8 @@ BibXML: BibTeX: -@misc{ GAP4.16dev, - title = {{GAP} {\textendash} {G}roups, {A}lgorithms, and {P}rogramming, {V}ersion 4.16dev}, +@misc{ GAP4.17dev, + title = {{GAP} {\textendash} {G}roups, {A}lgorithms, and {P}rogramming, {V}ersion 4.17dev}, organization = {The GAP {G}roup}, year = {this year}, howpublished = {\href{https://www.gap-system.org}{\texttt{https://www.gap-system.org}}}, @@ -41,7 +41,7 @@ If you are not using BibTeX, here is the bibliography entry produced by BibTeX (in bibliography style `alpha'): \bibitem[GAP]{GAP4} -\emph{GAP -- Groups, Algorithms, and Programming}, Version 4.16dev, +\emph{GAP -- Groups, Algorithms, and Programming}, Version 4.17dev, The GAP~Group (this year), \verb+https://www.gap-system.org+. If you have (predominantly) used one or more particular GAP packages, diff --git a/configure.ac b/configure.ac index 1c313ffb8a..9320f18ce0 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ dnl Setup autoconf dnl AC_PREREQ([2.68]) -m4_define([gap_version], [4.16dev]) +m4_define([gap_version], [4.17dev]) m4_define([gap_releaseday], [today]) m4_define([gap_releaseyear], [this year]) diff --git a/doc/versiondata b/doc/versiondata index 98c2758afa..a2eec48b00 100644 --- a/doc/versiondata +++ b/doc/versiondata @@ -4,7 +4,7 @@ Instead edit either the template file `doc/versiondata.in`, or edit `Makefile.rules` (which has code for generating this file), or edit `configure.ac` (where the value being substituted come from) --> - + - + From 9f5c520b7e0e1da2fd9a9fec49b3080f256a875f Mon Sep 17 00:00:00 2001 From: Christopher Jefferson Date: Mon, 1 Jun 2026 19:40:53 +0800 Subject: [PATCH 20/50] emscripten: add Docker-based one-stop build and polish demo page (#6385) Rework the emscripten build into a reproducible flow inside a pinned container: etc/emscripten/build-in-docker.sh builds the image, runs the wasm build, and assembles a self-contained web-example/ that can be copied to any static host. Replaces the previous mix of shell, Ruby and Node helpers. The toolchain is pinned to emsdk 3.1.23 because both halves of the REPL are sensitive to the exact version: GASMAN's conservative GC, and xterm-pty's emscriptenHack() patching emscripten's TTY device so tcsetattr() reaches the line discipline. 3.1.23 is the version that works with the pinned xterm-pty 0.9.4; a newer emsdk leaves tcsetattr unhonoured and double- echoes typed input. See the Dockerfile for the full rationale. Build robustness fixes, independent of the toolchain version: - configure zlib with --static (newer wasm-ld rejects its shared .so test targets; GAP only needs libz.a); - remove the generated src/c_*.c and ffdata.* before the native build so reruns regenerate them instead of failing; - assemble-website.sh copies the data tree resiliently (some packages ship dangling .dSYM symlinks that aborted the copy and left lib/, grp/ uncopied, causing startup 404s), drops pkg/log/ test logs, ships gap.worker.js only if the build produced one, and asserts lib/init.g landed in the output. Also fix the outdated documentation links in the demo page and refresh startup_manifest.json. AI assistance: Claude Code (Opus 4.8) was used to make these changes. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 11 + etc/emscripten/Dockerfile | 50 + etc/emscripten/README.md | 127 +- etc/emscripten/assemble-website.sh | 64 + etc/emscripten/build-in-docker.sh | 80 ++ etc/emscripten/build.sh | 152 ++- etc/emscripten/build_startup_manifest.js | 71 - etc/emscripten/generate_gap_fs_json.py | 25 +- etc/emscripten/run-web-demo.sh | 13 - etc/emscripten/serve.py | 35 + etc/emscripten/server.rb | 15 - etc/emscripten/startup_manifest.json | 1521 ++++++++++++++++++++++ etc/emscripten/web-template/gap-fs.js | 51 +- etc/emscripten/web-template/index.html | 181 ++- src/gasman.c | 4 +- 15 files changed, 2191 insertions(+), 209 deletions(-) create mode 100644 etc/emscripten/Dockerfile create mode 100755 etc/emscripten/assemble-website.sh create mode 100755 etc/emscripten/build-in-docker.sh delete mode 100755 etc/emscripten/build_startup_manifest.js delete mode 100755 etc/emscripten/run-web-demo.sh create mode 100755 etc/emscripten/serve.py delete mode 100755 etc/emscripten/server.rb create mode 100644 etc/emscripten/startup_manifest.json diff --git a/.gitignore b/.gitignore index 5d67442b54..ca50cf4952 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,17 @@ /libgap*.dll* /libgap*.so* +# emscripten / wasm build outputs (etc/emscripten/build.sh and friends) +/native-build/ +/extern/emscripten/ +/web-example/ +/packages.tar.gz +/gap.html +/gap.js +/gap.wasm +/gap.worker.js +/gap-fs.json + /bin/gap*.sh /bin/*-*/ # Compiling the `xgap` package creates the file `xgap.sh` diff --git a/etc/emscripten/Dockerfile b/etc/emscripten/Dockerfile new file mode 100644 index 0000000000..9025dbaaa3 --- /dev/null +++ b/etc/emscripten/Dockerfile @@ -0,0 +1,50 @@ +# Build environment for compiling GAP to WebAssembly via Emscripten. +# +# Pinned to emsdk 3.1.23 for reproducibility. Both pieces of the in-browser +# REPL are sensitive to the exact toolchain version: +# +# - GASMAN, GAP's conservative garbage collector, scans the stack including +# pointers held in wasm registers, reached via emscripten_scan_registers() +# (see src/gasman.c). That path is now compiled correctly regardless of +# version, so the GC itself is no longer the constraint. +# +# - The terminal uses xterm-pty, whose emscriptenHack() monkey-patches +# emscripten's internal TTY device so GAP's tcsetattr() (turning off echo +# and canonical mode) reaches the line discipline. That patch is tied to +# emscripten's TTY internals: on 3.1.47 the ioctl no longer reaches +# xterm-pty, echo stays on, and every typed line is echoed twice. +# +# 3.1.23 is the version where the pinned xterm-pty (0.9.4) works. Bump both +# together and re-test the REPL -- including that typed input is not +# double-echoed -- before changing this. + +FROM emscripten/emsdk:3.1.23 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + autoconf \ + automake \ + libtool \ + make \ + python3 \ + ca-certificates \ + curl \ + bison \ + byacc \ + m4 \ + && rm -rf /var/lib/apt/lists/* + +# Allow running as a non-root host UID without breaking the emscripten cache. +RUN mkdir -p /emsdk/upstream/emscripten/cache \ + && chmod -R 0777 /emsdk/upstream/emscripten/cache + +# Cache the GAP package distribution tarball so container runs don't +# re-download it from GitHub each time. The URL pins to the "latest" +# release on the PackageDistro side, so this snapshot drifts as upstream +# tags new releases — rebuild the image (--no-cache) to refresh. +ARG GAP_PACKAGES_URL=https://github.com/gap-system/PackageDistro/releases/download/latest/packages.tar.gz +RUN curl --fail --location --silent --show-error \ + --output /opt/gap-packages.tar.gz \ + "$GAP_PACKAGES_URL" \ + && chmod 0644 /opt/gap-packages.tar.gz + +WORKDIR /gap diff --git a/etc/emscripten/README.md b/etc/emscripten/README.md index 5946302efe..083de668b6 100644 --- a/etc/emscripten/README.md +++ b/etc/emscripten/README.md @@ -1,26 +1,127 @@ -Code to allow building gap to WASM using Emscripten. +# GAP in the browser -Files: +Build GAP as a WebAssembly module and serve it as a self-contained website. +The terminal interface uses [xterm-pty](https://github.com/mame/xterm-pty), +so the resulting page behaves like a normal GAP REPL. -- `build.sh`: Run as `etc/emscripten/build.sh` from a fresh copy of GAP. +## Quick start -- `web-template`: Uses 'xterm-pty' to create a "nice" interface to the Wasm GAP. +From a fresh GAP checkout, with either Docker or Podman installed: -- `build_startup_manifest.js`: Run it in the web root directory to build `startup_manifest.json` that contains resources to preload. +```sh +etc/emscripten/build-in-docker.sh +cd web-example +../etc/emscripten/serve.py +``` + +Then open . The first build takes 10–30 minutes; the +docker image, the GAP package distribution, and the GMP/zlib builds are all +cached for subsequent runs. + +To pick up newer GAP packages from upstream, force a fresh image build: + +```sh +docker build --no-cache -t gap-emscripten-build:3.1.23 etc/emscripten/ +``` + +On Apple Silicon (and other non-amd64 hosts), the build runs `linux/amd64` +under emulation, since `emscripten/emsdk:3.1.23` is amd64-only on Docker +Hub. `build-in-docker.sh` pins the platform explicitly so the layer cache +holds across runs; set `BUILD_PLATFORM` to override. + +The output directory `web-example/` is fully self-contained — copy it to any +static host (see "Hosting" below for the headers it needs). + +## Building without Docker + +If you already have emsdk 3.1.23 sourced in your shell, you can run the +underlying build directly: + +```sh +etc/emscripten/build.sh +etc/emscripten/assemble-website.sh +``` + +emsdk 3.1.23 is the version we test against, paired with xterm-pty 0.9.4. +GAP relies on ASYNCIFY together with GASMAN's conservative GC, which scans +wasm registers via `emscripten_scan_registers()` (see `src/gasman.c`); and +the terminal relies on xterm-pty's `emscriptenHack()` patching emscripten's +TTY device so `tcsetattr()` reaches the line discipline. Both are sensitive +to the toolchain version (a newer emsdk leaves `tcsetattr` unhonoured, so +typed input is echoed twice), so re-test the REPL when changing emsdk. -See 'run-web-demo.sh' as an example on how to set up a working website. +## Hosting -Note that this demo uses xterm-pty, a library which provides a terminal interface -for emscripten-compiled programs. This uses a javascript feature called -"SharedArrayBuffer", which requires some headers are returned by the server: +The xterm-pty terminal uses `SharedArrayBuffer`, which browsers only allow +when the page is served with these two headers: ``` Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp ``` -For more details, see for [this article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer). +`serve.py` is a 20-line stdlib-only Python server that adds them. For +GitHub Pages and other static hosts that don't let you set headers, +`web-template/coi-serviceworker.js` is included as a workaround (it +re-fetches resources through a service worker that adds the headers). + +## Files + +| File | Role | +| ---- | ---- | +| `build-in-docker.sh` | One-stop entry point. Builds the image, runs `build.sh` inside, then `assemble-website.sh`. | +| `Dockerfile` | Pinned `emscripten/emsdk:3.1.23` with autotools, python3, bison/byacc/m4, and a baked-in copy of the GAP package distribution tarball at `/opt/gap-packages.tar.gz`. | +| `build.sh` | Configures and builds GMP, zlib, and GAP itself for wasm. | +| `assemble-website.sh` | Copies the build outputs and data directories (`pkg`, `lib`, `grp`, …) into `web-example/`. | +| `generate_gap_fs_json.py` | Reads file paths on stdin, writes `gap-fs.json` (the manifest of every file in the virtual FS). | +| `startup_manifest.json` | List of files to fetch eagerly at startup, captured from a real GAP run. Anything not in this list is fetched lazily on first read. See "Updating the startup manifest" below for how to refresh it. | +| `serve.py` | Local server that adds the COOP/COEP headers. | +| `web-template/` | Static UI: `index.html`, the worker scripts, the FS init shim, and the COOP/COEP service worker for hosts where you can't set headers. | + +## Updating the startup manifest + +`startup_manifest.json` lists files (relative to the GAP root) that the FS +init shim downloads up front instead of lazily. The current list was +captured from a real GAP run reaching its prompt, so it includes both +the core library bootstrap (`lib/init.g`, `lib/read*.g`, …) and any +default-loaded packages. Entries that no longer exist in the build are +silently ignored, so it is safe to leave stale entries in place; it is +also safe to leave the list empty (every file becomes lazy). + +The manifest is a startup-time optimisation, not a correctness mechanism: +a wrong list never breaks the build, it only makes startup slower (files +GAP needs but the manifest omits get fetched lazily, one round-trip each) +or wastes bandwidth (files in the manifest that GAP doesn't actually +read are downloaded anyway). So it's worth refreshing when something +changes the set of files read at startup — most importantly when the +default loaded packages change, but also after large library reshuffles. + +To regenerate it after such changes: + +1. Build the website (`build-in-docker.sh`) and serve it (`serve.py`). +2. **Empty the served manifest before capturing.** Replace + `web-example/startup_manifest.json` with `[]` (or delete it). + Otherwise the existing entries are eagerly pre-fetched at startup, + appear in `fetchedUrls`, and you'll just round-trip the old list. + Editing the served file is enough — no rebuild is needed. +3. Open the page and wait for the GAP prompt to appear. Every file that + GAP actually reads now goes through the lazy `XHR` path and gets + captured. +4. Open devtools and read the captured URLs from the page's JS console: + `window.fetchedUrls` is an array of every unique URL the worker + requested. Chrome/Firefox provide a `copy()` console helper: + `copy(JSON.stringify(fetchedUrls))` puts the JSON on your clipboard. +5. Strip non-GAP-FS entries (`gap.js`, `gap.wasm`, `gap-fs.json`, the + xterm CDN URLs) and write the result to + `etc/emscripten/startup_manifest.json` (so it's checked in and gets + picked up by the next `assemble-website.sh`). A `jq` filter that + keeps just GAP filesystem paths: + + ```sh + jq '[.[] | select(test("^(pkg|lib|grp|tst|doc|hpcgap|dev|benchmark)/"))]' \ + fetched-urls.json > etc/emscripten/startup_manifest.json + ``` -The file "coi-serviceworker.js" works around this problem on Github pages. This won't -work locally, so "server.rb" is a simple ruby script, which just starts a web-server -which returns the required headers. \ No newline at end of file +The bookkeeping lives in `web-template/gap-fs.js` (wraps `fetch` and +`XMLHttpRequest.open` to report URLs to the main thread) and +`web-template/index.html` (accumulates them onto `window.fetchedUrls`). diff --git a/etc/emscripten/assemble-website.sh b/etc/emscripten/assemble-website.sh new file mode 100755 index 0000000000..12e6f6a83b --- /dev/null +++ b/etc/emscripten/assemble-website.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# +# Assemble a self-contained website from a completed wasm build. +# Outputs ./web-example/ relative to the GAP source root. +# +# Run after etc/emscripten/build.sh (or have build-in-docker.sh call it). + +set -euo pipefail + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd) +OUT_DIR="$ROOT_DIR/web-example" + +cd "$ROOT_DIR" + +for f in gap.js gap.wasm gap-fs.json; do + if [[ ! -f $f ]]; then + echo "Error: missing build output '$f'. Run etc/emscripten/build.sh first." >&2 + exit 1 + fi +done + +# Always start from a clean output directory. Merging into a previous +# web-example/ confuses cp when a tree has changed shape between runs +# (e.g. pkg/X switching between a symlink and a real directory). +rm -rf "$OUT_DIR" +mkdir -p "$OUT_DIR" + +cp "$SCRIPT_DIR"/web-template/* "$OUT_DIR"/ +cp "$SCRIPT_DIR"/startup_manifest.json "$OUT_DIR"/ +cp gap.js gap.wasm gap-fs.json "$OUT_DIR"/ +# Emscripten only emits a separate gap.worker.js for pthread builds; this +# single-threaded ASYNCIFY build doesn't use one (newer emscripten inlines +# the worker regardless). Copy it only if it was produced. +if [[ -f gap.worker.js ]]; then + cp gap.worker.js "$OUT_DIR"/ +fi +cp LICENSE COPYRIGHT "$OUT_DIR"/ + +# Data directories. These are referenced by gap-fs.json and either eagerly +# loaded (if listed in startup_manifest.json) or lazily fetched on first +# read by Emscripten's createLazyFile. +# +# -L dereferences symlinks so the output tree is self-contained (a setup +# where pkg/X is a symlink into a separate checkout still works). Some +# packages ship dangling symlinks as build artefacts (e.g. pkg/vole's +# rust/target/*.dSYM); cp prints those and exits non-zero but still copies +# everything else, so we don't let that abort the run. The assertion below +# catches a genuinely incomplete copy. +for d in pkg lib grp tst doc hpcgap dev benchmark; do + cp -RL "$d" "$OUT_DIR"/ 2>/dev/null || true +done + +# pkg/log holds package test logs (.log/.err/.out) that are never read at +# runtime; keep them out of the shipped site. +rm -rf "$OUT_DIR/pkg/log" + +# The library bootstrap must be present, or GAP 404s during startup. +if [[ ! -f "$OUT_DIR/lib/init.g" ]]; then + echo "Error: lib/init.g missing from $OUT_DIR after copy." >&2 + exit 1 +fi + +echo "Assembled website at $OUT_DIR" diff --git a/etc/emscripten/build-in-docker.sh b/etc/emscripten/build-in-docker.sh new file mode 100755 index 0000000000..ac7a7aa604 --- /dev/null +++ b/etc/emscripten/build-in-docker.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# +# One-stop shop: build GAP for the web inside a pinned container. +# +# Usage (run from the GAP source tree): +# etc/emscripten/build-in-docker.sh +# +# Output: ./web-example/ with a self-contained website. Copy it anywhere +# and serve with COOP/COEP headers (etc/emscripten/serve.py is one option). + +set -euo pipefail + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd) + +RUNTIME="${CONTAINER_RUNTIME:-}" +if [[ -z "$RUNTIME" ]]; then + if command -v podman >/dev/null 2>&1; then + RUNTIME=podman + elif command -v docker >/dev/null 2>&1; then + RUNTIME=docker + else + echo "Error: neither podman nor docker found in PATH." >&2 + echo "Install one, or set CONTAINER_RUNTIME explicitly." >&2 + exit 1 + fi +fi + +IMAGE_TAG="gap-emscripten-build:3.1.23" + +# Pin the platform. emscripten/emsdk:3.1.23 is amd64-only on Docker Hub, so on +# Apple Silicon (or any non-amd64 host) the runtime would otherwise renegotiate +# the platform on every build -- that mismatch invalidates the FROM layer's +# cache and cascades through the whole image, defeating the layer cache even +# with --layers. Override with BUILD_PLATFORM if needed. +PLATFORM="${BUILD_PLATFORM:-linux/amd64}" + +echo ">> Using container runtime: $RUNTIME (platform: $PLATFORM)" +echo ">> Building image $IMAGE_TAG (cached after first run)" + +# --layers is the podman/buildah flag for "use the layer cache"; older +# podman versions default it to false. Docker has caching on by default +# and rejects the flag, so only pass it for podman. +declare -a BUILD_ARGS=(--platform "$PLATFORM") +if [[ "$RUNTIME" != "docker" ]]; then + BUILD_ARGS+=(--layers) +fi +"$RUNTIME" build "${BUILD_ARGS[@]}" -t "$IMAGE_TAG" -f "$SCRIPT_DIR/Dockerfile" "$SCRIPT_DIR" + +# Run as the host user where possible so build outputs are not root-owned. +declare -a USER_ARGS=() +if [[ "$RUNTIME" == "docker" ]]; then + USER_ARGS=(--user "$(id -u):$(id -g)" -e HOME=/tmp) +else + # Rootless podman maps host UID to container root by default. + USER_ARGS=(--userns=keep-id) +fi + +echo ">> Building GAP inside container" +"$RUNTIME" run --platform "$PLATFORM" --rm \ + -v "$ROOT_DIR:/gap" \ + -w /gap \ + "${USER_ARGS[@]}" \ + "$IMAGE_TAG" \ + bash etc/emscripten/build.sh + +echo ">> Assembling website" +bash "$SCRIPT_DIR/assemble-website.sh" + +cat </dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) -if ! command -v emmake &> /dev/null; then - echo Please install, and source, emscripten - echo This script was tested with version 3.1.23 - echo See https://emscripten.org/docs/getting_started/downloads.html for install instructions +if ! command -v emmake >/dev/null 2>&1; then + echo "Please install and source emscripten." >&2 + echo "This script is tested with emsdk 3.1.23." >&2 + echo "See https://emscripten.org/docs/getting_started/downloads.html" >&2 exit 1 -fi; +fi # Build the configure script if this is a fresh git checkout if [[ ! -f ./configure ]]; then ./autogen.sh fi -# First build a standard GAP install, for some files -# we will need during building +# First build a standard GAP install: we need ffgen and gap-nocomp on the +# host to generate sources that the wasm build cannot run itself. +# +# We copy those generated sources (build/c_*.c, build/ffdata.*) into src/ +# further down, so the wasm build picks them up as overrides. GAP's +# Makefile.rules, however, also treats src/c_oper1.c, src/ffdata.c etc. as +# overrides during THIS native build -- so leftovers from a previous run +# would stop the native build regenerating them in native-build/build/, and +# the copy below would then fail. Remove any leftovers so the native build +# regenerates them cleanly (keeps the script idempotent across re-runs). +rm -f src/c_oper1.c src/c_type1.c src/ffdata.c src/ffdata.h ( mkdir -p native-build cd native-build if [[ ! -f config.status ]]; then ../configure fi - make -j8 + make -j"$JOBS" ) AUX_BUILD=$PWD/extern/emscripten/build AUX_PREFIX=$PWD/extern/emscripten/install -mkdir -p "$AUX_BUILD" -mkdir -p "$AUX_PREFIX" +mkdir -p "$AUX_BUILD" "$AUX_PREFIX" +# A 32-bit build is required by GAP's small-integer representation, so we +# pin --build to i686-pc-linux-gnu. This may need revisiting if GAP ever +# moves to a 64-bit-friendly small-integer encoding. ( mkdir -p "$AUX_BUILD/gmp" - cd "$AUX_BUILD/gmp" && + cd "$AUX_BUILD/gmp" if [[ ! -f config.status ]]; then CC_FOR_BUILD=/usr/bin/gcc ABI=standard \ - emconfigure $BASEDIR/extern/gmp/configure \ - --build i686-pc-linux-gnu --host none \ - --disable-assembly --enable-cxx \ - --prefix=$AUX_PREFIX - fi && - emmake make -j8 && + emconfigure "$BASEDIR/extern/gmp/configure" \ + --build i686-pc-linux-gnu --host none \ + --disable-assembly --enable-cxx \ + --prefix="$AUX_PREFIX" + fi + emmake make -j"$JOBS" emmake make install ) ( mkdir -p "$AUX_BUILD/zlib" - cd "$AUX_BUILD/zlib" && + cd "$AUX_BUILD/zlib" if [[ ! -f Makefile ]]; then - emconfigure $BASEDIR/extern/zlib/configure --prefix=$AUX_PREFIX - fi; - emmake make -j8 && + # --static: skip the shared library. Newer emscripten's wasm-ld + # rejects linking zlib's .so test programs (examplesh) with + # "unknown file type: libz.so"; GAP only needs the static libz.a. + emconfigure "$BASEDIR/extern/zlib/configure" --static --prefix="$AUX_PREFIX" + fi + emmake make -j"$JOBS" emmake make install ) -# There are two problems with building GAP -# 1) GAP builds some executables (ffgen and gap-nocomp), which it wants to -# execute while building. We get these files from 'native-build'. -# 2) 'configure' gets confused by some of the LDFLAGS we need, so we have to pass -# them in to 'make' +# Two quirks of building GAP under emscripten: +# 1) GAP runs ffgen and gap-nocomp during the build. We copy the host-built +# versions in from native-build/ further down. +# 2) configure rejects some LDFLAGS we need at link time, so we pass them +# only at make-time. # -# These options are: -# -sASYNCIFY -- we don't care about ASYNC, but this forces the compiler to output -# all variables onto the stack, which is required for GASMAN -# Note we could use 'ALLOW_MEMORY_GROWTH', both we don't currently, we instead set -# a big memory window. -# -O2 : Some optimisation -# EXEEXT=.html -- this is actually a GAP makefile option, it lets us make the -# output 'gap.html', which makes emscripten output a html page we can load -# --pre-js lazy_fs.js : Prepend lazy_fs.js that is generated for lazy loading - -# Run configure if we don't have a makefile, or someone configured this -# GAP for standard building (emscripten builds will use 'emcc') -if [[ ! -f GNUmakefile ]] || ! grep '/emcc' GNUmakefile > /dev/null; then +# Link-time flags worth noting: +# -sASYNCIFY forces variables onto the stack (required by GASMAN). +# -O2 enables some optimisation. +# EXEEXT=.html a GAP makefile knob that produces gap.html, the html +# shim emscripten generates for loading the wasm module. + +if [[ ! -f GNUmakefile ]] || ! grep -q '/emcc' GNUmakefile; then + # Wipe any in-tree state from a prior native (or mismatched) build. + # Stale build/deps/*.d files reference build/ffdata.h, which under + # emcc would be regenerated by a non-executable JS shim; stale .o + # files have the wrong architecture. Configure regenerates build/. + rm -rf build ffgen emconfigure ./configure ABI=32 \ - --with-gmp=$AUX_PREFIX \ - --with-zlib=$AUX_PREFIX \ - LDFLAGS="-s ASYNCIFY=1 -O2" -fi; + --with-gmp="$AUX_PREFIX" \ + --with-zlib="$AUX_PREFIX" \ + LDFLAGS="-s ASYNCIFY=1 -O2" +fi -# Get full required packages -emmake make bootstrap-pkg-full +# Provide the GAP package distribution without re-downloading it on every +# build. Preference order: +# 1. An existing pkg/ directory. +# 2. packages.tar.gz already on the host (carried in the source mount). +# 3. The tarball baked into the docker image at /opt/gap-packages.tar.gz. +# 4. As a last resort, GAP's own bootstrap-pkg-full target downloads it. +# Skipping straight to tar avoids `bootstrap-pkg-full`, which calls +# curl -L -O unconditionally and overwrites packages.tar.gz on every run. +if [[ ! -d pkg ]]; then + if [[ ! -f packages.tar.gz && -f /opt/gap-packages.tar.gz ]]; then + cp /opt/gap-packages.tar.gz packages.tar.gz + fi + if [[ -f packages.tar.gz ]]; then + mkdir pkg + (cd pkg && tar xzf ../packages.tar.gz) + else + emmake make bootstrap-pkg-full + fi +fi -# Copy in files from native_build +# Copy host-built generated sources into place cp native-build/build/c_*.c native-build/build/ffdata.* src/ -# Dynamically find and append ALL required files to the JS array -# The flag -type f is safe because the only symbolic link is 'tst/mockpkg/Makefile.gappkg', -# which is safe to ignore -find pkg lib grp tst doc hpcgap dev benchmark -type f | python3 etc/emscripten/generate_gap_fs_json.py - -if [ $? -ne 0 ]; then - echo "Build aborted: generate_gap_fs_json.py failed." - exit 1 -fi +# Build the file list that will be served. -L follows symlinks so that +# users' local development setups (e.g. replacing pkg/foo with a symlink +# to a git checkout under git/foo) are picked up; -type f then drops any +# symlinks themselves. +find -L pkg lib grp tst doc hpcgap dev benchmark -type f ! -path 'pkg/log/*' \ + | python3 etc/emscripten/generate_gap_fs_json.py -# The EXEEXT is usually for windows, but here it lets us set GAP's extension, -# which lets us produce a html page to run GAP in. -emmake make -j8 LDFLAGS="-lidbfs.js -s ASYNCIFY=1 -sTOTAL_STACK=32mb -sASYNCIFY_STACK_SIZE=32000000 -sINITIAL_MEMORY=2048mb -O2" EXEEXT=".html" +emmake make -j"$JOBS" \ + LDFLAGS="-lidbfs.js -s ASYNCIFY=1 -sTOTAL_STACK=32mb -sASYNCIFY_STACK_SIZE=32000000 -sINITIAL_MEMORY=2048mb -O2" \ + EXEEXT=".html" diff --git a/etc/emscripten/build_startup_manifest.js b/etc/emscripten/build_startup_manifest.js deleted file mode 100755 index edb8594b10..0000000000 --- a/etc/emscripten/build_startup_manifest.js +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env node -"use strict"; - -const http = require('http'); -const fs = require('fs'); -const path = require('path'); - -const PORT = 9999; -const BASE_DIR = process.cwd(); -const LOG_FILE = path.join(BASE_DIR, 'startup_manifest.json'); - -const requestedFiles = new Set(); -fs.writeFileSync(LOG_FILE, '[\n]'); - -const server = http.createServer((req, res) => { - let urlPath = req.url.split('?')[0]; - if (urlPath === '/') { - urlPath = '/index.html'; - } - - let localDiskPath = urlPath; - try { - localDiskPath = decodeURIComponent(urlPath); - } catch (e) {} - - const filePath = path.join(BASE_DIR, localDiskPath); - - fs.readFile(filePath, (err, data) => { - if (err) { - console.error(`[404] Ignored missing file: ${localDiskPath}`); - res.writeHead(404); - res.end(`404: File not found`); - return; - } - - const ignored = ['/favicon.ico', '/index.html', '/startup_manifest.json', 'coi-serviceworker.js', 'gap-worker.js', 'gap-fs.js', 'gap.js', 'gap.wasm', 'gap-fs.json']; - if (!ignored.includes(localDiskPath)) { - let manifestPath = localDiskPath.startsWith('/') ? localDiskPath.substring(1) : localDiskPath; - - if (!requestedFiles.has(manifestPath)) { - requestedFiles.add(manifestPath); - - const manifest = Array.from(requestedFiles); - fs.writeFileSync(LOG_FILE, JSON.stringify(manifest, null, 4)); - - console.log(`[Loaded & Logged] ${manifestPath} (Total: ${requestedFiles.size})`); - } - } - - let contentType = 'application/octet-stream'; - if (urlPath.endsWith('.html')) contentType = 'text/html'; - else if (urlPath.endsWith('.js')) contentType = 'text/javascript'; - else if (urlPath.endsWith('.wasm')) contentType = 'application/wasm'; - else if (urlPath.endsWith('.css')) contentType = 'text/css'; - - res.writeHead(200, { - 'Content-Type': contentType, - 'Cross-Origin-Opener-Policy': 'same-origin', - 'Cross-Origin-Embedder-Policy': 'require-corp', - 'Access-Control-Allow-Origin': '*' - }); - - res.end(data); - }); -}); - -server.listen(PORT, '0.0.0.0', () => { - console.log(`\n Tracker running at http://localhost:${PORT}/`); - console.log(`Serving files from: ${BASE_DIR}`); - console.log(`Logging valid loaded files to: ${LOG_FILE}\n`); -}); diff --git a/etc/emscripten/generate_gap_fs_json.py b/etc/emscripten/generate_gap_fs_json.py index dbf5447bba..917f0a2a38 100755 --- a/etc/emscripten/generate_gap_fs_json.py +++ b/etc/emscripten/generate_gap_fs_json.py @@ -1,18 +1,11 @@ -import sys -import json -import os - -def main(): - paths = [line.strip() for line in sys.stdin if line.strip()] +#!/usr/bin/env python3 +"""Read a list of file paths from stdin (one per line) and write them as a +JSON array to gap-fs.json in the current directory.""" - try: - with open('gap-fs.json', 'w', encoding='utf-8') as f: - json.dump(paths, f, separators=(',', ':')) - - print(f"Successfully wrote {len(paths)} files to gap-fs.json", file=sys.stderr) - except Exception as e: - print(f"Failed to write gap-fs.json: {e}", file=sys.stderr) - sys.exit(1) +import json +import sys -if __name__ == "__main__": - main() +paths = [line.strip() for line in sys.stdin if line.strip()] +with open("gap-fs.json", "w", encoding="utf-8") as f: + json.dump(paths, f, separators=(",", ":")) +print(f"wrote {len(paths)} files to gap-fs.json", file=sys.stderr) diff --git a/etc/emscripten/run-web-demo.sh b/etc/emscripten/run-web-demo.sh deleted file mode 100755 index a82eb948a9..0000000000 --- a/etc/emscripten/run-web-demo.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -echo This script assumes you have already run 'build.sh' - -mkdir -p web-example -cp etc/emscripten/web-template/* web-example/ -cp gap.js gap.wasm gap.worker.js gap-fs.json web-example/ - -cp -r pkg lib grp tst doc hpcgap dev benchmark web-example/ -cd web-example -../etc/emscripten/server.rb diff --git a/etc/emscripten/serve.py b/etc/emscripten/serve.py new file mode 100755 index 0000000000..7d089f0c54 --- /dev/null +++ b/etc/emscripten/serve.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +"""Serve the current directory with the COOP/COEP headers required by +xterm-pty's SharedArrayBuffer usage. Run from the assembled web-example/ +(or any directory containing the gap.* artifacts). + + ./serve.py # listens on 8080 + ./serve.py 9000 # listens on 9000 +""" + +from __future__ import annotations + +import http.server +import socketserver +import sys + + +class CrossOriginIsolatedHandler(http.server.SimpleHTTPRequestHandler): + def end_headers(self): + self.send_header("Cross-Origin-Opener-Policy", "same-origin") + self.send_header("Cross-Origin-Embedder-Policy", "require-corp") + super().end_headers() + + +def main() -> None: + port = int(sys.argv[1]) if len(sys.argv) > 1 else 8080 + with socketserver.TCPServer(("", port), CrossOriginIsolatedHandler) as httpd: + print(f"Serving on http://localhost:{port}/ (Ctrl-C to stop)") + try: + httpd.serve_forever() + except KeyboardInterrupt: + print() + + +if __name__ == "__main__": + main() diff --git a/etc/emscripten/server.rb b/etc/emscripten/server.rb deleted file mode 100755 index 642c9ad167..0000000000 --- a/etc/emscripten/server.rb +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env ruby -# Taken from https://github.com/mame/xterm-pty/ - -require "webrick" - -class Server < WEBrick::HTTPServer - def service(req, res) - super - res["Cross-Origin-Opener-Policy"] = "same-origin" - res["Cross-Origin-Embedder-Policy"] = "require-corp" - end -end - -Server.new(Port: 8080, DocumentRoot: ".").start - diff --git a/etc/emscripten/startup_manifest.json b/etc/emscripten/startup_manifest.json new file mode 100644 index 0000000000..3ab701c269 --- /dev/null +++ b/etc/emscripten/startup_manifest.json @@ -0,0 +1,1521 @@ +[ + "lib/init.g", + "lib/kernel.g", + "lib/global.g", + "lib/system.g", + "lib/read1.g", + "lib/hpc/thread1.g", + "lib/filter.g", + "lib/oper.g", + "lib/oper1.g", + "lib/type.g", + "lib/type1.g", + "lib/methsel.g", + "lib/methsel2.g", + "lib/function.g", + "lib/cache.gd", + "lib/object.gd", + "lib/variable.g", + "lib/package.gd", + "lib/coll.gd", + "lib/list.gd", + "lib/wpobj.gd", + "lib/arith.gd", + "lib/ffe.gd", + "lib/domain.gd", + "lib/string.g", + "lib/cyclotom.g", + "lib/set.gd", + "lib/record.gd", + "lib/random.gd", + "lib/cache.gi", + "lib/coll.gi", + "lib/flag.g", + "lib/boolean.g", + "lib/ffe.g", + "lib/arith.gi", + "lib/list.g", + "lib/wpobj.g", + "lib/permutat.g", + "lib/trans.g", + "lib/pperm.g", + "lib/filter.gi", + "lib/object.gi", + "lib/listcoef.gd", + "lib/info.gd", + "lib/files.gd", + "lib/streams.gd", + "lib/record.gi", + "lib/matobj1.gd", + "lib/vecmat.gd", + "lib/vec8bit.gd", + "lib/mat8bit.gd", + "lib/global.gd", + "lib/info.gi", + "lib/global.gi", + "lib/options.gd", + "lib/options.gi", + "lib/attr.gd", + "lib/attr.gi", + "lib/string.gd", + "lib/userpref.g", + "lib/cmdledit.g", + "lib/cmdleditx.g", + "lib/objset.g", + "lib/float.gd", + "lib/macfloat.g", + "lib/hpc/tasks.g", + "lib/error.g", + "lib/session.g", + "lib/read2.g", + "lib/process.gd", + "lib/files.gi", + "lib/streams.gi", + "lib/process.gi", + "lib/read3.g", + "lib/type.gd", + "lib/tuples.gd", + "lib/rvecempt.gd", + "lib/extaset.gd", + "lib/extlset.gd", + "lib/extrset.gd", + "lib/extuset.gd", + "lib/dict.gd", + "lib/bitfields.gd", + "lib/mapping.gd", + "lib/mapphomo.gd", + "lib/relation.gd", + "lib/magma.gd", + "lib/mgmideal.gd", + "lib/mgmhom.gd", + "lib/mgmadj.gd", + "lib/mgmcong.gd", + "lib/semicong.gd", + "lib/semigrp.gd", + "lib/smgideal.gd", + "lib/monoid.gd", + "lib/grp.gd", + "lib/invsgp.gd", + "lib/addmagma.gd", + "lib/addcoset.gd", + "lib/semiring.gd", + "lib/ring.gd", + "lib/matrix.gd", + "lib/matint.gd", + "lib/matblock.gd", + "lib/ideal.gd", + "lib/module.gd", + "lib/basis.gd", + "lib/basismut.gd", + "lib/vspc.gd", + "lib/vspchom.gd", + "lib/zlattice.gd", + "lib/algebra.gd", + "lib/mgmring.gd", + "lib/algfp.gd", + "lib/alglie.gd", + "lib/algsc.gd", + "lib/alghom.gd", + "lib/liefam.gd", + "lib/algrep.gd", + "lib/lierep.gd", + "lib/integer.gd", + "lib/gaussian.gd", + "lib/numtheor.gd", + "lib/dlog.gd", + "lib/primality.gd", + "lib/contfrac.gd", + "lib/ringsc.gd", + "lib/ringhom.gd", + "lib/combinat.gd", + "lib/ratfun.gd", + "lib/fampred.g", + "lib/list.gi", + "lib/set.gi", + "lib/wpobj.gi", + "lib/random.gi", + "lib/field.gd", + "lib/zmodnz.gd", + "lib/zmodnze.gd", + "lib/cyclotom.gd", + "lib/fldabnum.gd", + "lib/padics.gd", + "lib/ringpoly.gd", + "lib/upoly.gd", + "lib/polyfinf.gd", + "lib/polyrat.gd", + "lib/polyconw.gd", + "lib/algfld.gd", + "lib/meataxe.gd", + "lib/unknown.gd", + "lib/word.gd", + "lib/wordass.gd", + "lib/matobj2.gd", + "lib/matobjplist.gd", + "lib/matobjnz.gd", + "lib/rws.gd", + "lib/rwspcclt.gd", + "lib/rwsgrp.gd", + "lib/rwspcgrp.gd", + "lib/groebner.gd", + "lib/pcgs.gd", + "lib/pcgsind.gd", + "lib/pcgspcg.gd", + "lib/pcgsmodu.gd", + "lib/pcgsperm.gd", + "lib/pcgsspec.gd", + "lib/grppc.gd", + "lib/grppcnrm.gd", + "lib/grptbl.gd", + "lib/grpperm.gd", + "lib/grpprmcs.gd", + "lib/stbcbckt.gd", + "lib/ghom.gd", + "lib/ghompcgs.gd", + "lib/gprd.gd", + "lib/ghomperm.gd", + "lib/gpprmsya.gd", + "lib/addgphom.gd", + "lib/grpnames.g", + "lib/grpnames.gd", + "lib/quotsys.gd", + "lib/pquot.gd", + "lib/oprt.gd", + "lib/partitio.gd", + "lib/stbc.gd", + "lib/clas.gd", + "lib/clashom.gd", + "lib/permdeco.gd", + "lib/csetgrp.gd", + "lib/factgrp.gd", + "lib/grpreps.gd", + "lib/grppcrep.gd", + "lib/onecohom.gd", + "lib/grppccom.gd", + "lib/twocohom.gd", + "lib/grppcext.gd", + "lib/grppcfp.gd", + "lib/randiso.gd", + "lib/schur.gd", + "lib/schursym.gd", + "lib/grplatt.gd", + "lib/oprtglat.gd", + "lib/grppclat.gd", + "lib/grppcaut.gd", + "lib/straight.gd", + "lib/memory.gd", + "lib/grpfp.gd", + "lib/grpfree.gd", + "lib/sgpres.gd", + "lib/tietze.gd", + "lib/ghomfp.gd", + "lib/dt.g", + "lib/integer.gi", + "lib/grpnice.gd", + "lib/morpheus.gd", + "lib/grpmat.gd", + "lib/fitfree.gd", + "lib/grpffmat.gd", + "lib/grpramat.gd", + "grp/basic.gd", + "grp/classic.gd", + "grp/conformal.gd", + "grp/perf.gd", + "grp/suzuki.gd", + "grp/ree.gd", + "grp/simple.gd", + "grp/imf.gd", + "grp/glzmodmz.gd", + "grp/clasmax.grp", + "lib/orders.gd", + "lib/trans.gd", + "lib/pperm.gd", + "lib/fastendo.gd", + "lib/fpsemi.gd", + "lib/fpmon.gd", + "lib/rwssmg.gd", + "lib/kbsemi.gd", + "lib/tcsemi.gd", + "lib/adjoin.gd", + "lib/semirel.gd", + "lib/semitran.gd", + "lib/reesmat.gd", + "lib/semiquo.gd", + "lib/semipperm.gd", + "lib/pager.gd", + "lib/helpbase.gd", + "lib/helpview.gd", + "lib/helpt2t.gd", + "lib/helpdef.gd", + "lib/ctbl.gd", + "lib/ctblfuns.gd", + "lib/ctblmaps.gd", + "lib/ctblauto.gd", + "lib/ctbllatt.gd", + "lib/ctblsymm.gd", + "lib/ctblsolv.gd", + "lib/ctblpope.gd", + "lib/ctblmoli.gd", + "lib/ctblmono.gd", + "lib/ctblgrp.gd", + "lib/tom.gd", + "lib/proto.gd", + "lib/gasman.gd", + "lib/memusage.gd", + "lib/read4.g", + "lib/profile.g", + "lib/newprofile.g", + "lib/methwhy.g", + "lib/pager.gi", + "lib/helpbase.gi", + "lib/helpview.gi", + "lib/helpt2t.gi", + "lib/helpdef.gi", + "lib/reread.g", + "lib/package.gi", + "lib/string.gi", + "lib/test.gd", + "lib/test.gi", + "lib/galois.gd", + "lib/galois.gi", + "lib/transatl.g", + "lib/obsolete.g", + "lib/obsolete.gd", + "lib/read.g", + "lib/read5.g", + "lib/type.gi", + "lib/rvecempt.gi", + "lib/ratfun1.gi", + "lib/matrix.gi", + "lib/matint.gi", + "lib/matblock.gi", + "lib/tuples.gi", + "lib/domain.gi", + "lib/mapping1.gi", + "lib/mapping.gi", + "lib/mapprep.gi", + "lib/mapphomo.gi", + "lib/relation.gi", + "lib/magma.gi", + "lib/mgmideal.gi", + "lib/mgmhom.gi", + "lib/mgmadj.gi", + "lib/mgmcong.gi", + "lib/semigrp.gi", + "lib/semicong.gi", + "lib/smgideal.gi", + "lib/monoid.gi", + "lib/grp.gi", + "lib/invsgp.gi", + "lib/addmagma.gi", + "lib/addcoset.gi", + "lib/ring.gi", + "lib/ideal.gi", + "lib/module.gi", + "lib/modfree.gi", + "lib/modulrow.gi", + "lib/modulmat.gi", + "lib/basis.gi", + "lib/basismut.gi", + "lib/vspc.gi", + "lib/vspcrow.gi", + "lib/vspcmat.gi", + "lib/vspchom.gi", + "lib/zlattice.gi", + "lib/mgmring.gi", + "lib/algebra.gi", + "lib/idealalg.gi", + "lib/alghom.gi", + "lib/algfp.gi", + "lib/alglie.gi", + "lib/algliess.gi", + "lib/algsc.gi", + "lib/algmat.gi", + "lib/liefam.gi", + "lib/algrep.gi", + "lib/lierep.gi", + "lib/numtheor.gi", + "lib/dlog.gi", + "lib/primality.gi", + "lib/contfrac.gi", + "lib/ringsc.gi", + "lib/ringhom.gi", + "lib/combinat.gi", + "lib/ratfun.gi", + "lib/ratfunul.gi", + "lib/ringpoly.gi", + "lib/upoly.gi", + "lib/upolyirr.gi", + "lib/polyfinf.gi", + "lib/polyrat.gi", + "lib/polyconw.gi", + "lib/listcoef.gi", + "lib/algfld.gi", + "lib/groebner.gi", + "lib/unknown.gi", + "lib/field.gi", + "lib/fieldfin.gi", + "lib/zmodnz.gi", + "lib/zmodnze.gi", + "lib/ffe.gi", + "lib/ffeconway.gi", + "lib/rational.gi", + "lib/gaussian.gi", + "lib/cyclotom.gi", + "lib/fldabnum.gi", + "lib/padics.gi", + "lib/matobj.gi", + "lib/matobjrowlist.gi", + "lib/vecmat.gi", + "lib/vec8bit.gi", + "lib/mat8bit.gi", + "lib/matobjplist.gi", + "lib/matobjnz.gi", + "lib/meataxe.gi", + "lib/meatauto.gi", + "lib/word.gi", + "lib/wordass.gi", + "lib/wordrep.gi", + "lib/wordlett.gi", + "lib/mgmfree.gi", + "lib/smgrpfre.gi", + "lib/monofree.gi", + "lib/grpfree.gi", + "lib/rws.gi", + "lib/rwspcclt.gi", + "lib/rwspcsng.gi", + "lib/rwspccoc.gi", + "lib/rwsgrp.gi", + "lib/rwspcgrp.gi", + "lib/rwsdt.gi", + "lib/nilpquot.gi", + "lib/pquot.gi", + "lib/pcgs.gi", + "lib/pcgsind.gi", + "lib/pcgsmodu.gi", + "lib/pcgspcg.gi", + "lib/pcgscomp.gi", + "lib/pcgsperm.gi", + "lib/pcgsnice.gi", + "lib/pcgsspec.gi", + "lib/grppc.gi", + "lib/grppcint.gi", + "lib/grppcprp.gi", + "lib/grppcatr.gi", + "lib/grppcnrm.gi", + "lib/bitfields.gi", + "lib/dict.gi", + "lib/dicthf.gi", + "lib/grptbl.gi", + "lib/ghom.gi", + "lib/ghompcgs.gi", + "lib/gprd.gi", + "lib/ghomperm.gi", + "lib/grpperm.gi", + "lib/gpprmsya.gi", + "lib/gprdperm.gi", + "lib/gprdpc.gi", + "lib/gprdmat.gi", + "lib/oprt.gi", + "lib/oprtperm.gi", + "lib/oprtpcgs.gi", + "lib/partitio.gi", + "lib/stbc.gi", + "lib/stbcbckt.gi", + "lib/stbcrand.gi", + "lib/clas.gi", + "lib/claspcgs.gi", + "lib/csetgrp.gi", + "lib/csetperm.gi", + "lib/csetpc.gi", + "lib/factgrp.gi", + "lib/grpreps.gi", + "lib/grppcrep.gi", + "lib/grpprmcs.gi", + "lib/grpnames.gi", + "lib/onecohom.gi", + "lib/grppccom.gi", + "lib/grpcompl.gi", + "lib/twocohom.gi", + "lib/grppcext.gi", + "lib/randiso.gi", + "lib/randiso2.gi", + "lib/grppcfp.gi", + "lib/schur.gi", + "lib/schursym.gi", + "lib/grpnice.gi", + "lib/fitfree.gi", + "lib/permdeco.gi", + "lib/clashom.gi", + "lib/clasperm.gi", + "lib/maxsub.gi", + "lib/norad.gi", + "lib/autsr.gi", + "lib/morpheus.gi", + "lib/grplatt.gi", + "lib/oprtglat.gi", + "lib/grppclat.gi", + "lib/grppcaut.gi", + "lib/grpmat.gi", + "lib/grpffmat.gi", + "lib/grpramat.gi", + "lib/grpfp.gi", + "lib/gpfpiso.gi", + "lib/sgpres.gi", + "lib/tietze.gi", + "lib/ghomfp.gi", + "lib/addgphom.gi", + "lib/trans.gi", + "lib/pperm.gi", + "lib/fastendo.gi", + "lib/fpsemi.gi", + "lib/fpmon.gi", + "lib/rwssmg.gi", + "lib/kbsemi.gi", + "lib/tcsemi.gi", + "lib/adjoin.gi", + "lib/semirel.gi", + "lib/semitran.gi", + "lib/reesmat.gi", + "lib/semiquo.gi", + "lib/semipperm.gi", + "lib/proto.gi", + "lib/orders.gi", + "lib/gasman.gi", + "lib/memusage.gi", + "lib/function.gi", + "lib/float.gi", + "lib/ieee754.g", + "lib/read6.g", + "grp/basicpcg.gi", + "grp/basicprm.gi", + "grp/basicmat.gi", + "grp/basicfp.gi", + "grp/perf.grp", + "grp/classic.gi", + "grp/conformal.gi", + "grp/suzuki.gi", + "grp/ree.gi", + "grp/simple.gi", + "grp/imf.grp", + "grp/imf.gi", + "grp/glzmodmz.gi", + "lib/read7.g", + "lib/ctbl.gi", + "lib/ctblfuns.gi", + "lib/ctblmaps.gi", + "lib/ctblauto.gi", + "lib/ctbllatt.gi", + "lib/ctblsymm.gi", + "lib/ctblsolv.gi", + "lib/ctblpope.gi", + "lib/ctblmoli.gi", + "lib/ctblmono.gi", + "lib/ctblgrp.gi", + "lib/ctblperm.gi", + "lib/ctblpc.gi", + "lib/tom.gi", + "lib/straight.gi", + "lib/memory.gi", + "lib/read8.g", + "lib/overload.g", + "lib/syntaxtree.gd", + "lib/syntaxtree.gi", + "lib/teaching.g", + "lib/teachm2.g", + "lib/operdebug.g", + "lib/colorprompt.g", + "pkg/4ti2interface/PackageInfo.g", + "pkg/ace/PackageInfo.g", + "pkg/aclib/PackageInfo.g", + "pkg/agt/PackageInfo.g", + "pkg/alco/PackageInfo.g", + "pkg/alnuth/PackageInfo.g", + "pkg/anupq/PackageInfo.g", + "pkg/atlasrep/PackageInfo.g", + "pkg/autodoc/PackageInfo.g", + "pkg/automata/PackageInfo.g", + "pkg/automgrp/PackageInfo.g", + "pkg/autpgrp/PackageInfo.g", + "pkg/browse/PackageInfo.g", + "pkg/cap/PackageInfo.g", + "pkg/caratinterface/PackageInfo.g", + "pkg/cddinterface/PackageInfo.g", + "pkg/circle/PackageInfo.g", + "pkg/classicalmaximals/PackageInfo.g", + "pkg/classicpres/PackageInfo.g", + "pkg/cohomolo/PackageInfo.g", + "pkg/congruence/PackageInfo.g", + "pkg/corefreesub/PackageInfo.g", + "pkg/corelg/PackageInfo.g", + "pkg/crime/PackageInfo.g", + "pkg/crisp/PackageInfo.g", + "pkg/crypting/PackageInfo.g", + "pkg/cryst/PackageInfo.g", + "pkg/crystcat/PackageInfo.g", + "pkg/ctbllib/PackageInfo.g", + "pkg/cubefree/PackageInfo.g", + "pkg/curlinterface/PackageInfo.g", + "pkg/cvec/PackageInfo.g", + "pkg/datastructures/PackageInfo.g", + "pkg/deepthought/PackageInfo.g", + "pkg/design/PackageInfo.g", + "pkg/difsets/PackageInfo.g", + "pkg/digraphs/PackageInfo.g", + "pkg/edim/PackageInfo.g", + "pkg/example/PackageInfo.g", + "pkg/examplesforhomalg/PackageInfo.g", + "pkg/factint/PackageInfo.g", + "pkg/ferret/PackageInfo.g", + "pkg/fga/PackageInfo.g", + "pkg/fining/PackageInfo.g", + "pkg/float/PackageInfo.g", + "pkg/format/PackageInfo.g", + "pkg/forms/PackageInfo.g", + "pkg/fplsa/PackageInfo.g", + "pkg/fr/PackageInfo.g", + "pkg/francy/PackageInfo.g", + "pkg/fwtree/PackageInfo.g", + "pkg/gapdoc/PackageInfo.g", + "pkg/gauss/PackageInfo.g", + "pkg/gaussforhomalg/PackageInfo.g", + "pkg/gbnp/PackageInfo.g", + "pkg/generalizedmorphismsforcap/PackageInfo.g", + "pkg/genss/PackageInfo.g", + "pkg/gradedmodules/PackageInfo.g", + "pkg/gradedringforhomalg/PackageInfo.g", + "pkg/grape/PackageInfo.g", + "pkg/groupoids/PackageInfo.g", + "pkg/grpconst/PackageInfo.g", + "pkg/guarana/PackageInfo.g", + "pkg/guava/PackageInfo.g", + "pkg/hap/PackageInfo.g", + "pkg/hapcryst/PackageInfo.g", + "pkg/hecke/PackageInfo.g", + "pkg/help/PackageInfo.g", + "pkg/homalg/PackageInfo.g", + "pkg/homalgtocas/PackageInfo.g", + "pkg/ibnp/PackageInfo.g", + "pkg/idrel/PackageInfo.g", + "pkg/images/PackageInfo.g", + "pkg/inducereduce/PackageInfo.g", + "pkg/intpic/PackageInfo.g", + "pkg/io/PackageInfo.g", + "pkg/io_forhomalg/PackageInfo.g", + "pkg/irredsol/PackageInfo.g", + "pkg/itc/PackageInfo.g", + "pkg/json/PackageInfo.g", + "pkg/jupyterkernel/PackageInfo.g", + "pkg/jupyterviz/PackageInfo.g", + "pkg/kan/PackageInfo.g", + "pkg/kbmag/PackageInfo.g", + "pkg/laguna/PackageInfo.g", + "pkg/liealgdb/PackageInfo.g", + "pkg/liepring/PackageInfo.g", + "pkg/liering/PackageInfo.g", + "pkg/linearalgebraforcap/PackageInfo.g", + "pkg/lins/PackageInfo.g", + "pkg/localizeringforhomalg/PackageInfo.g", + "pkg/localnr/PackageInfo.g", + "pkg/loops/PackageInfo.g", + "pkg/lpres/PackageInfo.g", + "pkg/majoranaalgebras/PackageInfo.g", + "pkg/mapclass/PackageInfo.g", + "pkg/matgrp/PackageInfo.g", + "pkg/matricesforhomalg/PackageInfo.g", + "pkg/modisom/PackageInfo.g", + "pkg/modulargroup/PackageInfo.g", + "pkg/modulepresentationsforcap/PackageInfo.g", + "pkg/modules/PackageInfo.g", + "pkg/monoidalcategories/PackageInfo.g", + "pkg/nconvex/PackageInfo.g", + "pkg/nilmat/PackageInfo.g", + "pkg/nock/PackageInfo.g", + "pkg/nofoma/PackageInfo.g", + "pkg/normalizinterface/PackageInfo.g", + "pkg/nq/PackageInfo.g", + "pkg/numericalsgps/PackageInfo.g", + "pkg/openmath/PackageInfo.g", + "pkg/orb/PackageInfo.g", + "pkg/origami/PackageInfo.g", + "pkg/packagemaker/PackageInfo.g", + "pkg/packagemanager/PackageInfo.g", + "pkg/patternclass/PackageInfo.g", + "pkg/permut/PackageInfo.g", + "pkg/polenta/PackageInfo.g", + "pkg/polycyclic/PackageInfo.g", + "pkg/polymaking/PackageInfo.g", + "pkg/primgrp/PackageInfo.g", + "pkg/profiling/PackageInfo.g", + "pkg/qdistrnd/PackageInfo.g", + "pkg/qpa/PackageInfo.g", + "pkg/quagroup/PackageInfo.g", + "pkg/radiroot/PackageInfo.g", + "pkg/rcwa/PackageInfo.g", + "pkg/rds/PackageInfo.g", + "pkg/recog/PackageInfo.g", + "pkg/repndecomp/PackageInfo.g", + "pkg/repsn/PackageInfo.g", + "pkg/resclasses/PackageInfo.g", + "pkg/ringsforhomalg/PackageInfo.g", + "pkg/sco/PackageInfo.g", + "pkg/scscp/PackageInfo.g", + "pkg/semigroups/PackageInfo.g", + "pkg/sglppow/PackageInfo.g", + "pkg/sgpviz/PackageInfo.g", + "pkg/simpcomp/PackageInfo.g", + "pkg/singular/PackageInfo.g", + "pkg/sl2reps/PackageInfo.g", + "pkg/sla/PackageInfo.g", + "pkg/smallantimagmas/PackageInfo.g", + "pkg/smallclassnr/PackageInfo.g", + "pkg/smallgrp/PackageInfo.g", + "pkg/smallsemi/PackageInfo.g", + "pkg/sonata/PackageInfo.g", + "pkg/sophus/PackageInfo.g", + "pkg/sotgrps/PackageInfo.g", + "pkg/spinsym/PackageInfo.g", + "pkg/standardff/PackageInfo.g", + "pkg/symbcompcc/PackageInfo.g", + "pkg/thelma/PackageInfo.g", + "pkg/tomlib/PackageInfo.g", + "pkg/toolsforhomalg/PackageInfo.g", + "pkg/toric/PackageInfo.g", + "pkg/transgrp/PackageInfo.g", + "pkg/twistedconjugacy/PackageInfo.g", + "pkg/typeset/PackageInfo.g", + "pkg/ugaly/PackageInfo.g", + "pkg/unipot/PackageInfo.g", + "pkg/unitlib/PackageInfo.g", + "pkg/utils/PackageInfo.g", + "pkg/uuid/PackageInfo.g", + "pkg/walrus/PackageInfo.g", + "pkg/wedderga/PackageInfo.g", + "pkg/wpe/PackageInfo.g", + "pkg/xgap/PackageInfo.g", + "pkg/xmod/PackageInfo.g", + "pkg/xmodalg/PackageInfo.g", + "pkg/yangbaxter/PackageInfo.g", + "pkg/zeromqinterface/PackageInfo.g", + "pkg/gapdoc/init.g", + "pkg/gapdoc/lib/UnicodeTools.gd", + "pkg/gapdoc/lib/PrintUtil.gd", + "pkg/gapdoc/lib/Text.gd", + "pkg/gapdoc/lib/ComposeXML.gd", + "pkg/gapdoc/lib/XMLParser.gd", + "pkg/gapdoc/lib/GAPDoc.gd", + "pkg/gapdoc/lib/BibTeX.gd", + "pkg/gapdoc/lib/BibXMLextTools.gd", + "pkg/gapdoc/lib/GAPDoc2LaTeX.gd", + "pkg/gapdoc/lib/GAPDoc2Text.gd", + "pkg/gapdoc/lib/GAPDoc2HTML.gd", + "pkg/gapdoc/lib/Make.g", + "pkg/gapdoc/lib/Examples.gd", + "pkg/gapdoc/read.g", + "pkg/gapdoc/lib/UnicodeTools.gi", + "pkg/gapdoc/lib/UnicodeTabs.g", + "pkg/gapdoc/lib/PrintUtil.gi", + "pkg/gapdoc/lib/Text.gi", + "pkg/gapdoc/lib/ComposeXML.gi", + "pkg/gapdoc/lib/XMLParser.gi", + "pkg/gapdoc/lib/gapdocdtdinfo.g", + "pkg/gapdoc/lib/GAPDoc.gi", + "pkg/gapdoc/lib/BibTeX.gi", + "pkg/gapdoc/lib/bibxmlextinfo.g", + "pkg/gapdoc/lib/BibXMLextTools.gi", + "pkg/gapdoc/lib/GAPDoc2LaTeX.gi", + "pkg/gapdoc/lib/latexhead.tex", + "pkg/gapdoc/lib/GAPDoc2Text.gi", + "pkg/gapdoc/lib/TextThemes.g", + "pkg/gapdoc/lib/GAPDoc2HTML.gi", + "pkg/gapdoc/lib/Examples.gi", + "pkg/gapdoc/lib/HelpBookHandler.g", + "pkg/primgrp/init.g", + "pkg/primgrp/lib/primitiv.gd", + "pkg/primgrp/lib/irredsol.gd", + "pkg/primgrp/read.g", + "pkg/primgrp/lib/primitiv.grp", + "pkg/primgrp/lib/primitiv.gi", + "pkg/primgrp/lib/irredsol.grp", + "pkg/primgrp/lib/irredsol.gi", + "pkg/primgrp/lib/cohorts.grp", + "pkg/smallgrp/init.g", + "pkg/smallgrp/gap/small.gd", + "pkg/smallgrp/read.g", + "pkg/smallgrp/gap/small.gi", + "pkg/smallgrp/gap/smlgp1.g", + "pkg/smallgrp/gap/idgrp1.g", + "pkg/smallgrp/gap/smlinfo.gi", + "pkg/smallgrp/small2/smlgp2.g.gz", + "pkg/smallgrp/small3/smlgp3.g.gz", + "pkg/smallgrp/small4/smlgp4.g.gz", + "pkg/smallgrp/small5/smlgp5.g.gz", + "pkg/smallgrp/small6/smlgp6.g.gz", + "pkg/smallgrp/small7/smlgp7.g.gz", + "pkg/smallgrp/small8/smlgp8.g.gz", + "pkg/smallgrp/small9/smlgp9.g.gz", + "pkg/smallgrp/small10/smlgp10.g.gz", + "pkg/smallgrp/small11/smlgp11.g.gz", + "pkg/smallgrp/id2/idgrp2.g.gz", + "pkg/smallgrp/id3/idgrp3.g.gz", + "pkg/smallgrp/id4/idgrp4.g.gz", + "pkg/smallgrp/id5/idgrp5.g.gz", + "pkg/smallgrp/id6/idgrp6.g.gz", + "pkg/smallgrp/id9/idgrp9.g.gz", + "pkg/smallgrp/id10/idgrp10.g.gz", + "pkg/transgrp/init.g", + "pkg/transgrp/lib/trans.gd", + "pkg/transgrp/read.g", + "pkg/transgrp/lib/trans.grp", + "pkg/transgrp/lib/trans.gi", + "pkg/autpgrp/init.g", + "pkg/autpgrp/gap/autos.gd", + "pkg/autpgrp/read.g", + "pkg/autpgrp/gap/general.gi", + "pkg/autpgrp/gap/autoops.gi", + "pkg/autpgrp/gap/matrix.gi", + "pkg/autpgrp/gap/nicestab.gi", + "pkg/autpgrp/gap/initmat.gi", + "pkg/autpgrp/gap/initperm.gi", + "pkg/autpgrp/gap/hybrstab.gi", + "pkg/autpgrp/gap/matrstab.gi", + "pkg/autpgrp/gap/orbstab.gi", + "pkg/autpgrp/gap/autos.gi", + "pkg/autpgrp/gap/pcpres.gi", + "pkg/autpgrp/gap/countcl.gi", + "pkg/alnuth/init.g", + "pkg/alnuth/gap/setup.gd", + "pkg/alnuth/gap/factors.gd", + "pkg/alnuth/gap/field.gd", + "pkg/polycyclic/init.g", + "pkg/polycyclic/gap/matrix/matrix.gd", + "pkg/polycyclic/gap/basic/infos.gd", + "pkg/polycyclic/gap/basic/collect.gd", + "pkg/polycyclic/gap/basic/pcpelms.gd", + "pkg/polycyclic/gap/basic/pcpgrps.gd", + "pkg/polycyclic/gap/basic/pcppcps.gd", + "pkg/polycyclic/gap/basic/grphoms.gd", + "pkg/polycyclic/gap/basic/basic.gd", + "pkg/polycyclic/gap/cohom/cohom.gd", + "pkg/polycyclic/gap/matrep/matrep.gd", + "pkg/polycyclic/gap/matrep/unitri.gd", + "pkg/polycyclic/gap/pcpgrp/pcpgrp.gd", + "pkg/polycyclic/gap/pcpgrp/torsion.gd", + "pkg/polycyclic/gap/exam/exam.gd", + "pkg/polycyclic/gap/obsolete.gd", + "pkg/alnuth/read.g", + "pkg/alnuth/gap/userpref.gi", + "pkg/alnuth/gap/setup.gi", + "pkg/alnuth/gap/pari.gi", + "pkg/alnuth/gap/factors.gi", + "pkg/alnuth/gap/matfield.gi", + "pkg/alnuth/gap/polfield.gi", + "pkg/alnuth/gap/field.gi", + "pkg/alnuth/gap/unithom.gi", + "pkg/alnuth/gap/matunits.gi", + "pkg/alnuth/gap/rels.gi", + "pkg/alnuth/gap/present.gi", + "pkg/alnuth/gap/isom.gi", + "pkg/alnuth/gap/rationals.gi", + "pkg/alnuth/exam/unimod.gi", + "pkg/alnuth/exam/rationals.gi", + "pkg/alnuth/exam/fields.gi", + "pkg/polycyclic/read.g", + "pkg/polycyclic/gap/matrix/rowbases.gi", + "pkg/polycyclic/gap/matrix/latbases.gi", + "pkg/polycyclic/gap/matrix/lattices.gi", + "pkg/polycyclic/gap/matrix/modules.gi", + "pkg/polycyclic/gap/matrix/triangle.gi", + "pkg/polycyclic/gap/matrix/hnf.gi", + "pkg/polycyclic/gap/basic/collect.gi", + "pkg/polycyclic/gap/basic/colftl.gi", + "pkg/polycyclic/gap/basic/colcom.gi", + "pkg/polycyclic/gap/basic/coldt.gi", + "pkg/polycyclic/gap/basic/colsave.gi", + "pkg/polycyclic/gap/basic/pcpelms.gi", + "pkg/polycyclic/gap/basic/pcppcps.gi", + "pkg/polycyclic/gap/basic/pcpgrps.gi", + "pkg/polycyclic/gap/basic/pcppara.gi", + "pkg/polycyclic/gap/basic/pcpexpo.gi", + "pkg/polycyclic/gap/basic/pcpsers.gi", + "pkg/polycyclic/gap/basic/grphoms.gi", + "pkg/polycyclic/gap/basic/pcpfact.gi", + "pkg/polycyclic/gap/basic/chngpcp.gi", + "pkg/polycyclic/gap/basic/convert.gi", + "pkg/polycyclic/gap/basic/orbstab.gi", + "pkg/polycyclic/gap/basic/construct.gi", + "pkg/polycyclic/gap/cohom/cohom.gi", + "pkg/polycyclic/gap/cohom/addgrp.gi", + "pkg/polycyclic/gap/cohom/general.gi", + "pkg/polycyclic/gap/cohom/solabel.gi", + "pkg/polycyclic/gap/cohom/solcohom.gi", + "pkg/polycyclic/gap/cohom/twocohom.gi", + "pkg/polycyclic/gap/cohom/intcohom.gi", + "pkg/polycyclic/gap/cohom/onecohom.gi", + "pkg/polycyclic/gap/cohom/grpext.gi", + "pkg/polycyclic/gap/cohom/grpcom.gi", + "pkg/polycyclic/gap/cohom/norcom.gi", + "pkg/polycyclic/gap/action/extend.gi", + "pkg/polycyclic/gap/action/basepcgs.gi", + "pkg/polycyclic/gap/action/freegens.gi", + "pkg/polycyclic/gap/action/dixon.gi", + "pkg/polycyclic/gap/action/kernels.gi", + "pkg/polycyclic/gap/action/orbstab.gi", + "pkg/polycyclic/gap/action/orbnorm.gi", + "pkg/polycyclic/gap/pcpgrp/general.gi", + "pkg/polycyclic/gap/pcpgrp/inters.gi", + "pkg/polycyclic/gap/pcpgrp/grpinva.gi", + "pkg/polycyclic/gap/pcpgrp/torsion.gi", + "pkg/polycyclic/gap/pcpgrp/maxsub.gi", + "pkg/polycyclic/gap/pcpgrp/findex.gi", + "pkg/polycyclic/gap/pcpgrp/nindex.gi", + "pkg/polycyclic/gap/pcpgrp/nilpot.gi", + "pkg/polycyclic/gap/pcpgrp/polyz.gi", + "pkg/polycyclic/gap/pcpgrp/pcpattr.gi", + "pkg/polycyclic/gap/pcpgrp/wreath.gi", + "pkg/polycyclic/gap/pcpgrp/fitting.gi", + "pkg/polycyclic/gap/pcpgrp/centcon.gi", + "pkg/polycyclic/gap/pcpgrp/normcon.gi", + "pkg/polycyclic/gap/pcpgrp/schur.gi", + "pkg/polycyclic/gap/pcpgrp/tensor.gi", + "pkg/polycyclic/gap/matrep/matrep.gi", + "pkg/polycyclic/gap/matrep/affine.gi", + "pkg/polycyclic/gap/matrep/unitri.gi", + "pkg/polycyclic/gap/exam/pcplib.gi", + "pkg/polycyclic/gap/exam/matlib.gi", + "pkg/polycyclic/gap/exam/nqlib.gi", + "pkg/polycyclic/gap/exam/generic.gi", + "pkg/polycyclic/gap/exam/bgnilp.gi", + "pkg/polycyclic/gap/exam/metacyc.gi", + "pkg/polycyclic/gap/exam/metagrp.gi", + "pkg/polycyclic/gap/cover/const/bas.gi", + "pkg/polycyclic/gap/cover/const/orb.gi", + "pkg/polycyclic/gap/cover/const/aut.gi", + "pkg/polycyclic/gap/cover/const/com.gi", + "pkg/polycyclic/gap/cover/const/cov.gi", + "pkg/crisp/init.g", + "pkg/crisp/lib/classes.gd", + "pkg/crisp/lib/grpclass.gd", + "pkg/crisp/lib/fitting.gd", + "pkg/crisp/lib/schunck.gd", + "pkg/crisp/lib/form.gd", + "pkg/crisp/lib/projector.gd", + "pkg/crisp/lib/injector.gd", + "pkg/crisp/lib/normpro.gd", + "pkg/crisp/lib/solveeq.gd", + "pkg/crisp/lib/compl.gd", + "pkg/crisp/lib/radical.gd", + "pkg/crisp/lib/residual.gd", + "pkg/crisp/lib/util.gd", + "pkg/crisp/lib/samples.gd", + "pkg/crisp/lib/socle.gd", + "pkg/crisp/read.g", + "pkg/crisp/lib/classes.gi", + "pkg/crisp/lib/grpclass.gi", + "pkg/crisp/lib/fitting.gi", + "pkg/crisp/lib/schunck.gi", + "pkg/crisp/lib/form.gi", + "pkg/crisp/lib/projector.gi", + "pkg/crisp/lib/injector.gi", + "pkg/crisp/lib/normpro.gi", + "pkg/crisp/lib/solveeq.gi", + "pkg/crisp/lib/compl.gi", + "pkg/crisp/lib/radical.gi", + "pkg/crisp/lib/residual.gi", + "pkg/crisp/lib/util.gi", + "pkg/crisp/lib/samples.gi", + "pkg/crisp/lib/socle.gi", + "pkg/factint/init.g", + "pkg/factint/lib/factint.gd", + "pkg/factint/read.g", + "pkg/factint/tables/3k2k.g", + "pkg/factint/tables/akbk.g", + "pkg/factint/tables/factorial.g", + "pkg/factint/tables/fibo.g", + "pkg/factint/tables/primorial.g", + "pkg/factint/lib/general.gi", + "pkg/factint/lib/pminus1.gi", + "pkg/factint/lib/pplus1.gi", + "pkg/factint/lib/ecm.gi", + "pkg/factint/lib/cfrac.gi", + "pkg/factint/lib/mpqs.gi", + "pkg/forms/init.g", + "pkg/forms/lib/forms.gd", + "pkg/forms/lib/recognition.gd", + "pkg/forms/lib/conformal.gd", + "pkg/forms/read.g", + "pkg/forms/lib/forms.gi", + "pkg/forms/lib/recognition.gi", + "pkg/forms/lib/classic.gi", + "pkg/forms/lib/recognition_new.gi", + "pkg/forms/lib/conformal.gi", + "pkg/orb/init.g", + "pkg/orb/gap/homwdata.gd", + "pkg/orb/gap/avltree.gd", + "pkg/orb/gap/hash.gd", + "pkg/orb/gap/cache.gd", + "pkg/orb/gap/orbits.gd", + "pkg/orb/gap/search.gd", + "pkg/orb/gap/bysuborbit.gd", + "pkg/orb/read.g", + "pkg/orb/gap/homwdata.gi", + "pkg/orb/gap/avltree.gi", + "pkg/orb/gap/hash.gi", + "pkg/orb/gap/cache.gi", + "pkg/orb/gap/orbits.gi", + "pkg/orb/gap/search.gi", + "pkg/orb/gap/bysuborbit.gi", + "pkg/utils/init.g", + "pkg/utils/lib/start.gd", + "pkg/utils/lib/files.gd", + "pkg/utils/lib/groups.gd", + "pkg/utils/lib/iterator.gd", + "pkg/utils/lib/latex.gd", + "pkg/utils/lib/lcset.gd", + "pkg/utils/lib/lists.gd", + "pkg/utils/lib/magma.gd", + "pkg/utils/lib/maps.gd", + "pkg/utils/lib/matrix.gd", + "pkg/utils/lib/number.gd", + "pkg/utils/lib/print.gd", + "pkg/utils/lib/record.gd", + "pkg/utils/lib/string.gd", + "pkg/utils/lib/gslp.gd", + "pkg/utils/lib/download.gd", + "pkg/utils/read.g", + "pkg/utils/lib/files.gi", + "pkg/utils/lib/groups.gi", + "pkg/utils/lib/iterator.gi", + "pkg/utils/lib/latex.gi", + "pkg/utils/lib/lcset.gi", + "pkg/utils/lib/lists.gi", + "pkg/utils/lib/magma.gi", + "pkg/utils/lib/maps.gi", + "pkg/utils/lib/matrix.gi", + "pkg/utils/lib/number.gi", + "pkg/utils/lib/print.gi", + "pkg/utils/lib/record.gi", + "pkg/utils/lib/string.gi", + "pkg/utils/lib/gslp.gi", + "pkg/utils/lib/download.gi", + "pkg/genss/init.g", + "pkg/genss/gap/genss.gd", + "pkg/genss/gap/setwise.gd", + "pkg/genss/read.g", + "pkg/genss/gap/genss.gi", + "pkg/genss/gap/setwise.gi", + "pkg/atlasrep/init.g", + "pkg/atlasrep/gap/userpref.g", + "pkg/atlasrep/gap/bbox.gd", + "pkg/atlasrep/gap/access.gd", + "pkg/atlasrep/gap/scanmtx.gd", + "pkg/atlasrep/gap/scanmtx.gi", + "pkg/atlasrep/gap/types.gd", + "pkg/atlasrep/gap/interfac.gd", + "pkg/atlasrep/gap/mindeg.gd", + "pkg/atlasrep/gap/utils.gd", + "pkg/ctbllib/init.g", + "pkg/ctbllib/gap4/ctadmin.gd", + "pkg/ctbllib/gap4/construc.gd", + "pkg/ctbllib/gap4/ctblothe.gd", + "pkg/ctbllib/dlnames/dlnames.gd", + "pkg/ctbllib/gap4/obsolete.gd", + "pkg/ctbllib/gap4/brdbattrX.gd", + "pkg/ctbllib/gap4/brdbattrX.gi", + "pkg/recog/init.g", + "pkg/recog/gap/base/hack.g", + "pkg/recog/gap/base/methods.gd", + "pkg/recog/gap/base/methsel.gd", + "pkg/recog/gap/base/recognition.gd", + "pkg/recog/gap/base/kernel.gd", + "pkg/recog/gap/base/projective.gd", + "pkg/recog/gap/matrix/ppd.gd", + "pkg/recog/gap/matrix/classical.gd", + "pkg/recog/gap/projective/almostsimple.gd", + "pkg/recog/gap/projective/findnormal.gd", + "pkg/recog/gap/projective/AnSnOnFDPM.gd", + "pkg/spinsym/init.g", + "pkg/spinsym/gap/mtx.gd", + "pkg/spinsym/gap/fus.gd", + "pkg/spinsym/gap/young.gd", + "pkg/standardff/init.g", + "pkg/standardff/lib/Util.gd", + "pkg/standardff/lib/IsIrred.gd", + "pkg/standardff/lib/StandardFF.gd", + "pkg/standardff/lib/StandardCyc.gd", + "pkg/tomlib/init.g", + "pkg/tomlib/gap/tmadmin.tmd", + "pkg/tomlib/gap/stdgen.gd", + "pkg/atlasrep/read.g", + "pkg/atlasrep/gap/bbox.gi", + "pkg/atlasrep/gap/access.gi", + "pkg/atlasrep/gap/types.gi", + "pkg/atlasrep/gap/interfac.gi", + "pkg/atlasrep/gap/mindeg.gi", + "pkg/atlasrep/gap/utlmrkup.g", + "pkg/atlasrep/gap/utils.gi", + "pkg/atlasrep/gap/test.g", + "pkg/atlasrep/gap/json.g", + "pkg/atlasrep/gap/obsolete.gd", + "pkg/atlasrep/gap/obsolete.gi", + "pkg/ctbllib/read.g", + "pkg/ctbllib/gap4/ctadmin.gi", + "pkg/ctbllib/gap4/ctprimar.g", + "pkg/ctbllib/data/firstnames.json", + "pkg/ctbllib/data/othernames.json", + "pkg/ctbllib/data/fusionsources.json", + "pkg/ctbllib/data/extinfo.json", + "pkg/ctbllib/data/ctgeneri.tbl", + "pkg/ctbllib/data/version", + "pkg/ctbllib/data/namerepl.json", + "pkg/ctbllib/gap4/construc.gi", + "pkg/ctbllib/gap4/ctblothe.gi", + "pkg/ctbllib/gap4/test.g", + "pkg/ctbllib/dlnames/dlnames.gi", + "pkg/ctbllib/gap4/ctbltoct.g", + "pkg/ctbllib/gap4/ctdbattr.g", + "pkg/ctbllib/gap4/od.g", + "pkg/ctbllib/data/odresults.json", + "pkg/ctbllib/gap4/atlasstr.g", + "pkg/ctbllib/gap4/atlasirr.g", + "pkg/recog/read.g", + "pkg/recog/gap/base/methods.gi", + "pkg/recog/gap/base/methsel.gi", + "pkg/recog/gap/base/recognition.gi", + "pkg/recog/gap/base/kernel.gi", + "pkg/recog/gap/base/projective.gi", + "pkg/recog/gap/utils.gi", + "pkg/recog/gap/generic/TrivialGroup.gi", + "pkg/recog/gap/generic/FewGensAbelian.gi", + "pkg/recog/gap/generic/KnownNilpotent.gi", + "pkg/recog/gap/perm/giant.gi", + "pkg/recog/gap/perm/largebase.gi", + "pkg/recog/gap/SnAnBB.gi", + "pkg/recog/gap/generic/SnAnUnknownDegree.gi", + "pkg/recog/gap/matrix/matimpr.gi", + "pkg/recog/gap/matrix/blocks.gi", + "pkg/recog/gap/matrix/ppd.gi", + "pkg/recog/gap/matrix/classical.gi", + "pkg/recog/gap/matrix/slconstr.gi", + "pkg/recog/gap/projective/findnormal.gi", + "pkg/recog/gap/projective/c6.gi", + "pkg/recog/gap/projective/tensor.gi", + "pkg/recog/gap/projective/c3c5.gi", + "pkg/recog/gap/projective/d247.gi", + "pkg/recog/gap/projective/almostsimple/threeelorders.gi", + "pkg/recog/gap/projective/almostsimple.gi", + "pkg/recog/gap/projective/almostsimple/lietype.gi", + "pkg/recog/gap/projective/almostsimple/hints.gi", + "pkg/recog/gap/projective/classicalnatural.gi", + "pkg/recog/gap/projective/sl2_natural.gi", + "pkg/recog/gap/projective/sl.gi", + "pkg/recog/gap/projective/AnSnOnFDPM.gi", + "pkg/recog/gap/perm.gi", + "pkg/recog/gap/matrix.gi", + "pkg/recog/gap/projective.gi", + "pkg/spinsym/read.g", + "pkg/spinsym/gap/mtx.gi", + "pkg/spinsym/gap/fus.gi", + "pkg/spinsym/gap/young.gi", + "pkg/standardff/read.g", + "pkg/standardff/lib/Util.gi", + "pkg/standardff/lib/IsIrred.gi", + "pkg/standardff/lib/StandardFF.gi", + "pkg/standardff/lib/StandardCyc.gi", + "pkg/standardff/lib/CANFACT.g", + "pkg/standardff/lib/TestFuncs.g", + "pkg/tomlib/read.g", + "pkg/tomlib/gap/tmstdrd.tom", + "pkg/tomlib/gap/tmadmin.tmi", + "pkg/tomlib/gap/stdgen.gi", + "pkg/atlasrep/gap/ctbllib_only.g", + "pkg/ctbllib/gap4/atlasrep_only.g", + "pkg/ctbllib/gap4/tomlib_only.g", + "pkg/ctbllib/data/tom_tbl.json", + "pkg/ctbllib/gap4/spinsym_only.g", + "pkg/ctbllib/data/grp_atlas.json", + "pkg/ctbllib/data/attr_nccl.json", + "pkg/ctbllib/data/grp_small.json", + "pkg/ctbllib/data/grp_tom.json", + "pkg/ctbllib/data/grp_trans.json", + "pkg/ctbllib/data/grp_prim.json", + "pkg/ctbllib/data/grp_perf.json", + "pkg/fga/init.g", + "pkg/fga/lib/util.gd", + "pkg/fga/lib/Iterated.gd", + "pkg/fga/lib/Autom.gd", + "pkg/fga/lib/FreeGrps.gd", + "pkg/fga/lib/ReprAct.gd", + "pkg/fga/lib/Normal.gd", + "pkg/fga/lib/ExtAutom.gd", + "pkg/fga/lib/Hom.gd", + "pkg/fga/lib/AutGrp.gd", + "pkg/fga/lib/Intsect.gd", + "pkg/fga/lib/Whitehd.gd", + "pkg/fga/read.g", + "pkg/fga/lib/util.gi", + "pkg/fga/lib/Iterated.gi", + "pkg/fga/lib/Autom.gi", + "pkg/fga/lib/FreeGrps.gi", + "pkg/fga/lib/ReprAct.gi", + "pkg/fga/lib/Normal.gi", + "pkg/fga/lib/Central.gi", + "pkg/fga/lib/Index.gi", + "pkg/fga/lib/ExtAutom.gi", + "pkg/fga/lib/Hom.gi", + "pkg/fga/lib/AutGrp.gi", + "pkg/fga/lib/Intsect.gi", + "pkg/fga/lib/ReprActT.gi", + "pkg/fga/lib/Whitehd.gi", + "pkg/irredsol/init.g", + "pkg/irredsol/lib/util.g", + "pkg/irredsol/lib/util.gd", + "pkg/irredsol/lib/matmeths.gd", + "pkg/irredsol/lib/loading.gd", + "pkg/irredsol/lib/loadfp.gd", + "pkg/irredsol/lib/access.gd", + "pkg/irredsol/lib/iterators.gd", + "pkg/irredsol/lib/recognize.gd", + "pkg/irredsol/lib/primitive.gd", + "pkg/irredsol/lib/recognizeprim.gd", + "pkg/irredsol/lib/obsolete.gd", + "pkg/irredsol/read.g", + "pkg/irredsol/lib/matmeths.gi", + "pkg/irredsol/lib/loading.gi", + "pkg/irredsol/lib/loadfp.gi", + "pkg/irredsol/lib/access.gi", + "pkg/irredsol/lib/iterators.gi", + "pkg/irredsol/lib/recognize.gi", + "pkg/irredsol/lib/primitive.gi", + "pkg/irredsol/lib/recognizeprim.gi", + "pkg/irredsol/lib/util.gi", + "pkg/irredsol/lib/obsolete.gi", + "pkg/sophus/init.g", + "pkg/sophus/gap/sophus.gd", + "pkg/sophus/read.g", + "pkg/sophus/gap/general.gi", + "pkg/sophus/gap/lienp.gi", + "pkg/sophus/gap/liesct.gi", + "pkg/sophus/gap/liecover.gi", + "pkg/sophus/gap/nicestab.gi", + "pkg/sophus/gap/lieautoops.gi", + "pkg/sophus/gap/initauts.gi", + "pkg/sophus/gap/lieautgrp.gi", + "pkg/sophus/gap/allowable.gi", + "pkg/sophus/gap/descendant.gi", + "pkg/sophus/gap/lieisom.gi", + "pkg/sophus/gap/io.gi", + "pkg/laguna/init.g", + "pkg/laguna/lib/laguna.gd", + "pkg/laguna/lib/laguna.g", + "pkg/laguna/read.g", + "pkg/laguna/lib/laguna.gi", + "pkg/autodoc/init.g", + "pkg/autodoc/gap/DocumentationTree.gd", + "pkg/autodoc/gap/Parser.gd", + "pkg/autodoc/gap/AutoDocMainFunction.gd", + "pkg/autodoc/gap/ToolFunctions.gd", + "pkg/autodoc/gap/Magic.gd", + "pkg/autodoc/gap/Markdown.gd", + "pkg/autodoc/read.g", + "pkg/autodoc/gap/ToolFunctions.gi", + "pkg/autodoc/gap/DocumentationTree.gi", + "pkg/autodoc/gap/Parser.gi", + "pkg/autodoc/gap/AutoDocMainFunction.gi", + "pkg/autodoc/gap/Magic.gi", + "pkg/autodoc/gap/Markdown.gi", + "pkg/packagemanager/init.g", + "pkg/packagemanager/gap/PackageManager.gd", + "pkg/packagemanager/gap/archive.gd", + "pkg/packagemanager/gap/compile.gd", + "pkg/packagemanager/gap/directories.gd", + "pkg/packagemanager/gap/distro.gd", + "pkg/packagemanager/gap/doc.gd", + "pkg/packagemanager/gap/download.gd", + "pkg/packagemanager/gap/git.gd", + "pkg/packagemanager/gap/hg.gd", + "pkg/packagemanager/gap/interactive.gd", + "pkg/packagemanager/gap/packageinfo.gd", + "pkg/packagemanager/read.g", + "pkg/packagemanager/gap/PackageManager.gi", + "pkg/packagemanager/gap/archive.gi", + "pkg/packagemanager/gap/compile.gi", + "pkg/packagemanager/gap/directories.gi", + "pkg/packagemanager/gap/distro.gi", + "pkg/packagemanager/gap/doc.gi", + "pkg/packagemanager/gap/download.gi", + "pkg/packagemanager/gap/git.gi", + "pkg/packagemanager/gap/hg.gi", + "pkg/packagemanager/gap/interactive.gi", + "pkg/packagemanager/gap/packageinfo.gi", + "pkg/radiroot/init.g", + "pkg/radiroot/lib/Radicals.gd", + "pkg/radiroot/lib/SplittField.gd", + "pkg/radiroot/lib/Manipulations.gd", + "pkg/radiroot/lib/Strings.gd", + "pkg/radiroot/lib/Maple.gd", + "pkg/radiroot/read.g", + "pkg/radiroot/lib/Radicals.gi", + "pkg/radiroot/lib/SplittField.gi", + "pkg/radiroot/lib/Manipulations.gi", + "pkg/radiroot/lib/Strings.gi", + "pkg/radiroot/lib/Maple.gi", + "pkg/aclib/init.g", + "pkg/aclib/gap/groups.gd", + "pkg/cryst/init.g", + "pkg/cryst/gap/common.gd", + "pkg/cryst/gap/cryst.gd", + "pkg/cryst/gap/hom.gd", + "pkg/cryst/gap/wyckoff.gd", + "pkg/cryst/gap/zass.gd", + "pkg/cryst/gap/max.gd", + "pkg/cryst/gap/color.gd", + "pkg/cryst/gap/equiv.gd", + "pkg/cryst/grp/spacegrp.gd", + "pkg/crystcat/init.g", + "pkg/crystcat/lib/crystcat.gd", + "pkg/polenta/init.g", + "pkg/polenta/lib/finite.gd", + "pkg/polenta/lib/info.gd", + "pkg/polenta/lib/basic.gd", + "pkg/polenta/exam/test.gd", + "pkg/polenta/lib/cpcs.gd", + "pkg/polenta/lib/present.gd", + "pkg/polenta/lib/solvable.gd", + "pkg/polenta/lib/series.gd", + "pkg/polenta/lib/subgroups.gd", + "pkg/polenta/lib/ispolyz.gd", + "pkg/aclib/read.g", + "pkg/aclib/gap/matgrp3.gi", + "pkg/aclib/gap/matgrp4.gi", + "pkg/aclib/gap/matgrp.gi", + "pkg/aclib/gap/pcpgrp3.gi", + "pkg/aclib/gap/pcpgrp4.gi", + "pkg/aclib/gap/pcpgrp.gi", + "pkg/aclib/gap/betti.gi", + "pkg/aclib/gap/union.gi", + "pkg/aclib/gap/extend.gi", + "pkg/aclib/gap/crystgrp.gi", + "pkg/cryst/read.g", + "pkg/cryst/gap/common.gi", + "pkg/cryst/gap/hom.gi", + "pkg/cryst/gap/cryst.gi", + "pkg/cryst/gap/cryst2.gi", + "pkg/cryst/gap/fpgrp.gi", + "pkg/cryst/gap/zass.gi", + "pkg/cryst/gap/max.gi", + "pkg/cryst/gap/wyckoff.gi", + "pkg/cryst/gap/color.gi", + "pkg/cryst/gap/noxgap.gi", + "pkg/cryst/gap/pcpgrp.gi", + "pkg/cryst/gap/orbstab.gi", + "pkg/cryst/gap/equiv.gi", + "pkg/cryst/grp/spacegrp.grp", + "pkg/cryst/grp/spacegrp.gi", + "pkg/crystcat/read.g", + "pkg/crystcat/grp/crystcat.grp", + "pkg/crystcat/lib/crystcat.gi", + "pkg/crystcat/lib/normalizer.gi", + "pkg/polenta/read.g", + "pkg/polenta/lib/finite.gi", + "pkg/polenta/lib/basic.gi", + "pkg/polenta/lib/unipo.gi", + "pkg/polenta/lib/series.gi", + "pkg/polenta/lib/semi.gi", + "pkg/polenta/lib/ispoly.gi", + "pkg/polenta/lib/cpcs.gi", + "pkg/polenta/lib/present.gi", + "pkg/polenta/lib/isom.gi", + "pkg/polenta/lib/solvable.gi", + "pkg/polenta/exam/exam.gi", + "pkg/polenta/exam/test.gi", + "pkg/polenta/lib/subgroups.gi", + "pkg/polenta/lib/ispolyz.gi", + "pkg/resclasses/init.g", + "pkg/resclasses/lib/general.gd", + "pkg/resclasses/lib/z_pi.gd", + "pkg/resclasses/lib/resclass.gd", + "pkg/resclasses/lib/fixedrep.gd", + "pkg/resclasses/read.g", + "pkg/resclasses/lib/general.gi", + "pkg/resclasses/lib/resclaux.g", + "pkg/resclasses/lib/z_pi.gi", + "pkg/resclasses/lib/resclass.gi", + "pkg/resclasses/lib/fixedrep.gi", + "lib/obsolete.gi", + "pkg/4ti2interface/doc/manual.six", + "pkg/ace/doc/manual.six", + "pkg/aclib/doc/manual.six", + "pkg/agt/doc/manual.six", + "pkg/alco/doc/manual.six", + "pkg/alnuth/doc/manual.six", + "pkg/anupq/doc/manual.six", + "pkg/atlasrep/doc/manual.six", + "pkg/autodoc/doc/manual.six", + "pkg/automata/doc/manual.six", + "pkg/automgrp/doc/manual.six", + "pkg/autpgrp/doc/manual.six", + "pkg/browse/doc/manual.six", + "pkg/cap/doc/manual.six", + "pkg/caratinterface/doc/manual.six", + "pkg/cddinterface/doc/manual.six", + "pkg/circle/doc/manual.six", + "pkg/classicalmaximals/doc/manual.six", + "pkg/classicpres/doc/manual.six", + "pkg/cohomolo/doc/manual.six", + "pkg/congruence/doc/manual.six", + "pkg/corefreesub/doc/manual.six", + "pkg/corelg/doc/manual.six", + "pkg/crime/doc/manual.six", + "pkg/crisp/doc/manual.six", + "pkg/crypting/doc/manual.six", + "pkg/cryst/doc/manual.six", + "pkg/crystcat/doc/manual.six", + "pkg/ctbllib/doc/manual.six", + "pkg/ctbllib/doc2/manual.six", + "pkg/cubefree/doc/manual.six", + "pkg/curlinterface/doc/manual.six", + "pkg/cvec/doc/manual.six", + "pkg/datastructures/doc/manual.six", + "pkg/deepthought/doc/manual.six", + "pkg/design/doc/manual.six", + "pkg/difsets/doc/manual.six", + "pkg/digraphs/doc/manual.six", + "pkg/edim/doc/manual.six", + "pkg/example/doc/manual.six", + "pkg/examplesforhomalg/doc/manual.six", + "pkg/factint/doc/manual.six", + "pkg/ferret/doc/manual.six", + "pkg/fga/doc/manual.six", + "pkg/fining/doc/manual.six", + "pkg/float/doc/manual.six", + "pkg/format/doc/manual.six", + "pkg/forms/doc/manual.six", + "pkg/fplsa/doc/manual.six", + "pkg/fr/doc/manual.six", + "pkg/francy/doc/manual.six", + "pkg/fwtree/doc/manual.six", + "pkg/gapdoc/doc/manual.six", + "pkg/gapdoc/example/manual.six", + "pkg/gauss/doc/manual.six", + "pkg/gaussforhomalg/doc/manual.six", + "pkg/gbnp/doc/manual.six", + "pkg/generalizedmorphismsforcap/doc/manual.six", + "pkg/genss/doc/manual.six", + "pkg/gradedmodules/doc/manual.six", + "pkg/gradedringforhomalg/doc/manual.six", + "pkg/grape/doc/manual.six", + "pkg/groupoids/doc/manual.six", + "pkg/grpconst/doc/manual.six", + "pkg/guarana/doc/manual.six", + "pkg/guava/doc/manual.six", + "pkg/hap/doc/manual.six", + "pkg/hapcryst/doc/manual.six", + "pkg/hecke/doc/manual.six", + "pkg/help/doc/manual.six", + "pkg/homalg/doc/manual.six", + "pkg/homalgtocas/doc/manual.six", + "pkg/ibnp/doc/manual.six", + "pkg/idrel/doc/manual.six", + "pkg/images/doc/manual.six", + "pkg/inducereduce/doc/manual.six", + "pkg/intpic/doc/manual.six", + "pkg/io/doc/manual.six", + "pkg/io_forhomalg/doc/manual.six", + "pkg/irredsol/doc/manual.six", + "pkg/itc/doc/manual.six", + "pkg/json/doc/manual.six", + "pkg/jupyterkernel/doc/manual.six", + "pkg/jupyterviz/doc/manual.six", + "pkg/kan/doc/manual.six", + "pkg/kbmag/doc/manual.six", + "pkg/laguna/doc/manual.six", + "pkg/liealgdb/doc/manual.six", + "pkg/liepring/doc/manual.six", + "pkg/liering/doc/manual.six", + "pkg/linearalgebraforcap/doc/manual.six", + "pkg/lins/doc/manual.six", + "pkg/localizeringforhomalg/doc/manual.six", + "pkg/localnr/doc/manual.six", + "pkg/loops/doc/manual.six", + "pkg/lpres/doc/manual.six", + "pkg/majoranaalgebras/doc/manual.six", + "pkg/mapclass/doc/manual.six", + "pkg/matgrp/doc/manual.six", + "pkg/matricesforhomalg/doc/manual.six", + "pkg/modisom/doc/manual.six", + "pkg/modulargroup/doc/manual.six", + "pkg/modulepresentationsforcap/doc/manual.six", + "pkg/modules/doc/manual.six", + "pkg/monoidalcategories/doc/manual.six", + "pkg/nconvex/doc/manual.six", + "pkg/nilmat/doc/manual.six", + "pkg/nock/doc/manual.six", + "pkg/nofoma/doc/manual.six", + "pkg/normalizinterface/doc/manual.six", + "pkg/nq/doc/manual.six", + "pkg/numericalsgps/doc/manual.six", + "pkg/openmath/doc/manual.six", + "pkg/orb/doc/manual.six", + "pkg/origami/doc/manual.six", + "pkg/packagemaker/doc/manual.six", + "pkg/packagemanager/doc/manual.six", + "pkg/patternclass/doc/manual.six", + "pkg/permut/doc/manual.six", + "pkg/polenta/doc/manual.six", + "pkg/polycyclic/doc/manual.six", + "pkg/polymaking/doc/manual.six", + "pkg/primgrp/doc/manual.six", + "pkg/profiling/doc/manual.six", + "pkg/qdistrnd/doc/manual.six", + "pkg/qpa/doc/manual.six", + "pkg/quagroup/doc/manual.six", + "pkg/radiroot/doc/manual.six", + "pkg/rcwa/doc/manual.six", + "pkg/rds/doc/manual.six", + "pkg/recog/doc/manual.six", + "pkg/repndecomp/doc/manual.six", + "pkg/repsn/doc/manual.six", + "pkg/resclasses/doc/manual.six", + "pkg/ringsforhomalg/doc/manual.six", + "pkg/sco/doc/manual.six", + "pkg/scscp/doc/manual.six", + "pkg/semigroups/doc/manual.six", + "pkg/sglppow/doc/manual.six", + "pkg/sgpviz/doc/manual.six", + "pkg/simpcomp/doc/manual.six", + "pkg/singular/doc/manual.six", + "pkg/sl2reps/doc/manual.six", + "pkg/sla/doc/manual.six", + "pkg/smallantimagmas/doc/manual.six", + "pkg/smallclassnr/doc/manual.six", + "pkg/smallgrp/doc/manual.six", + "pkg/smallsemi/doc/manual.six", + "pkg/sonata/doc/ref/manual.six", + "pkg/sonata/doc/tut/manual.six", + "pkg/sophus/doc/manual.six", + "pkg/sotgrps/doc/manual.six", + "pkg/spinsym/doc/manual.six", + "pkg/standardff/doc/manual.six", + "pkg/symbcompcc/doc/manual.six", + "pkg/thelma/doc/manual.six", + "pkg/tomlib/doc/manual.six", + "pkg/toolsforhomalg/doc/manual.six", + "pkg/toric/doc/manual.six", + "pkg/transgrp/doc/manual.six", + "pkg/twistedconjugacy/doc/manual.six", + "pkg/typeset/doc/manual.six", + "pkg/ugaly/doc/manual.six", + "pkg/unipot/doc/manual.six", + "pkg/unitlib/doc/manual.six", + "pkg/utils/doc/manual.six", + "pkg/uuid/doc/manual.six", + "pkg/walrus/doc/manual.six", + "pkg/wedderga/doc/manual.six", + "pkg/wpe/doc/manual.six", + "pkg/xgap/doc/manual.six", + "pkg/xmod/doc/manual.six", + "pkg/xmodalg/doc/manual.six", + "pkg/yangbaxter/doc/manual.six", + "pkg/zeromqinterface/doc/manual.six" +] diff --git a/etc/emscripten/web-template/gap-fs.js b/etc/emscripten/web-template/gap-fs.js index f3a1467d42..ca8ea4f23d 100644 --- a/etc/emscripten/web-template/gap-fs.js +++ b/etc/emscripten/web-template/gap-fs.js @@ -1,3 +1,29 @@ +// Instrument fetch and XMLHttpRequest so the page can collect the list of +// URLs the worker actually requests, for rebuilding startup_manifest.json +// without scraping the browser network panel. Each unique URL is posted +// to the main thread as { type: "gap-fetched", url: ... }. +(function instrumentFetches() { + const seen = new Set(); + const report = (raw) => { + if (typeof raw !== "string") return; + if (seen.has(raw)) return; + seen.add(raw); + self.postMessage({ type: "gap-fetched", url: raw }); + }; + + const origFetch = self.fetch; + self.fetch = function(input, init) { + report(typeof input === "string" ? input : input && input.url); + return origFetch.apply(this, arguments); + }; + + const origOpen = XMLHttpRequest.prototype.open; + XMLHttpRequest.prototype.open = function(method, url) { + report(url); + return origOpen.apply(this, arguments); + }; +})(); + self.Module = self.Module || {}; self.Module.preRun = self.Module.preRun || []; @@ -43,8 +69,12 @@ self.Module.preRun.push(function() { if (p.startsWith('/')) p = p.substring(1); startupSet.add(p); }); + } else { + console.info("startup_manifest.json not present; falling back to fully lazy loading"); } - } catch (e) {} + } catch (e) { + console.warn("Failed to load startup_manifest.json:", e); + } var fetchPromises = fileList.map(async function(appPath) { var fetchRelativePath = appPath.split('/').map(encodeURIComponent).join('/'); @@ -58,16 +88,15 @@ self.Module.preRun.push(function() { FS.stat(idbfsPath); FS.writeFile(finalAppPath, FS.readFile(idbfsPath)); } catch (e) { - try { - const response = await fetch(fetchPath); - if (response.ok) { - const buffer = await response.arrayBuffer(); - const data = new Uint8Array(buffer); - FS.writeFile(finalAppPath, data); - FS.writeFile(idbfsPath, data); - needsSave = true; - } - } catch (fetchErr) {} + const response = await fetch(fetchPath); + if (!response.ok) { + throw new Error("Failed to fetch startup file " + fetchPath + ": " + response.status); + } + const buffer = await response.arrayBuffer(); + const data = new Uint8Array(buffer); + FS.writeFile(finalAppPath, data); + FS.writeFile(idbfsPath, data); + needsSave = true; } } else { var parts = appPath.split('/'); diff --git a/etc/emscripten/web-template/index.html b/etc/emscripten/web-template/index.html index b51df45fb8..d5f1bec759 100755 --- a/etc/emscripten/web-template/index.html +++ b/etc/emscripten/web-template/index.html @@ -1,22 +1,185 @@ - + + - gap-wasm + + + GAP in the browser + -
+
+

GAP in the browser

+

+ A WebAssembly build of GAP + running entirely in your browser — useful for trying things out + without installing. Not all packages work, working memory is + capped, and performance is reduced compared to a native build. + For real work, install GAP from + www.gap-system.org. +

+
+ +
+ What is this? · Licensing +

+ GAP is a system for + computational discrete algebra, with particular emphasis on + computational group theory. This page is a self-contained + WebAssembly build, served as a static site and run inside a + Web Worker; you interact with it through an + xterm-pty + terminal in the page below. +

+

+ To get started, try 1+1;, + Factorial(20);, or SymmetricGroup(5);. + The full GAP + manuals apply, with two caveats: some packages won't load + (anything that needs a native compiler or system library), and + anything that wants the local filesystem won't work. +

+

+ Files downloaded on first visit are cached in your browser's + IndexedDB, so subsequent visits start much faster. Clear the + site data to reset the cache. +

+

+ GAP is free software, distributed under the + GNU General Public License (version 2 or + later). See the copyright notice for + the full statement. +

+
+ +
+ Loading GAP… The first visit downloads several tens of megabytes; + subsequent visits are cached in your browser and load much faster. +
+ +
+ This page needs SharedArrayBuffer, which is only + available when the page is served with the headers + Cross-Origin-Opener-Policy: same-origin and + Cross-Origin-Embedder-Policy: require-corp. The + bundled service worker handles this on hosts where you can't set + headers (e.g. GitHub Pages); for local hosting use + etc/emscripten/serve.py. +
+ +
+
+
+ + + diff --git a/src/gasman.c b/src/gasman.c index 6712ebec79..7a616d6eb6 100644 --- a/src/gasman.c +++ b/src/gasman.c @@ -129,7 +129,7 @@ #include #include -#ifdef EMSCRIPTEN +#ifdef __EMSCRIPTEN__ #include #endif @@ -1957,7 +1957,7 @@ static NOINLINE void GenStackFuncBags(void) DisableMarkBagValidation = 1; #endif -#ifdef EMSCRIPTEN +#ifdef __EMSCRIPTEN__ emscripten_scan_stack(ScanRange); emscripten_scan_registers(ScanRange); // The standard scanning may not be required with From 9de742a8c0804aa45fbefa0f426caf05b5f27adb Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 1 Jun 2026 13:41:50 +0200 Subject: [PATCH 21/50] Update COPYRIGHT --- COPYRIGHT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYRIGHT b/COPYRIGHT index 6a58d3bd37..b144b05166 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with GAP; if not, see . -Copyright (C) 1988-2025 by its authors, which include: +Copyright (C) 1988-2026 by its authors, which include: * Ákos Seress * Alex Wegner From cb25fa70967f9fc7390e50eb8ae64c3fbfbb0afe Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 1 Jun 2026 22:34:43 +0200 Subject: [PATCH 22/50] Fix RingGeneralMappingByImages for non-SCRing (#6418) A filter was computed but not used. The filter that was used instead always implied IsSCRingGeneralMappingByImagesDefaultRep which is too broad. As a result, inappropriate methods were applied to some ring homomorphisms. Also add an example for using RingByStructureConstants. --- lib/ringhom.gi | 7 +------ lib/ringsc.gd | 8 ++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/ringhom.gi b/lib/ringhom.gi index 6377e0ceec..887a991704 100644 --- a/lib/ringhom.gi +++ b/lib/ringhom.gi @@ -52,12 +52,7 @@ function( S, R, gens, imgs ) fi; # Make the general mapping. - map:= Objectify( TypeOfDefaultGeneralMapping( S, R, - IsSPGeneralMapping - and IsRingGeneralMapping - and IsSCRingGeneralMappingByImagesDefaultRep ), - rec( - ) ); + map:= Objectify( TypeOfDefaultGeneralMapping( S, R, filter ), rec( ) ); SetMappingGeneratorsImages(map,[Immutable(gens),Immutable(imgs)]); # return the general mapping diff --git a/lib/ringsc.gd b/lib/ringsc.gd index bd2116bcd7..9871317d71 100644 --- a/lib/ringsc.gd +++ b/lib/ringsc.gd @@ -47,6 +47,14 @@ DeclareSynonym("IsSubringSCRing",IsRing and IsSCRingObjCollection); ## it can be either a string name ## (then name1, name2 etc. are chosen) ## or a list of strings which are then chosen. +## T:=EmptySCTable( 1, 0 );; +## gap> SetEntrySCTable( T, 1, 1, [ 1, 1 ] ); +## gap> R:=RingByStructureConstants([9], T); # Z/9Z +## +## gap> Elements(R); +## [ 0*r.1, r.1, 2*r.1, 3*r.1, 4*r.1, 5*r.1, 6*r.1, 7*r.1, -r.1 ] +## ]]> ##
## ## <#/GAPDoc> From ac1d8e95823dd3039ab3c6655f76e9e8e4833aa4 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 1 Jun 2026 22:41:56 +0200 Subject: [PATCH 23/50] Update CHANGES.md --- CHANGES.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 48c602ec6b..a2e9050afa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # GAP - history of changes -## GAP 4.16.0 (May 2026) +## GAP 4.16.0 (June 2026) The following gives an overview of the changes compared to the previous release. This list is not complete, many more internal or minor changes @@ -91,6 +91,7 @@ affect some users directly. ### Fixed bugs that could lead to unexpected errors +- [#6418](https://github.com/gap-system/gap/pull/6418) Fix `RingGeneralMappingByImages` for non-SCRing - [#6196](https://github.com/gap-system/gap/pull/6196) Fix an inconsistency problem in `IsFinite` for matrix groups over cycl. fields. - [#6159](https://github.com/gap-system/gap/pull/6159) Fix a potential error message about data types when computing extensions @@ -116,10 +117,10 @@ affect some users directly. #### Updated packages redistributed with GAP -The GAP 4.16.0 distribution contains 172 packages, of which 68 have been +The GAP 4.16.0 distribution contains 172 packages, of which 69 have been updated since GAP 4.15.1. The full list of updated packages is given below: -- [**4ti2Interface**](https://homalg-project.github.io/pkg/4ti2Interface): 2024.11-01 -> 2025.12-01 +- [**4ti2Interface**](https://homalg-project.github.io/pkg/4ti2Interface): 2024.11-01 -> 2026.05-01 - [**Alnuth**](https://gap-packages.github.io/alnuth): 3.2.1 -> 4.0.0 - [**ANUPQ**](https://gap-packages.github.io/anupq/): 3.3.2 -> 3.3.3 - [**AtlasRep**](https://www.math.rwth-aachen.de/~Thomas.Breuer/atlasrep): 2.1.9 -> 2.1.11 @@ -137,6 +138,7 @@ updated since GAP 4.15.1. The full list of updated packages is given below: - [**Digraphs**](https://digraphs.github.io/Digraphs): 1.13.1 -> 1.14.0 - [**ExamplesForHomalg**](https://homalg-project.github.io/pkg/ExamplesForHomalg): 2023.10-01 -> 2025.12-01 - [**ferret**](https://gap-packages.github.io/ferret/): 1.0.15 -> 1.0.16 +- [**float**](https://gap-packages.github.io/float/): 1.0.9 -> 1.0.10 - [**FORMAT**](https://gap-packages.github.io/format/): 1.4.4 -> 1.4.5 - [**Forms**](https://gap-packages.github.io/forms): 1.2.13 -> 1.3.0 - [**FPLSA**](https://gap-packages.github.io/FPLSA): 1.2.7 -> 1.2.8 @@ -157,7 +159,7 @@ updated since GAP 4.15.1. The full list of updated packages is given below: - [**IO_ForHomalg**](https://homalg-project.github.io/pkg/IO_ForHomalg): 2023.02-04 -> 2025.12-01 - [**json**](https://gap-packages.github.io/json/): 2.2.3 -> 2.4.0 - [**LinearAlgebraForCAP**](https://homalg-project.github.io/pkg/LinearAlgebraForCAP): 2025.09-01 -> 2026.05-04 -- [**LocalizeRingForHomalg**](https://homalg-project.github.io/pkg/LocalizeRingForHomalg): 2023.10-01 -> 2026.04-01 +- [**LocalizeRingForHomalg**](https://homalg-project.github.io/pkg/LocalizeRingForHomalg): 2023.10-01 -> 2026.05-01 - [**lpres**](https://gap-packages.github.io/lpres): 1.1.1 -> 1.1.2 - [**matgrp**](https://www.math.colostate.edu/~hulpke/matgrp): 0.72 -> 0.73 - [**MatricesForHomalg**](https://homalg-project.github.io/pkg/MatricesForHomalg): 2025.09-01 -> 2026.04-01 @@ -174,7 +176,7 @@ updated since GAP 4.15.1. The full list of updated packages is given below: - [**qpa**](https://gap-packages.github.io/qpa): 1.35 -> 1.37 - [**RCWA**](https://gap-packages.github.io/rcwa/): 4.8.0 -> 4.9.0 - [**recog**](https://gap-packages.github.io/recog): 1.4.4 -> 1.5.1 -- [**RingsForHomalg**](https://homalg-project.github.io/pkg/RingsForHomalg): 2024.11-02 -> 2025.12-01 +- [**RingsForHomalg**](https://homalg-project.github.io/pkg/RingsForHomalg): 2024.11-02 -> 2026.05-01 - [**SCO**](https://homalg-project.github.io/pkg/SCO): 2023.08-01 -> 2025.12-01 - [**Semigroups**](https://semigroups.github.io/Semigroups): 5.5.4 -> 5.6.3 - [**singular**](https://gap-packages.github.io/singular/): 2025.08.26 -> 2026.05.05 From 9490b09e1c0dc2b5adb144126c6d693dfb8e7bde Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 2 Jun 2026 00:03:15 +0200 Subject: [PATCH 24/50] Normalize release archive permissions (#6420) Remove group and other write bits before creating release archives. Keep package contents readable while preserving and normalizing executable bits. Co-authored-by: Codex --- .github/workflows/release.yml | 2 +- Makefile.rules | 7 ++++-- dev/releases/make_archives.py | 11 +++++---- dev/releases/test_archive_utils.py | 39 ++++++++++++++++++++++++++++++ dev/releases/utils.py | 24 ++++++++++++++++++ 5 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 dev/releases/test_archive_utils.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 36867a212c..eb4ce3c91b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: # run: python -m mypy --disallow-untyped-calls --disallow-untyped-defs dev/releases/*.py - name: "Run tests" - run: cd dev/releases && python -m pytest test_release_notes.py + run: cd dev/releases && python -m pytest unix: name: "Create Unix archives and data" diff --git a/Makefile.rules b/Makefile.rules index ffe22eb1ba..e2512739ec 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -24,8 +24,11 @@ default: all ######################################################################## # Developer helper targets ######################################################################## -test_release_notes: - cd dev/releases && python3 -m pytest test_release_notes.py +test_release_scripts: + cd dev/releases && python3 -m pytest +.PHONY: test_release_scripts + +test_release_notes: test_release_scripts .PHONY: test_release_notes diff --git a/dev/releases/make_archives.py b/dev/releases/make_archives.py index 5b06f8e0f3..33fe219c1b 100755 --- a/dev/releases/make_archives.py +++ b/dev/releases/make_archives.py @@ -29,6 +29,7 @@ from utils import ( download_with_sha256, error, + normalize_archive_permissions, notice, patchfile, verify_command_available, @@ -211,14 +212,11 @@ def run_with_log(args: List[str], name: str, msg: Optional[str] = None) -> None: notice("Extracting package tarballs") with tarfile.open(tmpdir + "/" + all_packages_tarball) as tar: tar.extractall(path="pkg") - # for some reason pkg sometimes ends up with permission 0700 so - # we make sure to fix that here - subprocess.run(["chmod", "0755", "pkg"], check=True) - # ensure all files are at readable by everyone - subprocess.run(["chmod", "-R", "a+r", "."], check=True) with tarfile.open(tmpdir + "/" + req_packages_tarball) as tar: tar.extractall(path=tmpdir + "/" + req_packages) + notice("Normalizing permissions in required packages") + normalize_archive_permissions(tmpdir + "/" + req_packages) notice("Building GAP's manuals") run_with_log(["make", "doc"], "gapdoc", "building the manuals") @@ -278,6 +276,9 @@ def run_with_log(args: List[str], name: str, msg: Optional[str] = None) -> None: notice("Removing generated files we don't want to distribute") run_with_log(["make", "distclean"], "make-distclean", "make distclean") + notice("Normalizing permissions in GAP archive tree") + normalize_archive_permissions(".") + # Create an archive in the current directory with shutil.make_archive, and # record the filename of the new archive in . diff --git a/dev/releases/test_archive_utils.py b/dev/releases/test_archive_utils.py new file mode 100644 index 0000000000..ef05608a4a --- /dev/null +++ b/dev/releases/test_archive_utils.py @@ -0,0 +1,39 @@ +import os +import stat + +from utils import normalize_archive_permissions + + +def mode(path): + return stat.S_IMODE(os.stat(path).st_mode) + + +def test_normalize_archive_permissions_removes_group_and_other_write_bits(tmp_path): + package_dir = tmp_path / "pkg" + package_dir.mkdir() + private_dir = package_dir / "private" + private_dir.mkdir() + unreadable_dir = package_dir / "unreadable" + unreadable_dir.mkdir() + world_writable_file = package_dir / "data.g" + world_writable_file.write_text("data", encoding="utf-8") + executable_file = package_dir / "script.sh" + executable_file.write_text("#!/bin/sh\n", encoding="utf-8") + oddly_executable_file = package_dir / "odd.g" + oddly_executable_file.write_text("data", encoding="utf-8") + + os.chmod(package_dir, 0o777) + os.chmod(private_dir, 0o700) + os.chmod(unreadable_dir, 0o600) + os.chmod(world_writable_file, 0o666) + os.chmod(executable_file, 0o777) + os.chmod(oddly_executable_file, 0o654) + + normalize_archive_permissions(tmp_path) + + assert mode(package_dir) == 0o755 + assert mode(private_dir) == 0o755 + assert mode(unreadable_dir) == 0o755 + assert mode(world_writable_file) == 0o644 + assert mode(executable_file) == 0o755 + assert mode(oddly_executable_file) == 0o644 diff --git a/dev/releases/utils.py b/dev/releases/utils.py index e38c0ba72f..c14420f7c6 100644 --- a/dev/releases/utils.py +++ b/dev/releases/utils.py @@ -12,6 +12,7 @@ import os import re import shutil +import stat import subprocess import sys from typing import Iterator, NoReturn @@ -74,6 +75,29 @@ def working_directory(path: str) -> Iterator[None]: os.chdir(prev_cwd) +def normalize_archive_permissions(root: str) -> None: + """Apply the archive permission policy recursively below ``root``. + + This mirrors ``chmod -R g-w,o-w,g+r,o+r`` for regular files and also makes + directories searchable by group and others. File executable bits are + normalized from the owner's executable bit, so scripts remain executable + without making ordinary data files executable. Symlinks are left untouched. + """ + for dirpath, dirnames, filenames in os.walk(root): + for name in [dirpath, *dirnames, *filenames]: + path = os.path.join(dirpath, name) if name != dirpath else dirpath + if os.path.islink(path): + continue + mode = stat.S_IMODE(os.stat(path).st_mode) + mode |= stat.S_IRGRP | stat.S_IROTH + mode &= ~(stat.S_IWGRP | stat.S_IWOTH) + if os.path.isdir(path) or mode & stat.S_IXUSR: + mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH + else: + mode &= ~(stat.S_IXGRP | stat.S_IXOTH) + os.chmod(path, mode) + + # compute the sha256 checksum of a file def sha256file(path: str) -> str: h = hashlib.sha256() From 8ae5f61d6d6773e6f2ec4923fec5411674920334 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 5 Jun 2026 17:51:53 +0200 Subject: [PATCH 25/50] julia-gc: introduce DISABLE_STACK_SCAN (#6421) Useful for debugging, and future work on alternative GC integration. --- src/julia_gc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/julia_gc.c b/src/julia_gc.c index 568b567b1e..f04d51e918 100644 --- a/src/julia_gc.c +++ b/src/julia_gc.c @@ -67,6 +67,8 @@ // should not be enabled by default. // #define VALIDATE_MARKING +// if DISABLE_STACK_SCAN is defined, all stack scanning is disabled +// #define DISABLE_STACK_SCAN // if USE_GAP_INSIDE_JULIA is defined, then some hacks which are needed // to make julia-inside-gap work are disabled. This is mainly for use in @@ -166,13 +168,15 @@ static jl_datatype_t * DatatypeGapObj; static jl_datatype_t * DatatypeSmallBag; static jl_datatype_t * DatatypeLargeBag; +#ifndef DISABLE_STACK_SCAN static jl_task_t * ScannedRootTask; +#endif static size_t MaxPoolObjSize; static int FullGC; static UInt StartTime, TotalTime; -#if !defined(USE_GAP_INSIDE_JULIA) +#if !defined(USE_GAP_INSIDE_JULIA) && !defined(DISABLE_STACK_SCAN) static Bag * GapStackBottom; static jl_task_t * RootTaskOfMainThread; #endif @@ -184,8 +188,10 @@ static TNumFreeFuncBags TabFreeFuncBags[NUM_TYPES]; // HACK: TabMarkFuncBags is accessed by MarkCopyingSubBags in src/objects.c TNumMarkFuncBags TabMarkFuncBags[NUM_TYPES]; +#ifndef DISABLE_STACK_SCAN static TaskInfoTree * TaskStacks; static pthread_mutex_t TaskStacksMutex; +#endif // // global bags @@ -325,6 +331,8 @@ void MarkJuliaWeakRef(void * p, void * ref) } +#ifndef DISABLE_STACK_SCAN + // Overview of conservative stack scanning // // A key aspect of conservative marking is that we need to determine whether a @@ -627,6 +635,8 @@ static void GapTaskScanner(jl_task_t * task, int root_task) } } +#endif // DISABLE_STACK_SCAN + // Julia callback static void PreGCHook(int full) { @@ -653,7 +663,9 @@ static void PreGCHook(int full) // Julia callback static void PostGCHook(int full) { +#ifndef DISABLE_STACK_SCAN ScannedRootTask = 0; +#endif TotalTime += SyTime() - StartTime; #ifdef COLLECT_MARK_CACHE_STATS /* printf("\n>>>Attempts: %ld\nHit rate: %lf\nCollision rate: %lf\n", @@ -758,6 +770,7 @@ void GAP_InitJuliaMemoryInterface(jl_module_t * module, jl_init(); #endif +#ifndef DISABLE_STACK_SCAN if (jl_n_gcthreads > 1) pthread_mutex_init(&TaskStacksMutex, NULL); TaskStacks = TaskInfoTreeMake(); @@ -766,6 +779,7 @@ void GAP_InitJuliaMemoryInterface(jl_module_t * module, // TLS and thus need to be installed after initialization. jl_gc_set_cb_root_scanner(GapRootScanner, 1); jl_gc_set_cb_task_scanner(GapTaskScanner, 1); +#endif jl_gc_set_cb_pre_gc(PreGCHook, 1); jl_gc_set_cb_post_gc(PostGCHook, 1); // jl_gc_enable(0); /// DEBUGGING @@ -816,7 +830,7 @@ void InitBags(UInt initial_size, Bag * stack_bottom) { TotalTime = 0; -#if !defined(USE_GAP_INSIDE_JULIA) +#if !defined(USE_GAP_INSIDE_JULIA) && !defined(DISABLE_STACK_SCAN) // initialize Julia memory interface. Note that this is only necessary // when we run standalone. In contrast, when GAP is loaded from GAP.jl // then GAP.jl invokes `GAP_InitJuliaMemoryInterface` at an appropriate From 2485080438691d962fcd15b341077c7b80a1fb39 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 6 Jun 2026 08:35:18 +0200 Subject: [PATCH 26/50] Miscellaneous kernel tweaks (#6422) * kernel: fix typo in src/gasman.c * CREATE_PTY_IOSTREAM: require args as plist * ExecuteProcess: require args as plist * kernel: change AUTO to require plain list --- lib/streams.gi | 3 +++ src/gasman.c | 4 ++-- src/gvars.c | 11 ++++++++--- src/iostream.c | 12 +++++++----- tst/testinstall/kernel/streams.tst | 2 +- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/streams.gi b/lib/streams.gi index 5f0f44aa73..f105a1c635 100644 --- a/lib/streams.gi +++ b/lib/streams.gi @@ -1367,6 +1367,9 @@ InstallGlobalFunction( InputOutputLocalProcess, Error("Can't handle new rep for directories"); fi; dirname := cdir![1]; + if not IsPlistRep(argts) then + argts := PlainListCopy(argts); + fi; ptynum := CREATE_PTY_IOSTREAM( dirname, exec, argts); if ptynum = fail then return fail; diff --git a/src/gasman.c b/src/gasman.c index 7a616d6eb6..0575a384b7 100644 --- a/src/gasman.c +++ b/src/gasman.c @@ -2026,7 +2026,7 @@ static UInt CollectBags_Mark(UInt FullBags) // For old bags, we invoke the marking function for bags with the // given TNUM. // Young bags normally are never put onto the changed list, because - // CHANGED_BAGS ignores young bags. However, it can happen if we + // CHANGED_BAG ignores young bags. However, it can happen if we // resize an old bag and it needs to be moved as a result, or if we // swap the masterpointers of an old and a young bag. In that case, // we must be careful to not collect the young bag (which was old @@ -2566,7 +2566,7 @@ void CheckMasterPointers( void ) // we must make sure to mark the new bag2 as changed, too (and vice-versa). // // 2. Both bags are young. Then they typically will not be on the list of -// changed bags, as CHANGED_BAGS just skips them. +// changed bags, as CHANGED_BAG just skips them. // However, while CHANGED_BAG will never put a young bag on the list of // changed bags, young bags can still be put on the ChangedBags list in // step 3, so we need to do something similar as in step 1. diff --git a/src/gvars.c b/src/gvars.c index e705d8e885..5232cd2d21 100644 --- a/src/gvars.c +++ b/src/gvars.c @@ -832,19 +832,24 @@ static Obj FuncAUTO(Obj self, Obj args) UInt gvar; // one global variable UInt i; // loop variable + RequirePlainList(SELF_NAME, args); + RequireDenseList(SELF_NAME, args); + RequireArgumentCondition(SELF_NAME, args, LEN_PLIST(args) >= 2, + "must be a list of length at least 2"); + // get and check the function - func = ELM_LIST( args, 1 ); + func = ELM_PLIST( args, 1 ); RequireFunction(SELF_NAME, func); // get the argument - arg = ELM_LIST( args, 2 ); + arg = ELM_PLIST( args, 2 ); // make the list of function and argument list = NewPlistFromArgs(func, arg); // make the global variables automatic for ( i = 3; i <= LEN_LIST(args); i++ ) { - name = ELM_LIST( args, i ); + name = ELM_PLIST( args, i ); RequireStringRep(SELF_NAME, name); gvar = GVarName( CONST_CSTR_STRING(name) ); SET_ELM_GVAR_LIST( ValGVars, gvar, 0 ); diff --git a/src/iostream.c b/src/iostream.c index c108389724..3773f4b3a3 100644 --- a/src/iostream.c +++ b/src/iostream.c @@ -30,6 +30,7 @@ #include "io.h" #include "lists.h" #include "modules.h" +#include "plist.h" #include "stringobj.h" #include "sysenv.h" #include "sysfiles.h" @@ -858,13 +859,14 @@ static Obj FuncCREATE_PTY_IOSTREAM(Obj self, Obj dir, Obj prog, Obj args) Char * argv[MAX_ARGS + 2]; UInt i, len; Int pty; - len = LEN_LIST(args); + RequirePlainList(SELF_NAME, args); + len = LEN_PLIST(args); if (len > MAX_ARGS) ErrorQuit("Too many arguments", 0, 0); ConvString(dir); ConvString(prog); for (i = 1; i <= len; i++) { - allargs[i] = ELM_LIST(args, i); + allargs[i] = ELM_PLIST(args, i); ConvString(allargs[i]); } // From here we cannot afford to have a garbage collection @@ -1098,13 +1100,13 @@ FuncExecuteProcess(Obj self, Obj dir, Obj prg, Obj in, Obj out, Obj args) RequireStringRep(SELF_NAME, prg); Int iin = GetSmallInt(SELF_NAME, in); Int iout = GetSmallInt(SELF_NAME, out); - RequireSmallList(SELF_NAME, args); + RequirePlainList(SELF_NAME, args); // create an argument array - for (i = 1; i <= LEN_LIST(args); i++) { + for (i = 1; i <= LEN_PLIST(args); i++) { if (i == 1023) break; - tmp = ELM_LIST(args, i); + tmp = ELM_PLIST(args, i); RequireStringRep(SELF_NAME, tmp); ExecArgs[i] = tmp; } diff --git a/tst/testinstall/kernel/streams.tst b/tst/testinstall/kernel/streams.tst index ebf5349ae6..12a3859cf5 100644 --- a/tst/testinstall/kernel/streams.tst +++ b/tst/testinstall/kernel/streams.tst @@ -293,7 +293,7 @@ Error, ExecuteProcess: must be a small integer (not the value 'fail') gap> ExecuteProcess("","",0,fail,fail); Error, ExecuteProcess: must be a small integer (not the value 'fail') gap> ExecuteProcess("","",0,0,fail); -Error, ExecuteProcess: must be a small list (not the value 'fail') +Error, ExecuteProcess: must be a plain list (not the value 'fail') gap> ExecuteProcess("","",0,0,[1]); Error, ExecuteProcess: must be a string (not the integer 1) From 77f8ab0b714aef357c2fdfcefba2127ba4fe3b2b Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 6 Jun 2026 13:06:11 +0200 Subject: [PATCH 27/50] More kernel tweaks (#6428) * kernel: drop unused return value of UseTmpPerm * kernel: use BOOL in more places * kernel: init buffer with memset * kernel: use size_t in some places * kernel: explain certain uses of 'extern inline' * kernel: update some comments --- src/code.c | 1 + src/collectors.cc | 25 ++++++------- src/cyclotom.c | 1 + src/exprs.c | 1 + src/funcs.c | 1 + src/gaptime.c | 8 ++--- src/gvars.c | 16 ++++----- src/io.c | 2 +- src/lists.c | 56 ++++++++++++++--------------- src/main.c | 3 +- src/objcftl.c | 1 + src/objset.c | 8 ++--- src/opers.cc | 25 ++++++------- src/permutat.cc | 3 +- src/plist.c | 92 +++++++++++++++++++++++------------------------ src/profile.c | 2 +- src/read.c | 10 +++--- src/records.c | 2 +- src/scanner.c | 2 +- src/sortbase.h | 9 ++--- src/sysfiles.c | 24 ++++++------- src/sysstr.h | 13 +++---- src/tietze.c | 34 +++++++++--------- src/trans.cc | 13 +++---- src/weakptr.c | 4 +-- 25 files changed, 183 insertions(+), 173 deletions(-) diff --git a/src/code.c b/src/code.c index 5ff2315c98..40268f9de8 100644 --- a/src/code.c +++ b/src/code.c @@ -57,6 +57,7 @@ DECL_MODULE_STATE Int CountExpr; static ModuleStateOffset CodeStateOffset = -1; +// for debugging from GDB / lldb, we mark this as extern inline extern inline struct CodeModuleState * CShelper(void) { return (struct CodeModuleState *)StateSlotsAtOffset(CodeStateOffset); diff --git a/src/collectors.cc b/src/collectors.cc index 3a8f37b314..c3561ea8db 100644 --- a/src/collectors.cc +++ b/src/collectors.cc @@ -63,6 +63,7 @@ DECL_MODULE_STATE UInt SC_MAX_STACK_SIZE; static ModuleStateOffset CollectorsStateOffset = -1; +// for debugging from GDB / lldb, we mark this as extern inline extern inline struct CollectorsState_ * CollectorsState(void) { return (struct CollectorsState_ *)StateSlotsAtOffset(CollectorsStateOffset); @@ -380,7 +381,7 @@ static Int SingleCollectWord(Obj sc, Obj vv, Obj w) Obj tmp; // temporary obj for power - Int resized = 0;// indicates whether a Resize() happened + BOOL resized = FALSE;// indicates whether a Resize() happened // is the first non-trivial entry in start = SC_NUMBER_RWS_GENERATORS(sc); @@ -421,23 +422,23 @@ static Int SingleCollectWord(Obj sc, Obj vv, Obj w) const UInt desiredStackSize = sizeof(Obj) * (max + 2); if ( SIZE_OBJ(vnw) < desiredStackSize ) { ResizeBag( vnw, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vlw) < desiredStackSize ) { ResizeBag( vlw, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vpw) < desiredStackSize ) { ResizeBag( vpw, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vew) < desiredStackSize ) { ResizeBag( vew, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vge) < desiredStackSize ) { ResizeBag( vge, desiredStackSize ); - resized = 1; + resized = TRUE; } if( resized ) return -1; @@ -891,7 +892,7 @@ static Int CombiCollectWord(Obj sc, Obj vv, Obj w) Obj tmp; // temporary obj for power - Int resized = 0;// indicates whether a Resize() happened + BOOL resized = FALSE;// indicates whether a Resize() happened // if is the identity return now if ( NPAIRS_WORD(w) == 0 ) { @@ -929,23 +930,23 @@ static Int CombiCollectWord(Obj sc, Obj vv, Obj w) const UInt desiredStackSize = sizeof(Obj) * (max + 2); if ( SIZE_OBJ(vnw) < desiredStackSize ) { ResizeBag( vnw, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vlw) < desiredStackSize ) { ResizeBag( vlw, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vpw) < desiredStackSize ) { ResizeBag( vpw, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vew) < desiredStackSize ) { ResizeBag( vew, desiredStackSize ); - resized = 1; + resized = TRUE; } if ( SIZE_OBJ(vge) < desiredStackSize ) { ResizeBag( vge, desiredStackSize ); - resized = 1; + resized = TRUE; } if( resized ) return -1; diff --git a/src/cyclotom.c b/src/cyclotom.c index 3025530f94..e626946916 100644 --- a/src/cyclotom.c +++ b/src/cyclotom.c @@ -185,6 +185,7 @@ DECL_MODULE_STATE UInt LastNCyc; #ifdef HPCGAP }; // end of struct CycModuleState +// for debugging from GDB / lldb, we mark this as extern inline extern inline struct CycModuleState *CycState(void) { return (struct CycModuleState *)StateSlotsAtOffset(CycStateOffset); diff --git a/src/exprs.c b/src/exprs.c index 2c234633ad..840d2d709b 100644 --- a/src/exprs.c +++ b/src/exprs.c @@ -66,6 +66,7 @@ DECL_MODULE_STATE UInt OldPrintPrecedence; static ModuleStateOffset ExprsStateOffset = -1; +// for debugging from GDB / lldb, we mark this as extern inline extern inline struct ExprsState * ExprsState(void) { return (struct ExprsState *)StateSlotsAtOffset(ExprsStateOffset); diff --git a/src/funcs.c b/src/funcs.c index 62919177f5..16acf1fb93 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -50,6 +50,7 @@ struct FuncsModuleState { #ifdef HPCGAP }; +// for debugging from GDB / lldb, we mark this as extern inline extern inline struct FuncsModuleState *FuncsState(void) { return (struct FuncsModuleState *)StateSlotsAtOffset(FuncsStateOffset); diff --git a/src/gaptime.c b/src/gaptime.c index c0fe220192..affa0895ac 100644 --- a/src/gaptime.c +++ b/src/gaptime.c @@ -267,17 +267,17 @@ static Obj FuncNanosecondsSinceEpochInfo(Obj self) Obj res, tmp; Int8 resolution; const char * method = "unsupported"; - Int monotonic = 0; + BOOL monotonic = FALSE; #if defined(__APPLE__) && defined(__MACH__) method = "mach_absolute_time"; - monotonic = 1; + monotonic = TRUE; #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) method = "clock_gettime"; - monotonic = 1; + monotonic = TRUE; #elif defined(HAVE_GETTIMEOFDAY) method = "gettimeofday"; - monotonic = 0; + monotonic = FALSE; #endif res = NEW_PREC(4); diff --git a/src/gvars.c b/src/gvars.c index 5232cd2d21..76d2746c9b 100644 --- a/src/gvars.c +++ b/src/gvars.c @@ -675,7 +675,7 @@ void MakeThreadLocalVar ( if (IS_INTOBJ(ExprGVar(gvar))) value = (Obj) 0; SET_ELM_GVAR_LIST( ExprGVars, gvar, INTOBJ_INT(rnam) ); - SetHasExprCopiesFopies(gvar, 1); + SetHasExprCopiesFopies(gvar, TRUE); CHANGED_GVAR_LIST( ExprGVars, gvar ); if (value && TLVars) SetTLDefault(TLVars, rnam, value); @@ -690,7 +690,7 @@ void MakeThreadLocalVar ( Obj FuncDeclareGlobalName(Obj self, Obj name) { RequireStringRep("DeclareGlobalName", name); - SetIsDeclaredName(GVarName(CONST_CSTR_STRING(name)), 1); + SetIsDeclaredName(GVarName(CONST_CSTR_STRING(name)), TRUE); return 0; } @@ -854,7 +854,7 @@ static Obj FuncAUTO(Obj self, Obj args) gvar = GVarName( CONST_CSTR_STRING(name) ); SET_ELM_GVAR_LIST( ValGVars, gvar, 0 ); SET_ELM_GVAR_LIST( ExprGVars, gvar, list ); - SetHasExprCopiesFopies(gvar, 1); + SetHasExprCopiesFopies(gvar, TRUE); CHANGED_GVAR_LIST( ExprGVars, gvar ); } @@ -1063,7 +1063,7 @@ static Obj FuncUNB_GVAR(Obj self, Obj gvar) */ typedef struct { Obj * copy; - UInt isFopy; + BOOL isFopy; const Char * name; } StructCopyGVar; @@ -1105,7 +1105,7 @@ void InitCopyGVar ( Panic("no room to record CopyGVar"); } CopyAndFopyGVars[NCopyAndFopyGVars].copy = copy; - CopyAndFopyGVars[NCopyAndFopyGVars].isFopy = 0; + CopyAndFopyGVars[NCopyAndFopyGVars].isFopy = FALSE; CopyAndFopyGVars[NCopyAndFopyGVars].name = name; NCopyAndFopyGVars++; #ifdef HPCGAP @@ -1142,7 +1142,7 @@ void InitFopyGVar ( Panic("no room to record FopyGVar"); } CopyAndFopyGVars[NCopyAndFopyGVars].copy = copy; - CopyAndFopyGVars[NCopyAndFopyGVars].isFopy = 1; + CopyAndFopyGVars[NCopyAndFopyGVars].isFopy = TRUE; CopyAndFopyGVars[NCopyAndFopyGVars].name = name; NCopyAndFopyGVars++; #ifdef HPCGAP @@ -1186,7 +1186,7 @@ void UpdateCopyFopyInfo ( void ) MakeBagPublic(cops); #endif SET_ELM_GVAR_LIST( FopiesGVars, gvar, cops ); - SetHasExprCopiesFopies(gvar, 1); + SetHasExprCopiesFopies(gvar, TRUE); CHANGED_GVAR_LIST( FopiesGVars, gvar ); } } @@ -1198,7 +1198,7 @@ void UpdateCopyFopyInfo ( void ) MakeBagPublic(cops); #endif SET_ELM_GVAR_LIST( CopiesGVars, gvar, cops ); - SetHasExprCopiesFopies(gvar, 1); + SetHasExprCopiesFopies(gvar, TRUE); CHANGED_GVAR_LIST( CopiesGVars, gvar ); } } diff --git a/src/io.c b/src/io.c index f17e34e606..9484c39a01 100644 --- a/src/io.c +++ b/src/io.c @@ -471,7 +471,7 @@ UInt CloseInput(TypInputFile * input) // if the input stream supports seeking, update its position to // reflect the actual state of things: we may have read and buffered // more bytes than we actually processed - int offset = strlen(input->ptr); + size_t offset = strlen(input->ptr); // check for EOF if (input->ptr[0] == '\377' && input->ptr[1] == '\0') offset = 0; diff --git a/src/lists.c b/src/lists.c index feb5c1584c..969d82573e 100644 --- a/src/lists.c +++ b/src/lists.c @@ -2415,7 +2415,7 @@ static Int CheckInit ( { Int i; // loop variable Int j; // loop variable - Int success = 1; + BOOL success = TRUE; Int fnums[] = { FN_IS_DENSE, FN_IS_NDENSE, FN_IS_HOMOG, FN_IS_NHOMOG, @@ -2453,7 +2453,7 @@ static Int CheckInit ( if ( ClearFiltsTNums[i] == 0 ) { Pr( "#W ClearFiltsListTNums [%s] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2464,7 +2464,7 @@ static Int CheckInit ( if ( HasFiltListTNums[i][fnums[j]] == -1 ) { Pr( "#W HasFiltListTNums [%s] [%s] missing\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; HasFiltListTNums[i][fnums[j]] = 0; } } @@ -2477,7 +2477,7 @@ static Int CheckInit ( if ( SetFiltListTNums[i][fnums[j]] == 0 ) { Pr( "#W SetFiltListTNums [%s] [%s] missing\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } } } @@ -2489,7 +2489,7 @@ static Int CheckInit ( if ( ResetFiltListTNums[i][fnums[j]] == 0 ) { Pr( "#W ResetFiltListTNums [%s] [%s] missing\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } } } @@ -2508,7 +2508,7 @@ static Int CheckInit ( Pr( "#W ResetFiltListTNums [%s] [%s] failed to reset\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } } } @@ -2524,7 +2524,7 @@ static Int CheckInit ( Pr( "#W SetFiltListTNums [%s] [%s] must not change\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } } } @@ -2537,7 +2537,7 @@ static Int CheckInit ( if ( ClearFiltsTNums[i]+IMMUTABLE != ClearFiltsTNums[i+IMMUTABLE]) { Pr( "#W ClearFiltsTNums [%s] mismatch between mutable and immutable\n", (Int)TNAM_TNUM(i), 0 ); - success = 0; + success = FALSE; } for ( j = 0; j < ARRAY_SIZE(fnums); j++ ) { @@ -2545,21 +2545,21 @@ static Int CheckInit ( HasFiltListTNums[i+IMMUTABLE][fnums[j]]) { Pr( "#W HasFiltListTNums [%s] [%s] mismatch between mutable and immutable\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } if ( (SetFiltListTNums[i][fnums[j]] | IMMUTABLE) != SetFiltListTNums[i+IMMUTABLE][fnums[j]]) { Pr( "#W SetFiltListTNums [%s] [%s] mismatch between mutable and immutable\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } if ( (ResetFiltListTNums[i][fnums[j]] | IMMUTABLE) != ResetFiltListTNums[i+IMMUTABLE][fnums[j]]) { Pr( "#W ResetFiltListTNums [%s] [%s] mismatch between mutable and immutable\n", (Int)TNAM_TNUM(i), (Int)fnams[j] ); - success = 0; + success = FALSE; } } @@ -2570,43 +2570,43 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ empty -> dense ] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( HasFiltListTNums[i][FN_IS_NDENSE] ) { Pr( "#W HasFiltListTNums [%s] [ empty + ndense ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( ! HasFiltListTNums[i][FN_IS_HOMOG] ) { Pr( "#W HasFiltListTNums [%s] [ empty -> homog ] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( HasFiltListTNums[i][FN_IS_NHOMOG] ) { Pr( "#W HasFiltListTNums [%s] [ empty + nhomog ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( ! HasFiltListTNums[i][FN_IS_SSORT] ) { Pr( "#W HasFiltListTNums [%s] [ empty -> ssort ] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( HasFiltListTNums[i][FN_IS_NSORT] ) { Pr( "#W HasFiltListTNums [%s] [ empty + nsort ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( HasFiltListTNums[i][FN_IS_TABLE] ) { Pr( "#W HasFiltListTNums [%s] [ empty + table ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2615,7 +2615,7 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ dense + ndense ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2624,13 +2624,13 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ ndense + homog ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( HasFiltListTNums[i][FN_IS_TABLE] ) { Pr( "#W HasFiltListTNums [%s] [ ndense + table ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2639,19 +2639,19 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ homog + nhomog ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( ! HasFiltListTNums[i][FN_IS_DENSE] ) { Pr( "#W HasFiltListTNums [%s] [ homog -> dense ] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( HasFiltListTNums[i][FN_IS_NDENSE] ) { Pr( "#W HasFiltListTNums [%s] [ homog + ndense ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2660,7 +2660,7 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ nhomog + table ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2669,13 +2669,13 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ table -> homog ] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } if ( ! HasFiltListTNums[i][FN_IS_DENSE] ) { Pr( "#W HasFiltListTNums [%s] [ table -> dense ] missing\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } @@ -2684,7 +2684,7 @@ static Int CheckInit ( Pr( "#W HasFiltListTNums [%s] [ ssort + nsort ] illegal\n", (Int)TNAM_TNUM(i), 0); - success = 0; + success = FALSE; } } } diff --git a/src/main.c b/src/main.c index 69d5e3dd95..0d1af37314 100644 --- a/src/main.c +++ b/src/main.c @@ -97,7 +97,6 @@ static void SetupGAPLocation(const char * argv0, char * GAPExecLocation) // In the code below, we keep resetting locBuf, as some of the methods we // try do not promise to leave the buffer empty on a failed return. char locBuf[GAP_PATH_MAX] = ""; - Int4 length = 0; #if defined(__APPLE__) && defined(__MACH__) uint32_t len = sizeof(locBuf); @@ -137,7 +136,7 @@ static void SetupGAPLocation(const char * argv0, char * GAPExecLocation) *GAPExecLocation = 0; // reset buffer after error // now strip the executable name off - length = strlen(GAPExecLocation); + size_t length = strlen(GAPExecLocation); while (length > 0 && GAPExecLocation[length] != '/') { GAPExecLocation[length] = 0; length--; diff --git a/src/objcftl.c b/src/objcftl.c index 472fd33772..83adcc9b13 100644 --- a/src/objcftl.c +++ b/src/objcftl.c @@ -44,6 +44,7 @@ struct CFTLModuleState { #ifdef HPCGAP }; +// for debugging from GDB / lldb, we mark this as extern inline extern inline struct CFTLModuleState *CFTLState(void) { return (struct CFTLModuleState *)StateSlotsAtOffset(CFTLStateOffset); diff --git a/src/objset.c b/src/objset.c index d72eaa22c3..1d404a5c8a 100644 --- a/src/objset.c +++ b/src/objset.c @@ -127,7 +127,7 @@ static inline void WRITE_SLOT(Obj container, int slot, Obj elm) static void PrintObjSet(Obj set) { UInt i, size = CONST_ADDR_WORD(set)[OBJSET_SIZE]; - Int comma = 0; + BOOL comma = FALSE; Pr("OBJ_SET([ ", 0, 0); for (i=0; i < size; i++) { Obj obj = READ_SLOT(set, i); @@ -135,7 +135,7 @@ static void PrintObjSet(Obj set) if (comma) { Pr(", ", 0, 0); } else { - comma = 1; + comma = TRUE; } PrintObj(obj); } @@ -146,7 +146,7 @@ static void PrintObjSet(Obj set) static void PrintObjMap(Obj map) { UInt i, size = CONST_ADDR_WORD(map)[OBJSET_SIZE]; - Int comma = 0; + BOOL comma = FALSE; Pr("OBJ_MAP([ ", 0, 0); for (i=0; i < size; i++) { Obj obj = READ_SLOT(map, i * 2); @@ -154,7 +154,7 @@ static void PrintObjMap(Obj map) if (comma) { Pr(", ", 0, 0); } else { - comma = 1; + comma = TRUE; } PrintObj(obj); Pr(", ", 0, 0); diff --git a/src/opers.cc b/src/opers.cc index ce86f7a99d..e2e431f8c9 100644 --- a/src/opers.cc +++ b/src/opers.cc @@ -755,7 +755,8 @@ static Obj FuncWITH_HIDDEN_IMPS_FLAGS(Obj self, Obj flags) #ifdef HPCGAP RegionWriteLock(REGION(WITH_HIDDEN_IMPS_FLAGS_CACHE)); #endif - Int changed, i, lastand, stop; + BOOL changed; + Int i, lastand, stop; Int hidden_imps_length = LEN_PLIST(HIDDEN_IMPS) / 2; Int hash = INT_INTOBJ(FuncHASH_FLAGS(0, flags)) % HIDDEN_IMPS_CACHE_LENGTH; @@ -777,18 +778,18 @@ static Obj FuncWITH_HIDDEN_IMPS_FLAGS(Obj self, Obj flags) #ifdef COUNT_OPERS WITH_HIDDEN_IMPS_MISS++; #endif - changed = 1; + changed = TRUE; lastand = 0; - while(changed) + while (changed) { - changed = 0; + changed = FALSE; for (i = hidden_imps_length, stop = lastand; i > stop; i--) { if( IS_SUBSET_FLAGS(with, ELM_PLIST(HIDDEN_IMPS, i*2)) && !IS_SUBSET_FLAGS(with, ELM_PLIST(HIDDEN_IMPS, i*2-1)) ) { with = FuncAND_FLAGS(0, with, ELM_PLIST(HIDDEN_IMPS, i*2-1)); - changed = 1; + changed = TRUE; stop = 0; lastand = i; } @@ -847,7 +848,8 @@ static Obj FuncWITH_IMPS_FLAGS(Obj self, Obj flags) #ifdef HPCGAP RegionWriteLock(REGION(IMPLICATIONS_SIMPLE)); #endif - Int changed, lastand, i, j, stop, imps_length; + BOOL changed; + Int lastand, i, j, stop, imps_length; Int hash = INT_INTOBJ(FuncHASH_FLAGS(0, flags)) % IMPS_CACHE_LENGTH; Obj cacheval; Obj with = flags; @@ -886,11 +888,11 @@ static Obj FuncWITH_IMPS_FLAGS(Obj self, Obj flags) // the other implications have to be considered in a loop imps_length = LEN_PLIST(IMPLICATIONS_COMPOSED); - changed = 1; + changed = TRUE; lastand = imps_length+1; while(changed) { - changed = 0; + changed = FALSE; for (i = 1, stop = lastand; i < stop; i++) { imp = ELM_PLIST(IMPLICATIONS_COMPOSED, i); @@ -898,7 +900,7 @@ static Obj FuncWITH_IMPS_FLAGS(Obj self, Obj flags) !IS_SUBSET_FLAGS(with, ELM_PLIST(imp, 1)) ) { with = FuncAND_FLAGS(0, with, ELM_PLIST(imp, 1)); - changed = 1; + changed = TRUE; stop = imps_length+1; lastand = i; } @@ -1607,7 +1609,6 @@ static UInt CacheMissStatistics[CACHE_SIZE + 1][7]; template static Obj GetMethodCached(Obj cacheBag, Int prec, Obj ids[]) { - UInt typematch; Obj * cache; Obj method = 0; UInt i; @@ -1625,11 +1626,11 @@ static Obj GetMethodCached(Obj cacheBag, Int prec, Obj ids[]) for (i = target; i < cacheEntrySize * CACHE_SIZE; i += cacheEntrySize) { if (cache[i + 1] == INTOBJ_INT(prec)) { - typematch = 1; + BOOL typematch = TRUE; // This loop runs over the arguments, should be compiled away for (int j = 0; j < n; j++) { if (cache[i + j + 2] != ids[j]) { - typematch = 0; + typematch = FALSE; break; } } diff --git a/src/permutat.cc b/src/permutat.cc index ccd5cfe976..7f7bb034a2 100644 --- a/src/permutat.cc +++ b/src/permutat.cc @@ -113,13 +113,12 @@ DECL_MODULE_STATE Obj TmpPerm; #endif -static UInt1 * UseTmpPerm(UInt size) +static void UseTmpPerm(UInt size) { if (TmpPerm == (Obj)0) TmpPerm = NewBag(T_PERM4, size); else if (SIZE_BAG(TmpPerm) < size) ResizeBag(TmpPerm, size); - return (UInt1 *)(ADDR_OBJ(TmpPerm) + 1); } template diff --git a/src/plist.c b/src/plist.c index c05f9b147a..a9b6d0f7e5 100644 --- a/src/plist.c +++ b/src/plist.c @@ -255,19 +255,19 @@ static Int KTNumPlist(Obj list, Obj * famfirst) // look at the first element elm = ELM_PLIST( list, 1 ); if ( elm == 0 ) { - isDense = 0; + isDense = FALSE; } #ifdef HPCGAP else if ( !CheckReadAccess(elm) ) { - isHom = 0; - areMut = 1; - isTable = 0; + isHom = FALSE; + areMut = TRUE; + isTable = FALSE; } #endif else if (TEST_OBJ_FLAG(elm, OBJ_FLAG_TESTING)) { - isHom = 0; + isHom = FALSE; areMut = IS_PLIST_MUTABLE(elm); - isTable = 0; + isTable = FALSE; } else { #ifdef HPCGAP @@ -285,20 +285,20 @@ static Int KTNumPlist(Obj list, Obj * famfirst) family = FAMILY_TYPE( typeObj ); ktnumFirst = 0; } - isHom = 1; + isHom = TRUE; areMut = IS_MUTABLE_OBJ(elm); // if entry is a homogeneous list this might be a table or list if (ktnumFirst >= T_PLIST_HOM) { - isTable = 1; - isRect = 1; + isTable = TRUE; + isRect = TRUE; len = LEN_PLIST(elm); } else if (ktnumFirst == 0 && IS_HOMOG_LIST(elm)) { - isTable = 1; + isTable = TRUE; // only handle small lists as rectangular if (IS_SMALL_LIST(elm)) { - isRect = 1; + isRect = TRUE; len = LEN_LIST(elm); } } @@ -319,45 +319,45 @@ static Int KTNumPlist(Obj list, Obj * famfirst) for ( ; isDense && (isHom || ! areMut) && i <= lenList; i++ ) { elm = ELM_PLIST( list, i ); if ( elm == 0 ) { - isDense = 0; + isDense = FALSE; } #ifdef HPCGAP else if ( !CheckReadAccess(elm) ) { - isHom = 0; - areMut = 1; - isTable = 0; - isRect = 0; + isHom = FALSE; + areMut = TRUE; + isTable = FALSE; + isRect = FALSE; } #endif else if (TEST_OBJ_FLAG(elm, OBJ_FLAG_TESTING)) { - isHom = 0; + isHom = FALSE; areMut = (areMut || IS_PLIST_MUTABLE(elm)); - isTable = 0; - isRect = 0; + isTable = FALSE; + isRect = FALSE; } else { if (isHom) { loopTypeObj = TYPE_OBJ(elm); if ( loopTypeObj != typeObj && FAMILY_TYPE(loopTypeObj) != family ) { - isHom = 0; - isTable = 0; - isRect = 0; + isHom = FALSE; + isTable = FALSE; + isRect = FALSE; } if ( isTable ) { // check IS_PLIST first, as it is much cheaper if (IS_PLIST(elm)) { if (isRect && LEN_PLIST(elm) != len) { - isRect = 0; + isRect = FALSE; } } else if (IS_SMALL_LIST(elm)) { if (isRect && LEN_LIST(elm) != len) { - isRect = 0; + isRect = FALSE; } } else { - isTable = 0; - isRect = 0; + isTable = FALSE; + isRect = FALSE; } } } @@ -367,13 +367,13 @@ static Int KTNumPlist(Obj list, Obj * famfirst) // if we know it is not dense if (knownNDense) - isDense = 0; + isDense = FALSE; // otherwise if we don't know that it IS dense else if (!knownDense) for ( ; isDense && i <= lenList; i++ ) { elm = ELM_PLIST( list, i ); if ( elm == 0 ) { - isDense = 0; + isDense = FALSE; } } @@ -403,13 +403,13 @@ static Int KTNumPlist(Obj list, Obj * famfirst) else if (IS_FFE(ELM_PLIST(list,1))) { FF fld = FLD_FFE(ELM_PLIST(list,1)); - UInt isFFE = 1; + BOOL isFFE = TRUE; for (i = 2; i <= lenList; i++) { x = ELM_PLIST(list,i); if (!IS_FFE(x) || FLD_FFE(x) != fld) { - isFFE = 0; + isFFE = FALSE; break; } } @@ -446,8 +446,8 @@ static Int KTNumHomPlist(Obj list) Obj elm, x; // one element of Int i; // loop variable Int res; // result - Int isSSort; // list is (known to be) SSorted - Int isNSort; // list is (known to be) non-sorted + BOOL isSSort; // list is (known to be) SSorted + BOOL isNSort; // list is (known to be) non-sorted #ifdef HPCGAP if (!CheckWriteAccess(list)) { @@ -486,13 +486,13 @@ static Int KTNumHomPlist(Obj list) if (IS_FFE(elm)) { FF fld = FLD_FFE(ELM_PLIST(list,1)); - UInt isFFE = 1; + BOOL isFFE = TRUE; for (i = 2; i <= lenList; i++) { x = ELM_PLIST(list,i); if (!IS_FFE(x) || FLD_FFE(x) != fld) { - isFFE = 0; + isFFE = FALSE; break; } } @@ -509,10 +509,10 @@ static Int KTNumHomPlist(Obj list) if (!HAS_FILT_LIST(list, FN_IS_TABLE )) { if ( IS_HOMOG_LIST(elm) ) { - isTable = 1; + isTable = TRUE; if (IS_PLIST(elm)) { - isRect = 1; + isRect = TRUE; len = LEN_PLIST(elm); } } @@ -528,7 +528,7 @@ static Int KTNumHomPlist(Obj list) } else { - isTable = 1; + isTable = TRUE; isRect = HAS_FILT_LIST(list, FN_IS_RECT); } if (isTable && !isRect) @@ -1961,10 +1961,10 @@ static BOOL IsSSortPlist(Obj list) Int lenList; Obj elm1; Obj elm2; - Int areMut; + BOOL areMut; Int i; Obj fam=0; // initialize to help compiler - Int isHom; + BOOL isHom; // get the length lenList = LEN_PLIST( list ); @@ -1987,10 +1987,10 @@ static BOOL IsSSortPlist(Obj list) if (!SyInitializing) { fam = FAMILY_OBJ(elm1); - isHom = 1; + isHom = TRUE; } else - isHom = 0; + isHom = FALSE; // loop over the other elements for ( i = 2; i <= lenList; i++ ) { @@ -2047,10 +2047,10 @@ static BOOL IsSSortPlistDense(Obj list) Int lenList; Obj elm1; Obj elm2; - Int areMut; + BOOL areMut; Int i; Obj fam=0; // initialize to help compiler - Int isHom; + BOOL isHom; // get the length lenList = LEN_PLIST( list ); @@ -2071,10 +2071,10 @@ static BOOL IsSSortPlistDense(Obj list) if (!SyInitializing) { fam = FAMILY_OBJ(elm1); - isHom = 1; + isHom = TRUE; } else - isHom = 0; + isHom = FALSE; // loop over the other elements for ( i = 2; i <= lenList; i++ ) { @@ -2453,7 +2453,7 @@ static Obj FuncIsRectangularTablePlist(Obj self, Obj plist) Obj len; UInt lenlist; UInt i; - UInt hasMut = 0; + BOOL hasMut = FALSE; Obj elm; assert(!HAS_FILT_LIST(plist, FN_IS_RECT)); diff --git a/src/profile.c b/src/profile.c index c6c193adaa..bfd26913cb 100644 --- a/src/profile.c +++ b/src/profile.c @@ -430,7 +430,7 @@ void InformProfilingThatThisIsAForkedGAP(void) char filenamecpy[GAP_PATH_MAX]; // Allow 20 characters to allow space for .%d.gz const int SUPPORTED_PATH_LEN = GAP_PATH_MAX - 20; - if(strlen(profileState.filename) > SUPPORTED_PATH_LEN) { + if (strlen(profileState.filename) > SUPPORTED_PATH_LEN) { Panic("Filename can be at most %d character when forking", SUPPORTED_PATH_LEN); } if (endsWithgz(profileState.filename)) { diff --git a/src/read.c b/src/read.c index 1c12349574..437302919e 100644 --- a/src/read.c +++ b/src/read.c @@ -319,7 +319,7 @@ GAP_STATIC_ASSERT(sizeof(LHSRef) <= 8, "LHSRef is too big"); /**************************************************************************** ** */ -static UInt EvalRef(ReaderState * rs, const LHSRef ref, Int needExpr) +static UInt EvalRef(ReaderState * rs, const LHSRef ref, BOOL needExpr) { TRY_IF_NO_ERROR { @@ -643,7 +643,7 @@ static void ReadReferenceModifiers(ReaderState * rs, TypSymbolSet follow) // read one or more selectors while (IS_IN(rs->s.Symbol, S_LPAREN | S_LBRACK | S_LBRACE | S_DOT)) { LHSRef ref = ReadSelector(rs, follow, level); - level = EvalRef(rs, ref, 1); + level = EvalRef(rs, ref, TRUE); } } @@ -864,13 +864,13 @@ static void ReadCallVarAss(ReaderState * rs, TypSymbolSet follow, Char mode) while (IS_IN(rs->s.Symbol, S_LPAREN | S_LBRACK | S_LBRACE | S_DOT)) { // so the prefix was a reference - UInt level = EvalRef(rs, ref, 1); + UInt level = EvalRef(rs, ref, TRUE); ref = ReadSelector(rs, follow, level); } // if we need a reference if (mode == 'r' || (mode == 'x' && rs->s.Symbol != S_ASSIGN)) { - Int needExpr = mode == 'r' || !IS_IN(rs->s.Symbol, S_SEMICOLON); + BOOL needExpr = mode == 'r' || !IS_IN(rs->s.Symbol, S_SEMICOLON); EvalRef(rs, ref, needExpr); } @@ -2065,7 +2065,7 @@ static void ReadFor(ReaderState * rs, TypSymbolSet follow) // volatile LHSRef ref = ReadVar(rs, follow); if (ref.type != R_INVALID) - EvalRef(rs, ref, 1); + EvalRef(rs, ref, TRUE); CheckUnboundGlobal(rs, ref); // 'in' diff --git a/src/records.c b/src/records.c index e19befec0d..76546db9c1 100644 --- a/src/records.c +++ b/src/records.c @@ -64,7 +64,7 @@ static void NewRNamCallback(SymbolTable * symtab, UInt id, Obj name) */ UInt RNamName(const Char * name) { - UInt len = strlen(name); + size_t len = strlen(name); if (len > 1023) { // Note: We can't pass 'name' here, as it might get moved by garbage collection ErrorQuit("Record names must consist of at most 1023 characters", 0, 0); diff --git a/src/scanner.c b/src/scanner.c index cc607b7582..37e642bb77 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -71,7 +71,7 @@ static void SyntaxErrorOrWarning(ScannerState * s, // error is reported, so the pretty-printed context would leak // a literal 0xFF byte to *errout* with no caret to anchor it. const char * line = GetInputLineBuffer(s->input); - const UInt len = strlen(line); + const size_t len = strlen(line); const int line_is_sentinel = (len == 0 || line[0] == '\377'); if (!line_is_sentinel) { if (line[len-1] != '\n') diff --git a/src/sortbase.h b/src/sortbase.h index 069c97672c..4dfd9afefc 100644 --- a/src/sortbase.h +++ b/src/sortbase.h @@ -164,11 +164,11 @@ static inline void PREFIXNAME(Sort3)(SORT_FUNC_ARGS, Int a, Int b, Int c) { * to be moved, and store the partition_point in the argument * partition_point */ -static inline Int PREFIXNAME(Partition)(SORT_FUNC_ARGS, Int start, Int end, +static inline BOOL PREFIXNAME(Partition)(SORT_FUNC_ARGS, Int start, Int end, Int *partition_point) { Int left = start; Int right = end; - Int first_pass = 1; + BOOL first_pass = TRUE; SORT_CREATE_LOCAL(pivot); PREFIXNAME(Sort3)(SORT_ARGS, start, start / 2 + end / 2, end); @@ -198,7 +198,7 @@ static inline Int PREFIXNAME(Partition)(SORT_FUNC_ARGS, Int start, Int end, *partition_point = left; return first_pass; } - first_pass = 0; + first_pass = FALSE; SWAP_INDICES(SORT_ARGS, left, right); left++; @@ -275,7 +275,8 @@ static void PREFIXNAME(CheckBadPivot)(SORT_FUNC_ARGS, Int start, Int end, Int pi static void PREFIXNAME(QuickSort)(SORT_FUNC_ARGS, Int start, Int end, Int depth) { - Int pivot, first_pass; + Int pivot; + BOOL first_pass; if (end - start < 24) { PREFIXNAME(Insertion)(SORT_ARGS, start, end); diff --git a/src/sysfiles.c b/src/sysfiles.c index c2cf83db00..b65033dbe1 100644 --- a/src/sysfiles.c +++ b/src/sysfiles.c @@ -250,7 +250,7 @@ Int4 SyGAPCRC( const Char * name ) UInt4 new; Int4 ch; Int fid; - Int seen_nl; + BOOL seen_nl; // the CRC of a non existing file is 0 fid = SyFopen(name, "r", TRUE); @@ -260,7 +260,7 @@ Int4 SyGAPCRC( const Char * name ) // read in the file byte by byte and compute the CRC crc = 0x12345678L; - seen_nl = 0; + seen_nl = FALSE; while ( (ch = SyGetch(fid) )!= EOF ) { if ( ch == '\377' || ch == '\n' || ch == '\r' ) @@ -269,10 +269,10 @@ Int4 SyGAPCRC( const Char * name ) if ( seen_nl ) continue; else - seen_nl = 1; + seen_nl = TRUE; } else - seen_nl = 0; + seen_nl = FALSE; old = (crc >> 8) & 0x00FFFFFFL; new = syCcitt32[ ( (UInt4)( crc ^ ch ) ) & 0xff ]; crc = old ^ new; @@ -321,14 +321,14 @@ static Obj FuncCrcString(Obj self, Obj str) UInt4 i, len; const Char *ptr; Int4 ch; - Int seen_nl; + BOOL seen_nl; RequireStringRep(SELF_NAME, str); ptr = CONST_CSTR_STRING(str); len = GET_LEN_STRING(str); crc = 0x12345678L; - seen_nl = 0; + seen_nl = FALSE; for (i = 0; i < len; i++) { ch = (Int4)(ptr[i]); if ( ch == '\377' || ch == '\n' || ch == '\r' ) @@ -337,10 +337,10 @@ static Obj FuncCrcString(Obj self, Obj str) if ( seen_nl ) continue; else - seen_nl = 1; + seen_nl = TRUE; } else - seen_nl = 0; + seen_nl = FALSE; old = (crc >> 8) & 0x00FFFFFFL; new = syCcitt32[ ( (UInt4)( crc ^ ch ) ) & 0xff ]; crc = old ^ new; @@ -981,7 +981,7 @@ static UInt syLastIntr; // time of the last interrupt #ifdef HAVE_LIBREADLINE -static Int doingReadline; +static BOOL doingReadline; #endif static void syAnswerIntr(int signr) @@ -1207,7 +1207,7 @@ void SyFputs ( const Char * line, Int fid ) { - UInt i; + size_t i; // if outputting to the terminal compute the cursor position and length if ( fid == 1 || fid == 3 ) { @@ -2089,9 +2089,9 @@ static Char * readlineFgets(Char * line, UInt length, Int fid, UInt block) rl_event_hook = (OnCharReadHookActiveCheck()) ? charreadhook_rl : 0; #endif // now do the real work - doingReadline = 1; + doingReadline = TRUE; rlres = readline(STATE(Prompt)); - doingReadline = 0; + doingReadline = FALSE; // we get a NULL pointer on EOF, say by pressing Ctr-d if (!rlres) { if (!SyCTRD) { diff --git a/src/sysstr.h b/src/sysstr.h index c9173e5c8e..72ed52e687 100644 --- a/src/sysstr.h +++ b/src/sysstr.h @@ -23,8 +23,8 @@ ** *F IsAlpha( ) . . . . . . . . . . . . . is a character a normal letter ** -** 'IsAlpha' returns 1 if its character argument is a character from the -** range 'a..zA..Z' and 0 otherwise. +** 'IsAlpha' returns TRUE if its character argument is a character from the +** range 'a..zA..Z' and FALSE otherwise. */ #define IsAlpha(ch) (isalpha((unsigned int)ch)) @@ -33,8 +33,8 @@ ** *F IsDigit( ) . . . . . . . . . . . . . . . . . is a character a digit ** -** 'IsDigit' returns 1 if its character argument is a digit from the range -** '0..9' and 0 otherwise. +** 'IsDigit' returns TRUE if its character argument is a digit from the +** range '0..9' and FALSE otherwise. */ #define IsDigit(ch) (isdigit((unsigned int)ch)) @@ -43,8 +43,9 @@ ** *F IsIdent( ) . . . . . . . . is a character valid in a GAP identifier ** -** 'IsIdent' returns 1 if its character argument can be used unquoted inside -** a GAP identifier, i.e., is in the range 'a..zA..Z0-9_@', and 0 otherwise. +** 'IsIdent' returns TRUE if its character argument can be used unquoted +** inside a GAP identifier, i.e., is in the range 'a..zA..Z0-9_@', and +** FALSE otherwise. */ EXPORT_INLINE BOOL IsIdent(char ch) { diff --git a/src/tietze.c b/src/tietze.c index d86049a0ea..fa2ced13fa 100644 --- a/src/tietze.c +++ b/src/tietze.c @@ -289,7 +289,7 @@ static Obj FuncTzReplaceGens(Obj self, Obj tietze) Int total; // total length of relators Int old, new; // generators or inverses Int leng, reduced; // relator lengths - Int altered; // flag + BOOL altered; // flag Int i, j; // loop variables // check the Tietze stack @@ -317,7 +317,7 @@ static Obj FuncTzReplaceGens(Obj self, Obj tietze) rel = ptRels[i]; pt2 = ptRel = ADDR_OBJ( rel ); leng = INT_INTOBJ( ptLens[i] ); - altered = 0; + altered = FALSE; // don't change a square relator defining a valid involution if (ELM_PLIST(flags, i) == INTOBJ_INT(3) && leng == 2 && @@ -336,16 +336,18 @@ static Obj FuncTzReplaceGens(Obj self, Obj tietze) new = INT_INTOBJ( ptInvs[-old] ); if ( ! new ) { - altered = 1; + altered = TRUE; continue; // loop over j } if ( pt2 > ptRel && *pt2 == ptInvs[new] ) { - altered = 1; + altered = TRUE; --pt2; } else { - if ( new != old ) { altered = 1; } + if ( new != old ) { + altered = TRUE; + } *++pt2 = INTOBJ_INT( new ); } } @@ -973,9 +975,8 @@ static Obj FuncTzSearchC(Obj self, Obj args) Int n, m; // subword lengths Int count; // number of altered relators Int i, j, jj, x, y; // loop variables - Int lasty; // flag - Int altered; // flag - Int equal; // flag + Int lasty; // previous value of y + BOOL altered; // flag // get and check arguments if ( ! IS_SMALL_LIST(args) || 4 < LEN_LIST(args) || LEN_LIST(args) < 3 ) { @@ -1036,7 +1037,7 @@ static Obj FuncTzSearchC(Obj self, Obj args) ErrorQuit(" must be false or true", 0, 0); } } - equal = ( equ == True ); + const BOOL equal = ( equ == True ); // Skip relators of inconvenient lengths or with inconvenient flags, // and return if the remaining range is empty @@ -1072,8 +1073,9 @@ static Obj FuncTzSearchC(Obj self, Obj args) inv = 109109 * inv; // initialize the hash table - for ( i = 0; i < 2048; i++ ) - ((UInt4 *)keys1)[i] = ((UInt4 *)keys2)[i] = ((UInt4 *)keys3)[i] = 0; + memset(keys1, 0, sizeof(keys1)); + memset(keys2, 0, sizeof(keys2)); + memset(keys3, 0, sizeof(keys3)); // loop over the Tietze relators, starting at position pos1 for ( y = pos1; y < numrels; ) { @@ -1130,7 +1132,7 @@ static Obj FuncTzSearchC(Obj self, Obj args) ylen = INT_INTOBJ( ptLens[y] ); yflag = INT_INTOBJ( ptFlags[y] ); ylen1 = ylen - 1; - altered = 0; + altered = FALSE; // Loop to the next relator, if the current relator is too short if ( y > lasty @@ -1238,7 +1240,7 @@ static Obj FuncTzSearchC(Obj self, Obj args) } ptFlags[y] = INTOBJ_INT( newflag ); - altered = 1; + altered = TRUE; ++count; break; // loop over i } @@ -1285,7 +1287,7 @@ static Obj FuncTzSearchC(Obj self, Obj args) ptFlags = ADDR_OBJ( flags); ptInvs = ADDR_OBJ( invs ) + (numgens + 1); - altered = 1; + altered = TRUE; ++count; --y; break; // loop over i @@ -1331,7 +1333,7 @@ static Obj FuncTzSearchC(Obj self, Obj args) } ptFlags[y] = INTOBJ_INT( newflag ); - altered = 1; + altered = TRUE; ++count; break; // loop over i } @@ -1378,7 +1380,7 @@ static Obj FuncTzSearchC(Obj self, Obj args) ptFlags = ADDR_OBJ( flags); ptInvs = ADDR_OBJ( invs ) + numgens + 1; - altered = 1; + altered = TRUE; ++count; --y; break; // loop over i diff --git a/src/trans.cc b/src/trans.cc index 891a858598..557e7b02a5 100644 --- a/src/trans.cc +++ b/src/trans.cc @@ -3865,7 +3865,8 @@ Obj OnSetsTrans(Obj set, Obj f) const UInt4 * ptf4; UInt deg; Obj * ptres, tmp, res; - UInt i, isint, k; + UInt i, k; + BOOL isInt; // copy the list into a mutable plist, which we will then modify in place res = PLAIN_LIST_COPY(set); @@ -3876,7 +3877,7 @@ Obj OnSetsTrans(Obj set, Obj f) ptf2 = CONST_ADDR_TRANS2(f); deg = DEG_TRANS2(f); // loop over the entries of the tuple - isint = 1; + isInt = TRUE; for (i = 1; i <= len; i++, ptres++) { tmp = *ptres; if (IS_POS_INTOBJ(tmp)) { @@ -3886,7 +3887,7 @@ Obj OnSetsTrans(Obj set, Obj f) } } else { - isint = 0; + isInt = FALSE; tmp = POW(tmp, f); ptres = ADDR_OBJ(res) + i; ptf2 = CONST_ADDR_TRANS2(f); @@ -3900,7 +3901,7 @@ Obj OnSetsTrans(Obj set, Obj f) deg = DEG_TRANS4(f); // loop over the entries of the tuple - isint = 1; + isInt = TRUE; for (i = 1; i <= len; i++, ptres++) { tmp = *ptres; if (IS_POS_INTOBJ(tmp)) { @@ -3910,7 +3911,7 @@ Obj OnSetsTrans(Obj set, Obj f) } } else { - isint = 0; + isInt = FALSE; tmp = POW(tmp, f); ptres = ADDR_OBJ(res) + i; ptf4 = CONST_ADDR_TRANS4(f); @@ -3921,7 +3922,7 @@ Obj OnSetsTrans(Obj set, Obj f) } // sort the result and remove dups - if (isint) { + if (isInt) { SortPlistByRawObj(res); REMOVE_DUPS_PLIST_INTOBJ(res); RetypeBagSM(res, T_PLIST_CYC_SSORT); diff --git a/src/weakptr.c b/src/weakptr.c index 8d27774971..f99e8bde37 100644 --- a/src/weakptr.c +++ b/src/weakptr.c @@ -279,7 +279,7 @@ static Obj FuncWeakPointerObj(Obj self, Obj list) static Int LengthWPObj(Obj wp) { - Int changed = 0; + BOOL changed = FALSE; Int len = STORED_LEN_WPOBJ(wp); #ifdef HPCGAP if (!CheckExclusiveWriteAccess(wp)) @@ -291,7 +291,7 @@ static Int LengthWPObj(Obj wp) elm = ELM_WPOBJ(wp, len); if (elm) break; - changed = 1; + changed = TRUE; len--; } if (changed) From f1710d2725af0dcdbce062e1b1905aa6e08ec6e1 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 6 Jun 2026 13:06:50 +0200 Subject: [PATCH 28/50] kernel: remove `ErrorReturnObj`, `C_NEW_STRING` (#6415) * kernel: remove ErrorReturnObj, C_NEW_STRING We don't use them nor any distributed package. * remove stuff which is now also dead --- lib/error.g | 16 ++-------------- lib/methsel2.g | 1 - src/error.c | 20 +++----------------- src/error.h | 7 ------- src/stringobj.h | 12 ------------ 5 files changed, 5 insertions(+), 51 deletions(-) diff --git a/lib/error.g b/lib/error.g index de03ee813f..dbf522412a 100644 --- a/lib/error.g +++ b/lib/error.g @@ -228,7 +228,7 @@ end); # Unbind(ErrorInner); BIND_GLOBAL("ErrorInner", function(options, earlyMessage) - local context, tracebackContext, mayReturnVoid, mayReturnObj, + local context, tracebackContext, mayReturnVoid, lateMessage, x, prompt, res, errorLVars, errorTracebackLVars, kernelErrorLVars, justQuit, printEarlyMessage, printEarlyTraceback, printAutomaticTraceback, lastErrorStream; @@ -262,17 +262,6 @@ BIND_GLOBAL("ErrorInner", function(options, earlyMessage) mayReturnVoid := false; fi; - if IsBound(options.mayReturnObj) then - mayReturnObj := options.mayReturnObj; - if not mayReturnObj in [false, true] then - PrintTo(ERROR_OUTPUT, "ErrorInner: option mayReturnObj must be true or false\n"); - LEAVE_ALL_NAMESPACES(); - JUMP_TO_CATCH(1); - fi; - else - mayReturnObj := false; - fi; - if IsBound(options.tracebackContext) then tracebackContext := options.tracebackContext; if not IsLVarsBag(tracebackContext) then @@ -410,7 +399,7 @@ BIND_GLOBAL("ErrorInner", function(options, earlyMessage) prompt := "brk> "; fi; if not justQuit then - res := SHELL(context,mayReturnVoid,mayReturnObj,true,prompt,false); + res := SHELL(context,mayReturnVoid,false,true,prompt,false); else res := fail; fi; @@ -455,7 +444,6 @@ BIND_GLOBAL("ErrorNoReturn", function(arg) rec( context := ParentLVars(GetCurrentLVars()), mayReturnVoid := false, - mayReturnObj := false, lateMessage := "type 'quit;' to quit to outer loop", ), arg); diff --git a/lib/methsel2.g b/lib/methsel2.g index 51700574ea..45a5f471b0 100644 --- a/lib/methsel2.g +++ b/lib/methsel2.g @@ -252,7 +252,6 @@ end; context := GetCurrentLVars(), tracebackContext := ParentLVars(GetCurrentLVars()), mayReturnVoid := false, - mayReturnObj := false, lateMessage := "type 'quit;' to quit to outer loop" ), [ no_method_found ]); diff --git a/src/error.c b/src/error.c index 2618e32739..64371589f2 100644 --- a/src/error.c +++ b/src/error.c @@ -422,7 +422,6 @@ static Obj CallErrorInner(const Char * msg, Int arg2, UInt justQuit, UInt mayReturnVoid, - UInt mayReturnObj, Obj lateMessage) { // Must do this before creating any other GAP objects, @@ -447,7 +446,6 @@ static Obj CallErrorInner(const Char * msg, #endif AssPRec(r, RNamName("context"), STATE(CurrLVars)); AssPRec(r, RNamName("justQuit"), justQuit ? True : False); - AssPRec(r, RNamName("mayReturnObj"), mayReturnObj ? True : False); AssPRec(r, RNamName("mayReturnVoid"), mayReturnVoid ? True : False); AssPRec(r, RNamName("lateMessage"), lateMessage); l = NewPlistFromArgs(EarlyMsg); @@ -469,7 +467,7 @@ static Obj CallErrorInner(const Char * msg, void ErrorQuit(const Char * msg, Int arg1, Int arg2) { - CallErrorInner(msg, arg1, arg2, 1, 0, 0, False); + CallErrorInner(msg, arg1, arg2, 1, 0, False); Panic("ErrorQuit must not return"); } @@ -496,18 +494,6 @@ void ErrorMayQuitNrAtLeastArgs(Int narg, Int actual) } -/**************************************************************************** -** -*F ErrorReturnObj( , , , ) . . print and return obj -*/ -Obj ErrorReturnObj(const Char * msg, Int arg1, Int arg2, const Char * msg2) -{ - Obj LateMsg; - LateMsg = MakeString(msg2); - return CallErrorInner(msg, arg1, arg2, 0, 0, 1, LateMsg); -} - - /**************************************************************************** ** *F ErrorReturnVoid( , , , ) . . . print and return @@ -516,7 +502,7 @@ void ErrorReturnVoid(const Char * msg, Int arg1, Int arg2, const Char * msg2) { Obj LateMsg; LateMsg = MakeString(msg2); - CallErrorInner(msg, arg1, arg2, 0, 1, 0, LateMsg); + CallErrorInner(msg, arg1, arg2, 0, 1, LateMsg); // ErrorMode( msg, arg1, arg2, (Obj)0, msg2, 'x' ); } @@ -527,7 +513,7 @@ void ErrorReturnVoid(const Char * msg, Int arg1, Int arg2, const Char * msg2) void ErrorMayQuit(const Char * msg, Int arg1, Int arg2) { Obj LateMsg = MakeString("type 'quit;' to quit to outer loop"); - CallErrorInner(msg, arg1, arg2, 0, 0, 0, LateMsg); + CallErrorInner(msg, arg1, arg2, 0, 0, LateMsg); Panic("ErrorMayQuit must not return"); } diff --git a/src/error.h b/src/error.h index 7915e12756..d0d8749d97 100644 --- a/src/error.h +++ b/src/error.h @@ -69,13 +69,6 @@ void ErrorMayQuitNrArgs(Int narg, Int actual) NORETURN; void ErrorMayQuitNrAtLeastArgs(Int narg, Int actual) NORETURN; -/**************************************************************************** -** -*F ErrorReturnObj( , , , ) . . print and return obj -*/ -Obj ErrorReturnObj(const Char * msg, Int arg1, Int arg2, const Char * msg2); - - /**************************************************************************** ** *F ErrorReturnVoid( , , , ) . . . print and return diff --git a/src/stringobj.h b/src/stringobj.h index 9b28f61107..4071c06365 100644 --- a/src/stringobj.h +++ b/src/stringobj.h @@ -358,18 +358,6 @@ EXPORT_INLINE Obj MakeImmStringWithLen(const char * buf, size_t len) } -/**************************************************************************** -** -*F C_NEW_STRING( , , ) . . . . . . create GAP string -** -** This macro is deprecated and only provided for backwards compatibility -** with some package kernel extensions. Use 'MakeStringWithLen' and -** 'MakeImmStringWithLen' instead. -*/ -#define C_NEW_STRING(string,len,cstr) \ - string = MakeStringWithLen( (cstr), (len) ) - - /**************************************************************************** ** *F AppendCStr( , , ) . . append data in a buffer to a string From 871d4fc4af182d4dc4c9a046e59032ba480bd9a9 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 6 Jun 2026 13:07:33 +0200 Subject: [PATCH 29/50] Fix ConjugateGroup for matrix groups not defined over a field (#6425) --- lib/grpmat.gi | 7 ++++++- tst/testbugfix/2026-06-05-ConjugateGroup.tst | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tst/testbugfix/2026-06-05-ConjugateGroup.tst diff --git a/lib/grpmat.gi b/lib/grpmat.gi index 65104b3aa4..69966bc7a2 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -1353,7 +1353,12 @@ InstallMethod( ConjugateGroup, ", ", IsCollsElms, if HasIsSubgroupSL( G ) then SetIsSubgroupSL( H, IsSubgroupSL( G ) ); fi; - F:= FieldOfMatrixList( [ g ] ); + + F:= DefaultScalarDomainOfMatrixList( [ g ] ); + if not IsField( F ) then + return H; + fi; + if HasInvariantBilinearForm( G ) then if not IsBound( ginv ) then ginv := g^-1; diff --git a/tst/testbugfix/2026-06-05-ConjugateGroup.tst b/tst/testbugfix/2026-06-05-ConjugateGroup.tst new file mode 100644 index 0000000000..bd8e9c0783 --- /dev/null +++ b/tst/testbugfix/2026-06-05-ConjugateGroup.tst @@ -0,0 +1,13 @@ +# Fix an unexpected error in ConjugateGroup when applied to +# a matrix group not over a field +# See https://github.com/gap-system/gap/issues/6423 +gap> G:=SL(2,Integers mod 4);; +gap> H:=ConjugateGroup(G,G.1);; +gap> G = H; +true + +# original test case +gap> S := SylowSubgroup(SL(2,Integers mod 4),2);; +gap> M := MaximalSubgroups(S);; +gap> Length(M); +3 From 834868ea5cf3247f970bd9afc54f65915150b736 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 8 Jun 2026 11:15:49 +0200 Subject: [PATCH 30/50] kernel: improve `ErrorReturnVoid` break-loop message (#6416) ... and in general make its phrasing more consistent. Also update some several outdated sections of the documentation about break loops and error handling. Co-authored-by: Codex --- doc/ref/debug.xml | 18 ++++++++----- doc/ref/language.xml | 10 +++---- doc/ref/mloop.xml | 36 +++++++------------------ doc/ref/types.xml | 10 +++---- doc/tut/lists.xml | 9 +++---- lib/list.gd | 16 +++-------- src/cyclotom.c | 2 +- src/error.c | 15 ++++++----- src/funcs.c | 3 +-- src/hpc/thread.c | 2 +- src/stats.c | 20 +++++++------- src/streams.c | 18 +++++-------- src/vec8bit.c | 11 ++++---- src/vecgf2.c | 4 +-- tst/testspecial/mem-overflow.g.out | 3 ++- tst/testspecial/stack-depth-func.g.out | 6 +++-- tst/testspecial/stack-depth-func2.g.out | 6 +++-- tst/testspecial/stack-depth-rec.g.out | 6 +++-- 18 files changed, 86 insertions(+), 109 deletions(-) diff --git a/doc/ref/debug.xml b/doc/ref/debug.xml index 7121efabd7..e947af8d05 100644 --- a/doc/ref/debug.xml +++ b/doc/ref/debug.xml @@ -923,7 +923,8 @@ Error, recursion depth trap (5000) [2] dive( depth - 1 ); @ *stdin*:1 ... at *stdin*:4 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> return; gap> dive(11000); Error, recursion depth trap (5000) @@ -932,7 +933,8 @@ Error, recursion depth trap (5000) [2] dive( depth - 1 ); @ *stdin*:1 ... at *stdin*:5 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> return; Error, recursion depth trap (10000) *[1] dive( depth - 1 ); @@ -940,8 +942,10 @@ Error, recursion depth trap (10000) [2] dive( depth - 1 ); @ *stdin*:1 ... at *stdin*:5 -you may 'return;' -brk> return;gap> +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue +brk> return; +gap> ]]>

@@ -981,7 +985,8 @@ Error, recursion depth trap (1000) [2] dive( depth - 1 ); @ *stdin*:4 ... at *stdin*:12 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> return; Error, recursion depth trap (2000) *[1] dive( depth - 1 ); @@ -989,7 +994,8 @@ Error, recursion depth trap (2000) [2] dive( depth - 1 ); @ *stdin*:4 ... at *stdin*:12 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> GetRecursionDepth(); 0 brk> return; diff --git a/doc/ref/language.xml b/doc/ref/language.xml index cab355969b..cce1a2fbfc 100644 --- a/doc/ref/language.xml +++ b/doc/ref/language.xml @@ -715,11 +715,10 @@ gap> xx := 15; 15 gap> MakeReadOnlyGlobal("xx"); gap> xx := 16; -Variable: 'xx' is read only -not in any function -Entering break read-eval-print loop ... -you can 'quit;' to quit to outer loop, or -you can 'return;' after making it writable to continue +Error, Variable: 'xx' is read only +Stack trace: +not in any function at *stdin*:3 +type 'quit;' to quit to outer loop brk> quit; gap> IsReadOnlyGlobal("xx"); true @@ -1563,6 +1562,7 @@ gap> f2:= function( x ) return f1( x ); end;; gap> f2( 4 ); value: 4 Error, Function Calls: must return a value +Stack trace: *[1] f1( x ) @ *stdin*:2 ( ) diff --git a/doc/ref/mloop.xml b/doc/ref/mloop.xml index b39f2f50e8..ee80492a0b 100644 --- a/doc/ref/mloop.xml +++ b/doc/ref/mloop.xml @@ -477,6 +477,7 @@ indicate that you are in a break loop. 1/0; Error, Rational operations: must not be zero +Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop ]]> @@ -487,7 +488,8 @@ If errors occur within a break loop &GAP; enters another break loop at a 1/0; Error, Rational operations: must not be zero -not in any function at *stdin*:2 +Stack trace: +not in any function at *errin*:1 type 'quit;' to quit to outer loop brk_2> ]]> @@ -537,25 +539,11 @@ purpose of this function. return return from break loop The other way to leave a break loop is to return from a break loop. -To do this you type return; or return obj;. If the break loop was entered because you interrupted &GAP;, then you can continue by typing return;. -If the break loop was entered due to an error, -you may have to modify the value of a variable before typing return; -(see the example for ) or you may have to -return an object obj -(by typing: return obj;) to continue the computation; -in any case, the message printed on entering the break loop will -tell you which of these alternatives is possible. -For example, if the break loop was entered because a variable had no -assigned value, the value to be returned is often a value that this -variable should have to continue the computation. -

- return 9; # we had tried to enter the divisor 9 but typed 0 ... -1/9 -gap> -]]> +If the break loop was entered due to an error, this option may or may not +be available, depending on the kind of error. The message printed on entering +the break loop will tell you whether this possible. @@ -581,7 +569,6 @@ function( ) ... end gap> Error("!\n"); Error, ! Hello -Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit; @@ -606,8 +593,7 @@ emitted at level 1

Note that for break loops entered by a call to , -the lines after Entering break read-eval-print loop ... -and before the brk> prompt can also be customised, +the lines just before the brk> prompt can also be customised, namely by redefining .

ErrorNoTraceBack @@ -649,7 +635,6 @@ Here is a somewhat trivial demonstration of the use of ErrorNoTraceBack("Gidday!", " How's", " it", " going?\n"); Error, Gidday! How's it going? -Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit; @@ -661,7 +646,6 @@ Now we call with the same arguments to show the difference. gap> Error("Gidday!", " How's", " it", " going?\n"); Error, Gidday! How's it going? Hello -Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit; @@ -685,9 +669,8 @@ gap> OnBreak := Where;; Break loop message When a break loop is entered by a call to -the message after the -Entering break read-eval-print loop ... line is produced -by the function OnBreakMessage, +the message at the end starting with you can 'quit;' to ... +is produced by the function OnBreakMessage, which just like is a user-configurable global variable that is a function with no arguments. @@ -718,7 +701,6 @@ calling as we did above, now produces: gap> Error("!\n"); Error, ! Hello -Entering break read-eval-print loop ... brk> quit; # to get back to outer loop ]]>

diff --git a/doc/ref/types.xml b/doc/ref/types.xml index 32ffe77b0c..b35730b539 100644 --- a/doc/ref/types.xml +++ b/doc/ref/types.xml @@ -601,12 +601,10 @@ for an object.

Setter( prop )( Rationals, false ); -You cannot set an "and-filter" except to true -not in any function -Entering break read-eval-print loop ... -you can 'quit;' to quit to outer loop, or -you can type 'return true;' to set all components true -(but you might really want to reset just one component) to continue +Error, You cannot set an "and-filter" except to true +Stack trace: +not in any function at *stdin*:8 +type 'quit;' to quit to outer loop brk> ]]> diff --git a/doc/tut/lists.xml b/doc/tut/lists.xml index d79908c21e..de893722ef 100644 --- a/doc/tut/lists.xml +++ b/doc/tut/lists.xml @@ -341,11 +341,10 @@ gap> list[3][5] := 'w';; list; copy; [ 1, 2, "threw", [ 4 ] ] [ 1, 2, "three", [ 4 ] ] gap> copy[3][5] := 'w'; -List Assignment: must be a mutable list -not in any function -Entering break read-eval-print loop ... -you can 'quit;' to quit to outer loop, or -you can 'return;' and ignore the assignment to continue +Error, List Assignment: must be a mutable list +Stack trace: +not in any function at *stdin*:3 +type 'quit;' to quit to outer loop brk> quit; ]]>

diff --git a/lib/list.gd b/lib/list.gd index 5a44805bae..f595715899 100644 --- a/lib/list.gd +++ b/lib/list.gd @@ -379,7 +379,7 @@ DeclareSynonym( "AsSSortedListList", AS_LIST_SORTED_LIST ); ## Lists with holes are sometimes convenient when the list represents ## a mapping from a finite, but not consecutive, ## subset of the positive integers. -## IsDenseList( [ 1, 2, 3 ] ); ## true ## gap> l := [ , 4, 9,, 25,, 49,,,, 121 ];; IsDenseList( l ); @@ -387,22 +387,12 @@ DeclareSynonym( "AsSSortedListList", AS_LIST_SORTED_LIST ); ## gap> l[3]; ## 9 ## gap> l[4]; -## List Element: [4] must have an assigned value -## not in any function -## Entering break read-eval-print loop ... -## you can 'quit;' to quit to outer loop, or -## you can 'return;' after assigning a value to continue -## brk> l[4] := 16;; # assigning a value -## brk> return; # to escape the break-loop -## 16 -## gap> -## ]]> +## Error, List Element: [4] must have an assigned value +## ]]> ##

## Observe that requesting the value of l[4], which was not ## assigned, caused the entry of a break-loop ## (see Section ). -## After assigning a value and typing return;, &GAP; is finally -## able to comply with our request (by responding with 16). ## ## ## <#/GAPDoc> diff --git a/src/cyclotom.c b/src/cyclotom.c index e626946916..9c56dde8e3 100644 --- a/src/cyclotom.c +++ b/src/cyclotom.c @@ -836,7 +836,7 @@ static UInt FindCommonField(UInt nl, UInt nr, UInt *ml, UInt *mr) "This computation requires a cyclotomic field of degree %d, larger " "than the current limit of %d", n, (Int)CyclotomicsLimit, - "You may return after raising the limit with SetCyclotomicsLimit"); + "you can 'return;' after raising the limit with SetCyclotomicsLimit"); } // Finish up diff --git a/src/error.c b/src/error.c index 64371589f2..b783458689 100644 --- a/src/error.c +++ b/src/error.c @@ -500,10 +500,13 @@ void ErrorMayQuitNrAtLeastArgs(Int narg, Int actual) */ void ErrorReturnVoid(const Char * msg, Int arg1, Int arg2, const Char * msg2) { - Obj LateMsg; - LateMsg = MakeString(msg2); - CallErrorInner(msg, arg1, arg2, 0, 1, LateMsg); - // ErrorMode( msg, arg1, arg2, (Obj)0, msg2, 'x' ); + if (msg2 == 0) { + msg2 = "you can 'return;' to continue"; + } + + Obj lateMsg = MakeString("you can 'quit;' to quit to outer loop, or\n"); + AppendString(lateMsg, MakeString(msg2)); + CallErrorInner(msg, arg1, arg2, 0, 1, lateMsg); } /**************************************************************************** @@ -634,7 +637,7 @@ void ErrorBoundedInt( void AssertionFailure(void) { - ErrorReturnVoid("Assertion failure", 0, 0, "you may 'return;'"); + ErrorReturnVoid("Assertion failure", 0, 0, 0); } void AssertionFailureWithMessage(Obj message) @@ -645,7 +648,7 @@ void AssertionFailureWithMessage(Obj message) AssertionFailure(); } else if (IS_STRING_REP(message)) { - ErrorReturnVoid("Assertion failure: %g", (Int)message, 0, "you may 'return;'"); + ErrorReturnVoid("Assertion failure: %g", (Int)message, 0, 0); } else { PrintObj(message); diff --git a/src/funcs.c b/src/funcs.c index 16acf1fb93..4d585e5bb2 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -387,8 +387,7 @@ void RecursionDepthTrap( void ) if (GetRecursionDepth() > 0) { recursionDepth = GetRecursionDepth(); SetRecursionDepth(0); - ErrorReturnVoid("recursion depth trap (%d)", (Int)recursionDepth, 0, - "you may 'return;'"); + ErrorReturnVoid("recursion depth trap (%d)", (Int)recursionDepth, 0, 0); SetRecursionDepth(recursionDepth); } } diff --git a/src/hpc/thread.c b/src/hpc/thread.c index 420074bf93..67f5219fda 100644 --- a/src/hpc/thread.c +++ b/src/hpc/thread.c @@ -975,7 +975,7 @@ static void InterruptCurrentThread(int locked, Stat stat) if (handler) CALL_WITH_CATCH(handler, NEW_PLIST(T_PLIST, 0)); else - ErrorReturnVoid("system interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("system interrupt", 0, 0, 0); if (!locked) pthread_mutex_unlock(thread->lock); } diff --git a/src/stats.c b/src/stats.c index fb2de23a1b..7ed53a74ce 100644 --- a/src/stats.c +++ b/src/stats.c @@ -392,7 +392,7 @@ static ALWAYS_INLINE ExecStatus ExecForHelper(Stat stat, UInt nr) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -435,7 +435,7 @@ static ALWAYS_INLINE ExecStatus ExecForHelper(Stat stat, UInt nr) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -530,7 +530,7 @@ static ALWAYS_INLINE ExecStatus ExecForRangeHelper(Stat stat, UInt nr) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -666,7 +666,7 @@ static ALWAYS_INLINE ExecStatus ExecWhileHelper(Stat stat, UInt nr) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -737,7 +737,7 @@ static ALWAYS_INLINE ExecStatus ExecRepeatHelper(Stat stat, UInt nr) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -952,7 +952,7 @@ static ExecStatus ExecReturnObj(Stat stat) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -980,7 +980,7 @@ static ExecStatus ExecReturnVoid(Stat stat) #if !defined(HAVE_SIGNAL) // test for an interrupt if ( HaveInterrupt() ) { - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); } #endif @@ -1027,7 +1027,7 @@ UInt TakeInterrupt( void ) { if (HaveInterrupt()) { UnInterruptExecStat(); - ErrorReturnVoid("user interrupt", 0, 0, "you can 'return;'"); + ErrorReturnVoid("user interrupt", 0, 0, 0); return 1; } return 0; @@ -1067,12 +1067,12 @@ static ExecStatus ExecIntrStat(Stat stat) if (printError) { ErrorReturnVoid("reached the pre-set memory limit\n" "(change it with the -o command line option)", - 0, 0, "you can 'return;'"); + 0, 0, 0); } } else #endif - ErrorReturnVoid( "user interrupt", 0, 0, "you can 'return;'" ); + ErrorReturnVoid("user interrupt", 0, 0, 0); #endif // continue at the interrupted statement diff --git a/src/streams.c b/src/streams.c index d36d67eb46..4750f3dec2 100644 --- a/src/streams.c +++ b/src/streams.c @@ -517,8 +517,7 @@ static Obj FuncLOG_TO(Obj self, Obj filename) { RequireStringRep(SELF_NAME, filename); if ( ! OpenLog( CONST_CSTR_STRING(filename) ) ) { - ErrorReturnVoid("LogTo: cannot log to %g", (Int)filename, 0, - "you can 'return;'"); + ErrorReturnVoid("LogTo: cannot log to %g", (Int)filename, 0, 0); return False; } return True; @@ -533,8 +532,7 @@ static Obj FuncLOG_TO_STREAM(Obj self, Obj stream) { RequireOutputStream(SELF_NAME, stream); if ( ! OpenLogStream(stream) ) { - ErrorReturnVoid("LogTo: cannot log to stream", 0, 0, - "you can 'return;'"); + ErrorReturnVoid("LogTo: cannot log to stream", 0, 0, 0); return False; } return True; @@ -578,8 +576,7 @@ static Obj FuncINPUT_LOG_TO(Obj self, Obj filename) { RequireStringRep(SELF_NAME, filename); if ( ! OpenInputLog( CONST_CSTR_STRING(filename) ) ) { - ErrorReturnVoid("InputLogTo: cannot log to %g", (Int)filename, 0, - "you can 'return;'"); + ErrorReturnVoid("InputLogTo: cannot log to %g", (Int)filename, 0, 0); return False; } return True; @@ -594,8 +591,7 @@ static Obj FuncINPUT_LOG_TO_STREAM(Obj self, Obj stream) { RequireOutputStream(SELF_NAME, stream); if ( ! OpenInputLogStream(stream) ) { - ErrorReturnVoid("InputLogTo: cannot log to stream", 0, 0, - "you can 'return;'"); + ErrorReturnVoid("InputLogTo: cannot log to stream", 0, 0, 0); return False; } return True; @@ -639,8 +635,7 @@ static Obj FuncOUTPUT_LOG_TO(Obj self, Obj filename) { RequireStringRep(SELF_NAME, filename); if ( ! OpenOutputLog( CONST_CSTR_STRING(filename) ) ) { - ErrorReturnVoid("OutputLogTo: cannot log to %g", (Int)filename, 0, - "you can 'return;'"); + ErrorReturnVoid("OutputLogTo: cannot log to %g", (Int)filename, 0, 0); return False; } return True; @@ -655,8 +650,7 @@ static Obj FuncOUTPUT_LOG_TO_STREAM(Obj self, Obj stream) { RequireOutputStream(SELF_NAME, stream); if ( ! OpenOutputLogStream(stream) ) { - ErrorReturnVoid("OutputLogTo: cannot log to stream", 0, 0, - "you can 'return;'"); + ErrorReturnVoid("OutputLogTo: cannot log to stream", 0, 0, 0); return False; } return True; diff --git a/src/vec8bit.c b/src/vec8bit.c index 3b50507c67..1b583895a8 100644 --- a/src/vec8bit.c +++ b/src/vec8bit.c @@ -3002,7 +3002,7 @@ void ASS_VEC8BIT(Obj list, Obj pos, Obj elm) ErrorReturnVoid("List assignment would increase length of " "locked compressed vector", 0, 0, - "You can `return;' to ignore the assignment"); + "you can 'return;' to ignore the assignment"); return; } ResizeWordSizedBag(list, SIZE_VEC8BIT(p, elts)); @@ -3094,7 +3094,7 @@ static Obj FuncUNB_VEC8BIT(Obj self, Obj list, Obj pos) if (True == DoFilter(IsLockedRepresentationVector, list)) { ErrorReturnVoid( "Unbind of entry of locked compressed vector is forbidden", 0, 0, - "You can `return;' to ignore the assignment"); + "you can 'return;' to ignore the assignment"); return 0; } @@ -3220,7 +3220,7 @@ static Obj FuncAPPEND_VEC8BIT(Obj self, Obj vecl, Obj vecr) lenr = LEN_VEC8BIT(vecr); if (True == DoFilter(IsLockedRepresentationVector, vecl) && lenr > 0) { ErrorReturnVoid("Append to locked compressed vector is forbidden", 0, - 0, "You can `return;' to ignore the operation"); + 0, "you can 'return;' to ignore the operation"); return 0; } info = GetFieldInfo8Bit(FIELD_VEC8BIT(vecl)); @@ -4369,7 +4369,7 @@ static void ResizeVec8Bit(Obj vec, UInt newlen, UInt knownclean) if (True == DoFilter(IsLockedRepresentationVector, vec)) { ErrorReturnVoid("Resize of locked compressed vector is forbidden", 0, - 0, "You can `return;' to ignore the operation"); + 0, "you can 'return;' to ignore the operation"); return; } @@ -5002,8 +5002,7 @@ static Obj MakeShiftedVecs(Obj v, UInt len) ResizeVec8Bit(vn, len, 0); len1 = (len == 0) ? 0 : RightMostNonZeroVec8Bit(vn); if (len1 == 0) - ErrorReturnVoid("Zero coefficient vector for reduction", 0, 0, - "you can 'return;'"); + ErrorReturnVoid("Zero coefficient vector for reduction", 0, 0, 0); if (len1 != len) { ResizeVec8Bit(vn, len1, 1); len = len1; diff --git a/src/vecgf2.c b/src/vecgf2.c index b3c7454cb0..c484531c5f 100644 --- a/src/vecgf2.c +++ b/src/vecgf2.c @@ -3826,7 +3826,7 @@ FuncREDUCE_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) if (len2a == 0) { ErrorReturnVoid("ReduceCoeffs: second argument must not be zero", 0, - 0, "you may 'return;' to skip the reduction"); + 0, "you can 'return;' to skip the reduction"); return 0; } @@ -3872,7 +3872,7 @@ FuncQUOTREM_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) } if (len2a == 0) { ErrorReturnVoid("QuotremCoeffs: second argument must not be zero", 0, - 0, "you may 'return;' to skip the reduction"); + 0, "you can 'return;' to skip the reduction"); return 0; } diff --git a/tst/testspecial/mem-overflow.g.out b/tst/testspecial/mem-overflow.g.out index 82620ab76a..1f9147a44c 100644 --- a/tst/testspecial/mem-overflow.g.out +++ b/tst/testspecial/mem-overflow.g.out @@ -7,7 +7,8 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:3 -you can 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> # ... then we should be in a break loop. Exit that, perform some other computations. brk> quit; gap> Factorial(42); diff --git a/tst/testspecial/stack-depth-func.g.out b/tst/testspecial/stack-depth-func.g.out index 60ab11d2a3..37a8116566 100644 --- a/tst/testspecial/stack-depth-func.g.out +++ b/tst/testspecial/stack-depth-func.g.out @@ -14,7 +14,8 @@ Stack trace: [5] f( ); @ *stdin*:2 ... at *stdin*:3 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> return; # try once more Error, recursion depth trap (10000) Stack trace: @@ -29,5 +30,6 @@ Stack trace: [5] f( ); @ *stdin*:2 ... at *stdin*:3 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/stack-depth-func2.g.out b/tst/testspecial/stack-depth-func2.g.out index 7027f3df17..d41cac1c18 100644 --- a/tst/testspecial/stack-depth-func2.g.out +++ b/tst/testspecial/stack-depth-func2.g.out @@ -14,7 +14,8 @@ Stack trace: [5] f( ) @ *stdin*:2 ... at *stdin*:3 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> return; # try once more Error, recursion depth trap (10000) Stack trace: @@ -29,5 +30,6 @@ Stack trace: [5] f( ) @ *stdin*:2 ... at *stdin*:3 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/stack-depth-rec.g.out b/tst/testspecial/stack-depth-rec.g.out index af205e7582..3a2f0bcb5a 100644 --- a/tst/testspecial/stack-depth-rec.g.out +++ b/tst/testspecial/stack-depth-rec.g.out @@ -82,7 +82,8 @@ Stack trace: [5] String( record.(nam) ) @ GAPROOT/lib/record.gi:LINE ... at *stdin*:4 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> return; # try once more Error, recursion depth trap (5000) Stack trace: @@ -97,5 +98,6 @@ Stack trace: [5] String( record.(nam) ) @ GAPROOT/lib/record.gi:LINE ... at *stdin*:4 -you may 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> QUIT; From dece20419f1f324a5c634688721b448422a0f983 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 8 Jun 2026 12:10:32 +0200 Subject: [PATCH 31/50] kernel: refactor FuncPRINT_CURRENT_STATEMENT (#6424) Move part of the code from the kernel to the library. This will make future improvements easier. Co-authored-by: Codex --- lib/error.g | 13 ++++++++--- src/error.c | 42 ++++++++++++++-------------------- tst/testinstall/kernel/gap.tst | 2 +- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/lib/error.g b/lib/error.g index dbf522412a..2a942b4fec 100644 --- a/lib/error.g +++ b/lib/error.g @@ -135,7 +135,8 @@ BIND_GLOBAL("PRETTY_PRINT_VARS", function(context) end); BIND_GLOBAL("WHERE", function(depth, context, activecontext, showlocals) - local bottom, lastcontext, f, level, totaldepth, countcontext; + local bottom, lastcontext, f, level, totaldepth, countcontext, + prefixwidth, location; if depth <= 0 then return; fi; @@ -151,14 +152,20 @@ BIND_GLOBAL("WHERE", function(depth, context, activecontext, showlocals) totaldepth := totaldepth + 1; countcontext := ParentLVars(countcontext); od; + prefixwidth := Length(String(totaldepth)); level := 1; while depth > 0 and context <> bottom do - PRINT_CURRENT_STATEMENT( + location := PRINT_CURRENT_STATEMENT( ERROR_OUTPUT, context, activecontext, level, - totaldepth); + prefixwidth); + if location <> fail then + PrintTo(ERROR_OUTPUT, "\n", + ListWithIdenticalEntries(prefixwidth+2, ' '), + "@ ", location[1], ":", location[2]); + fi; if showlocals then PRETTY_PRINT_VARS(context); else diff --git a/src/error.c b/src/error.c index b783458689..b392cd4302 100644 --- a/src/error.c +++ b/src/error.c @@ -184,12 +184,17 @@ static Obj FuncCURRENT_STATEMENT_LOCATION(Obj self, Obj context) return retlist; } -static Obj FuncPRINT_CURRENT_STATEMENT(Obj self, Obj stream, Obj context, - Obj activeContext, Obj level, - Obj totalDepth) +static Obj FuncPRINT_CURRENT_STATEMENT(Obj self, + Obj stream, + Obj context, + Obj activeContext, + Obj level, + Obj prefixWidth) { + volatile Obj location = Fail; + if (IsBottomLVars(context)) - return 0; + return Fail; // HACK: we want to redirect output // Try to print the output to stream. Use *errout* as a fallback. @@ -208,35 +213,26 @@ static Obj FuncPRINT_CURRENT_STATEMENT(Obj self, Obj stream, Obj context, BOOL rethrow = FALSE; GAP_TRY { - UInt levelInt = INT_INTOBJ(level); - UInt totalDepthInt = INT_INTOBJ(totalDepth); - UInt prefixWidth = 0; - UInt levelWidth = 0; - UInt i; - - char prefix[32]; Obj func = FUNC_LVARS(context); Obj funcname = NAME_FUNC(func); Int line = -1; - GAP_ASSERT(func); + Stat call = STAT_LVARS(context); Obj body = BODY_FUNC(func); Obj filename = GET_FILENAME_BODY(body); - while (totalDepthInt > 0) { - prefixWidth++; - totalDepthInt /= 10; - } - if (activeContext != Fail) { - i = levelInt; + char prefix[32]; + UInt levelInt = INT_INTOBJ(level); + UInt levelWidth = 0; + UInt i = levelInt; while (i > 0) { levelWidth++; i /= 10; } snprintf(prefix, sizeof(prefix), "%c%*s[%lu] ", context == activeContext ? '*' : ' ', - (int)(prefixWidth - levelWidth), "", + (int)(INT_INTOBJ(prefixWidth) - levelWidth), "", (unsigned long)levelInt); Pr("%s", (Int)prefix, 0); } @@ -274,11 +270,7 @@ static Obj FuncPRINT_CURRENT_STATEMENT(Obj self, Obj stream, Obj context, SWITCH_TO_OLD_LVARS(currLVars); } if (line > 0) { - Pr("\n", 0, 0); - for (i = 0; i < prefixWidth + 2; i++) { - Pr(" ", 0, 0); - } - Pr("@ %g:%d", (Int)filename, line); + location = NewPlistFromArgs(filename, INTOBJ_INT(line)); } } GAP_CATCH @@ -292,7 +284,7 @@ static Obj FuncPRINT_CURRENT_STATEMENT(Obj self, Obj stream, Obj context, if (rethrow) GAP_THROW(); - return 0; + return location; } /**************************************************************************** diff --git a/tst/testinstall/kernel/gap.tst b/tst/testinstall/kernel/gap.tst index 493afea431..ba82a4c3ca 100644 --- a/tst/testinstall/kernel/gap.tst +++ b/tst/testinstall/kernel/gap.tst @@ -112,9 +112,9 @@ fail gap> CURRENT_STATEMENT_LOCATION(GetCurrentLVars()); fail gap> PRINT_CURRENT_STATEMENT("*errout*", GetCurrentLVars(), fail, 1, 1); +fail gap> f:=function() local l; l:=GetCurrentLVars(); PRINT_CURRENT_STATEMENT("*errout*", l, fail, 1, 1); Print("\n"); end;; f(); PRINT_CURRENT_STATEMENT( "*errout*", l, fail, 1, 1 ); - @ stream:1 # gap> CALL_WITH_CATCH(fail,fail); From 4e09c0807e0e79f28f569c8913e1a2e63b8d9669 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 9 Jun 2026 01:07:41 +0200 Subject: [PATCH 32/50] Adjust when 'Stack trace:' message is printed (#6432) * Adjust when 'Stack trace:' message is printed * Update one more error message * Add two missing 'Stack trace:' --- doc/ref/debug.xml | 6 +++- doc/ref/language.xml | 1 - doc/ref/mloop.xml | 35 ++++++++++--------- doc/ref/types.xml | 1 - doc/tut/group.xml | 1 + doc/tut/lists.xml | 1 - doc/tut/migrat.xml | 31 ++++++++-------- lib/error.g | 4 +-- lib/integer.gd | 1 + lib/oper1.g | 1 + .../64bit/low-mem-list-types.g.out | 3 -- tst/testspecial/64bit/low-mem-plist-1.g.out | 2 -- tst/testspecial/64bit/low-mem-plist-2.g.out | 2 -- tst/testspecial/backtrace.g.out | 30 ++++++++++++++++ tst/testspecial/backtrace2.g.out | 21 +++++++++++ tst/testspecial/debug-var.g.out | 1 - .../error-in-InputTextString.g.out | 1 - tst/testspecial/last-access.g.out | 1 - tst/testspecial/line-continuation.g.out | 2 -- tst/testspecial/method-not-found-where.g.out | 1 + tst/testspecial/print-formatting.g.out | 1 - tst/testspecial/repl-syntax-err.g.out | 1 - tst/testspecial/stack-trace-depth.g.out | 2 ++ tst/testspecial/top-level-error.g.out | 1 - tst/testspecial/trace.g.out | 6 ---- tst/testspecial/up-down-env.g.out | 2 -- 26 files changed, 98 insertions(+), 61 deletions(-) diff --git a/doc/ref/debug.xml b/doc/ref/debug.xml index e947af8d05..92f55cff95 100644 --- a/doc/ref/debug.xml +++ b/doc/ref/debug.xml @@ -42,7 +42,6 @@ error as in the following example occurs and a break loop is entered: gap> IsNormal(2,2); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `IsNormal' on 2 arguments -Stack trace: called from read-eval loop at *stdin*:1 type 'quit;' to quit to outer loop brk> @@ -918,6 +917,7 @@ gap> dive(100); gap> OnBreak:= function() Where(2); end;; # shorter traceback gap> dive(6000); Error, recursion depth trap (5000) +Stack trace: *[1] dive( depth - 1 ); @ *stdin*:1 [2] dive( depth - 1 ); @@ -928,6 +928,7 @@ you can 'return;' to continue brk> return; gap> dive(11000); Error, recursion depth trap (5000) +Stack trace: *[1] dive( depth - 1 ); @ *stdin*:1 [2] dive( depth - 1 ); @@ -937,6 +938,7 @@ you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> return; Error, recursion depth trap (10000) +Stack trace: *[1] dive( depth - 1 ); @ *stdin*:1 [2] dive( depth - 1 ); @@ -980,6 +982,7 @@ gap> dive(100); Depth 100 gap> dive(2500); Error, recursion depth trap (1000) +Stack trace: *[1] dive( depth - 1 ); @ *stdin*:4 [2] dive( depth - 1 ); @@ -989,6 +992,7 @@ you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> return; Error, recursion depth trap (2000) +Stack trace: *[1] dive( depth - 1 ); @ *stdin*:4 [2] dive( depth - 1 ); diff --git a/doc/ref/language.xml b/doc/ref/language.xml index cce1a2fbfc..b4fbfefcaa 100644 --- a/doc/ref/language.xml +++ b/doc/ref/language.xml @@ -716,7 +716,6 @@ gap> xx := 15; gap> MakeReadOnlyGlobal("xx"); gap> xx := 16; Error, Variable: 'xx' is read only -Stack trace: not in any function at *stdin*:3 type 'quit;' to quit to outer loop brk> quit; diff --git a/doc/ref/mloop.xml b/doc/ref/mloop.xml index ee80492a0b..a13c30e6c8 100644 --- a/doc/ref/mloop.xml +++ b/doc/ref/mloop.xml @@ -477,7 +477,6 @@ indicate that you are in a break loop. 1/0; Error, Rational operations: must not be zero -Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop ]]> @@ -488,7 +487,6 @@ If errors occur within a break loop &GAP; enters another break loop at a 1/0; Error, Rational operations: must not be zero -Stack trace: not in any function at *errin*:1 type 'quit;' to quit to outer loop brk_2> @@ -634,7 +632,8 @@ Here is a somewhat trivial demonstration of the use of

ErrorNoTraceBack("Gidday!", " How's", " it", " going?\n"); -Error, Gidday! How's it going? +Error, +Gidday! How's it going? you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit; @@ -752,7 +751,8 @@ Error, user interrupt @ GAPROOT/lib/stbc.gi:18 ( ) called from read-eval loop at *stdin*:2 -you can 'return;' +you can 'quit;' to quit to outer loop, or +you can 'return;' to continue brk> Where(2); *[1] genlabels := Filtered( genlabels, function ( x ) return pnt ^ sgs[x] = pnt; @@ -828,14 +828,15 @@ Error, ! you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> Where(); +Stack trace: *[1] Error( "!\n" ); - @ *stdin*:4 + @ *stdin*:3 [2] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [3] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [4] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 ( ) called from read-eval loop at *errin*:1 brk> n; @@ -844,28 +845,30 @@ brk> DownEnv(); brk> n; 3 brk> Where(); +Stack trace: [1] Error( "!\n" ); - @ *stdin*:4 + @ *stdin*:3 *[2] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [3] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [4] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 ( ) called from read-eval loop at *errin*:5 brk> DownEnv( 2 ); brk> n; 1 brk> Where(); +Stack trace: [1] Error( "!\n" ); - @ *stdin*:4 + @ *stdin*:3 [2] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [3] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 *[4] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 ( ) called from read-eval loop at *errin*:8 brk> DownEnv( -2 ); diff --git a/doc/ref/types.xml b/doc/ref/types.xml index b35730b539..cc80d788a6 100644 --- a/doc/ref/types.xml +++ b/doc/ref/types.xml @@ -602,7 +602,6 @@ for an object. Setter( prop )( Rationals, false ); Error, You cannot set an "and-filter" except to true -Stack trace: not in any function at *stdin*:8 type 'quit;' to quit to outer loop brk> diff --git a/doc/tut/group.xml b/doc/tut/group.xml index 3d19ea2713..f8b1020368 100644 --- a/doc/tut/group.xml +++ b/doc/tut/group.xml @@ -928,6 +928,7 @@ gap> Size( Image( hom, DerivedSubgroup(s4) ) ); PreImage( hom, (1,2,3) ); Error, must be an injective and surjective mapping +Stack trace: *[1] ErrorNoReturn( " must be an injective and surjective ", "mapping" ); @ GAPROOT/lib/mapping.gi:262 ( ) diff --git a/doc/tut/lists.xml b/doc/tut/lists.xml index de893722ef..0361f480bb 100644 --- a/doc/tut/lists.xml +++ b/doc/tut/lists.xml @@ -342,7 +342,6 @@ gap> list[3][5] := 'w';; list; copy; [ 1, 2, "three", [ 4 ] ] gap> copy[3][5] := 'w'; Error, List Assignment: must be a mutable list -Stack trace: not in any function at *stdin*:3 type 'quit;' to quit to outer loop brk> quit; diff --git a/doc/tut/migrat.xml b/doc/tut/migrat.xml index bf73228ae0..13cdad7898 100644 --- a/doc/tut/migrat.xml +++ b/doc/tut/migrat.xml @@ -851,24 +851,23 @@ When interrupting, the first line printed by Where actually may be one level higher, as shown below.

OnBreak := function() Where(0); end;; # eliminate back-tracing on -gap> # entry to break loop +gap> OnBreak := function() end;; # eliminate back-tracing on entry to break loop gap> test:= function( n ) > if n > 3 then Error( "!\n" ); fi; test( n+1 ); end;; gap> test( 1 ); Error, ! -at *stdin*:6 you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> Where(); +Stack trace: *[1] Error( "!\n" ); - @ *stdin*:4 + @ *stdin*:3 [2] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [3] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [4] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 ( ) called from read-eval loop at *errin*:1 brk> n; @@ -877,28 +876,30 @@ brk> DownEnv(); brk> n; 3 brk> Where(); +Stack trace: [1] Error( "!\n" ); - @ *stdin*:4 + @ *stdin*:3 *[2] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [3] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [4] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 ( ) called from read-eval loop at *errin*:5 brk> DownEnv( 2 ); brk> n; 1 brk> Where(); +Stack trace: [1] Error( "!\n" ); - @ *stdin*:4 + @ *stdin*:3 [2] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 [3] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 *[4] test( n + 1 ); - @ *stdin*:4 + @ *stdin*:3 ( ) called from read-eval loop at *errin*:8 brk> DownEnv( -2 ); diff --git a/lib/error.g b/lib/error.g index 2a942b4fec..0daa77277a 100644 --- a/lib/error.g +++ b/lib/error.g @@ -145,6 +145,7 @@ BIND_GLOBAL("WHERE", function(depth, context, activecontext, showlocals) PrintTo(ERROR_OUTPUT, "called from read-eval loop "); return; fi; + PrintTo(ERROR_OUTPUT, "Stack trace:\n"); lastcontext := context; totaldepth := 0; countcontext := context; @@ -308,9 +309,6 @@ BIND_GLOBAL("ErrorInner", function(options, earlyMessage) printAutomaticTraceback := function() if IsBound(OnBreak) and IsFunction(OnBreak) then - if OnBreak = Where or OnBreak = WhereWithVars then - PrintTo(ERROR_OUTPUT, "Stack trace:\n"); - fi; OnBreak(); fi; end; diff --git a/lib/integer.gd b/lib/integer.gd index 20ca4e07ed..c2ae9c8ac8 100644 --- a/lib/integer.gd +++ b/lib/integer.gd @@ -249,6 +249,7 @@ DeclareGlobalFunction( "BestQuoInt" ); ## ChineseRem( [ 6, 10, 14 ], [ 1, 2, 3 ] ); ## Error, the residues must be equal modulo 2 +## Stack trace: ## *[1] Error( "the residues must be equal modulo ", g.gcd ); ## @ GAPROOT/lib/integer.gi:391 ## ( ) diff --git a/lib/oper1.g b/lib/oper1.g index 2c25bf1cff..1abc10d131 100644 --- a/lib/oper1.g +++ b/lib/oper1.g @@ -929,6 +929,7 @@ end); ## SylowSubgroup( s4, 6 ); ## Error, SylowSubgroup:

must be a prime +## Stack trace: ## *[1] <> ## @ GAPROOT/lib/oper1.g:964 ## [2] <> diff --git a/tst/testspecial/64bit/low-mem-list-types.g.out b/tst/testspecial/64bit/low-mem-list-types.g.out index 086225b90a..b8c7f74302 100644 --- a/tst/testspecial/64bit/low-mem-list-types.g.out +++ b/tst/testspecial/64bit/low-mem-list-types.g.out @@ -1,18 +1,15 @@ gap> ListWithIdenticalEntries(2^50, 'a'); Error, Cannot allocate 1125899906842633 bytes: cannot extend the workspace any more!! -Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop brk> quit; gap> ListWithIdenticalEntries(2^50, true); Error, Cannot allocate 140737488355336 bytes: cannot extend the workspace any more!! -Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop brk> quit; gap> ListWithIdenticalEntries(2^50, 2); Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!! -Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop brk> quit; diff --git a/tst/testspecial/64bit/low-mem-plist-1.g.out b/tst/testspecial/64bit/low-mem-plist-1.g.out index 9264df9d43..f3bdaee9b0 100644 --- a/tst/testspecial/64bit/low-mem-plist-1.g.out +++ b/tst/testspecial/64bit/low-mem-plist-1.g.out @@ -2,13 +2,11 @@ gap> l := []; [ ] gap> l[2^50] := 1; Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!!!! -Stack trace: not in any function at *stdin*:3 type 'quit;' to quit to outer loop brk> quit; gap> l[2^50] := 2; Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!!!! -Stack trace: not in any function at *stdin*:3 type 'quit;' to quit to outer loop brk> quit; diff --git a/tst/testspecial/64bit/low-mem-plist-2.g.out b/tst/testspecial/64bit/low-mem-plist-2.g.out index d50a3a7ab5..3d430e5bb8 100644 --- a/tst/testspecial/64bit/low-mem-plist-2.g.out +++ b/tst/testspecial/64bit/low-mem-plist-2.g.out @@ -1,12 +1,10 @@ gap> EmptyPlist(2^50); Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!! -Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop brk> quit; gap> EmptyPlist(2^50); Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!! -Stack trace: not in any function at *stdin*:2 type 'quit;' to quit to outer loop brk> quit; diff --git a/tst/testspecial/backtrace.g.out b/tst/testspecial/backtrace.g.out index f2130d7a95..c29cadf6fc 100644 --- a/tst/testspecial/backtrace.g.out +++ b/tst/testspecial/backtrace.g.out @@ -20,11 +20,13 @@ Stack trace: called from read-eval loop at *stdin*:13 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] l[[ 1 .. 3 ]] := 1; @ *stdin*:11 ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] l[[ 1 .. 3 ]] := 1; @ *stdin*:11 arguments: @@ -45,11 +47,13 @@ Stack trace: called from read-eval loop at *stdin*:16 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] 1 / 0 @ *stdin*:15 ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] 1 / 0 @ *stdin*:15 arguments: @@ -71,6 +75,7 @@ fi; called from read-eval loop at *stdin*:19 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] if x then return 1; fi; @@ -78,6 +83,7 @@ fi; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] if x then return 1; fi; @@ -102,6 +108,7 @@ fi; called from read-eval loop at *stdin*:22 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] if 1 then return 1; fi; @@ -109,6 +116,7 @@ fi; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] if 1 then return 1; fi; @@ -134,6 +142,7 @@ fi; called from read-eval loop at *stdin*:25 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] if 1 < 0 then return 1; elif 1 then @@ -143,6 +152,7 @@ fi; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] if 1 < 0 then return 1; elif 1 then @@ -168,6 +178,7 @@ od; called from read-eval loop at *stdin*:28 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] while 1 do return 1; od; @@ -175,6 +186,7 @@ od; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] while 1 do return 1; od; @@ -201,6 +213,7 @@ od; you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> Where(); +Stack trace: *[1] Error( "You cannot loop over the integer ", n, " did you mean the range [1..", n, "]" ); @ GAPROOT/lib/integer.gi:LINE [2] for i in 1 do @@ -210,6 +223,7 @@ od; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] Error( "You cannot loop over the integer ", n, " did you mean the range [1..", n, "]" ); @ GAPROOT/lib/integer.gi:LINE arguments: @@ -240,6 +254,7 @@ od; called from read-eval loop at *stdin*:34 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] for i in true do return 1; od; @@ -247,6 +262,7 @@ od; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] for i in true do return 1; od; @@ -271,6 +287,7 @@ od; called from read-eval loop at *stdin*:36 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] for i in true do return 1; od; @@ -278,6 +295,7 @@ od; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] for i in true do return 1; od; @@ -304,6 +322,7 @@ od; called from read-eval loop at *stdin*:38 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] for i in true do return 1; od; @@ -311,6 +330,7 @@ od; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] for i in true do return 1; od; @@ -337,6 +357,7 @@ od; called from read-eval loop at *stdin*:40 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] for i in true do return 1; od; @@ -344,6 +365,7 @@ od; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] for i in true do return 1; od; @@ -369,6 +391,7 @@ until 1; called from read-eval loop at *stdin*:42 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] repeat x := 1; until 1; @@ -376,6 +399,7 @@ until 1; ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] repeat x := 1; until 1; @@ -398,11 +422,13 @@ Stack trace: called from read-eval loop at *stdin*:45 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] Assert( 0, 1 ); @ *stdin*:44 ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] Assert( 0, 1 ); @ *stdin*:44 arguments: @@ -423,11 +449,13 @@ Stack trace: called from read-eval loop at *stdin*:48 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] Assert( 0, 1, "hello" ); @ *stdin*:47 ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] Assert( 0, 1, "hello" ); @ *stdin*:47 arguments: @@ -457,6 +485,7 @@ Stack trace: called from read-eval loop at *stdin*:56 type 'quit;' to quit to outer loop brk> Where(); +Stack trace: *[1] return m[i][j]; @ GAPROOT/lib/matrix.gi:LINE [2] ELM_LIST( m, row, col ) @@ -466,6 +495,7 @@ brk> Where(); ( ) called from read-eval loop at *errin*:1 brk> WhereWithVars(); +Stack trace: *[1] return m[i][j]; @ GAPROOT/lib/matrix.gi:LINE arguments: diff --git a/tst/testspecial/backtrace2.g.out b/tst/testspecial/backtrace2.g.out index 3583cc7588..51ade71f0c 100644 --- a/tst/testspecial/backtrace2.g.out +++ b/tst/testspecial/backtrace2.g.out @@ -39,6 +39,7 @@ you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> n; Where(); 3 +Stack trace: *[1] Error( "!\n" ); @ *stdin*:24 [2] test( n + 1 ); @@ -49,6 +50,7 @@ brk> n; Where(); called from read-eval loop at *errin*:1 brk> DownEnv(); n; Where(); 2 +Stack trace: [1] Error( "!\n" ); @ *stdin*:24 *[2] test( n + 1 ); @@ -59,6 +61,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:2 brk> DownEnv(); n; Where(); 1 +Stack trace: [1] Error( "!\n" ); @ *stdin*:24 [2] test( n + 1 ); @@ -69,6 +72,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:3 brk> DownEnv(); n; Where(); 1 +Stack trace: [1] Error( "!\n" ); @ *stdin*:24 [2] test( n + 1 ); @@ -79,6 +83,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:4 brk> UpEnv(); n; Where(); 2 +Stack trace: [1] Error( "!\n" ); @ *stdin*:24 *[2] test( n + 1 ); @@ -89,6 +94,7 @@ brk> UpEnv(); n; Where(); called from read-eval loop at *errin*:5 brk> UpEnv(); n; Where(); 3 +Stack trace: *[1] Error( "!\n" ); @ *stdin*:24 [2] test( n + 1 ); @@ -99,6 +105,7 @@ brk> UpEnv(); n; Where(); called from read-eval loop at *errin*:6 brk> UpEnv(); n; Where(); 3 +Stack trace: *[1] Error( "!\n" ); @ *stdin*:24 [2] test( n + 1 ); @@ -133,6 +140,7 @@ Stack trace: type 'quit;' to quit to outer loop brk> n; Where(); 3 +Stack trace: *[1] 1 / 0 @ *stdin*:35 [2] test( n + 1 ); @@ -143,6 +151,7 @@ brk> n; Where(); called from read-eval loop at *errin*:1 brk> DownEnv(); n; Where(); 2 +Stack trace: [1] 1 / 0 @ *stdin*:35 *[2] test( n + 1 ); @@ -153,6 +162,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:2 brk> DownEnv(); n; Where(); 1 +Stack trace: [1] 1 / 0 @ *stdin*:35 [2] test( n + 1 ); @@ -163,6 +173,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:3 brk> DownEnv(); n; Where(); 1 +Stack trace: [1] 1 / 0 @ *stdin*:35 [2] test( n + 1 ); @@ -173,6 +184,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:4 brk> UpEnv(); n; Where(); 2 +Stack trace: [1] 1 / 0 @ *stdin*:35 *[2] test( n + 1 ); @@ -183,6 +195,7 @@ brk> UpEnv(); n; Where(); called from read-eval loop at *errin*:5 brk> UpEnv(); n; Where(); 3 +Stack trace: *[1] 1 / 0 @ *stdin*:35 [2] test( n + 1 ); @@ -193,6 +206,7 @@ brk> UpEnv(); n; Where(); called from read-eval loop at *errin*:6 brk> UpEnv(); n; Where(); 3 +Stack trace: *[1] 1 / 0 @ *stdin*:35 [2] test( n + 1 ); @@ -229,6 +243,7 @@ Stack trace: type 'quit;' to quit to outer loop brk> n; Where(); 3 +Stack trace: *[1] IsAbelian( 1 ) @ *stdin*:47 [2] test( n + 1 ); @@ -239,6 +254,7 @@ brk> n; Where(); called from read-eval loop at *errin*:1 brk> DownEnv(); n; Where(); 3 +Stack trace: *[1] IsAbelian( 1 ) @ *stdin*:47 [2] test( n + 1 ); @@ -249,6 +265,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:2 brk> DownEnv(); n; Where(); 2 +Stack trace: [1] IsAbelian( 1 ) @ *stdin*:47 *[2] test( n + 1 ); @@ -259,6 +276,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:3 brk> DownEnv(); n; Where(); 1 +Stack trace: [1] IsAbelian( 1 ) @ *stdin*:47 [2] test( n + 1 ); @@ -269,6 +287,7 @@ brk> DownEnv(); n; Where(); called from read-eval loop at *errin*:4 brk> UpEnv(); n; Where(); 2 +Stack trace: [1] IsAbelian( 1 ) @ *stdin*:47 *[2] test( n + 1 ); @@ -279,6 +298,7 @@ brk> UpEnv(); n; Where(); called from read-eval loop at *errin*:5 brk> UpEnv(); n; Where(); 3 +Stack trace: *[1] IsAbelian( 1 ) @ *stdin*:47 [2] test( n + 1 ); @@ -289,6 +309,7 @@ brk> UpEnv(); n; Where(); called from read-eval loop at *errin*:6 brk> UpEnv(); n; Where(); 3 +Stack trace: *[1] IsAbelian( 1 ) @ *stdin*:47 [2] test( n + 1 ); diff --git a/tst/testspecial/debug-var.g.out b/tst/testspecial/debug-var.g.out index c39af18014..ab72b2459f 100644 --- a/tst/testspecial/debug-var.g.out +++ b/tst/testspecial/debug-var.g.out @@ -89,7 +89,6 @@ gap> x; 42 gap> y; Error, Variable: 'y' must have a value -Stack trace: not in any function at *stdin*:16 gap> gap> h:=function(p) diff --git a/tst/testspecial/error-in-InputTextString.g.out b/tst/testspecial/error-in-InputTextString.g.out index 18aca9b5f0..36b19d8b23 100644 --- a/tst/testspecial/error-in-InputTextString.g.out +++ b/tst/testspecial/error-in-InputTextString.g.out @@ -1,7 +1,6 @@ gap> Read(InputTextString("Print(1 + [()]);")); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `+' on 2 arguments -Stack trace: called from read-eval loop at stream:1 type 'quit;' to quit to outer loop brk> quit; diff --git a/tst/testspecial/last-access.g.out b/tst/testspecial/last-access.g.out index d958151341..78d756615f 100644 --- a/tst/testspecial/last-access.g.out +++ b/tst/testspecial/last-access.g.out @@ -5,7 +5,6 @@ gap> 1;2;3;[last,last2,last3]; [ 3, 2, 1 ] gap> Error("err"); Error, err -Stack trace: not in any function at *stdin*:3 you can 'quit;' to quit to outer loop, or you can 'return;' to continue diff --git a/tst/testspecial/line-continuation.g.out b/tst/testspecial/line-continuation.g.out index 88f253686c..2f06f33fdc 100644 --- a/tst/testspecial/line-continuation.g.out +++ b/tst/testspecial/line-continuation.g.out @@ -4,7 +4,6 @@ gap> # counter only once, so that both examples below report the error in line 2 gap> # gap> EvalString("123\\\n45x;"); Error, Variable: '12345x' must have a value -Stack trace: not in any function at stream:2 Error, Could not evaluate string. Stack trace: @@ -17,7 +16,6 @@ you can 'return;' to continue brk> quit; gap> EvalString("123\\\r\n45x;"); Error, Variable: '12345x' must have a value -Stack trace: not in any function at stream:2 Error, Could not evaluate string. Stack trace: diff --git a/tst/testspecial/method-not-found-where.g.out b/tst/testspecial/method-not-found-where.g.out index 30601cd166..eaaeaee161 100644 --- a/tst/testspecial/method-not-found-where.g.out +++ b/tst/testspecial/method-not-found-where.g.out @@ -13,6 +13,7 @@ brk> ShowMethods(1); #I Searching Method for IsDiagonalMatrix with 1 argument: #I Total: 3 entries brk> Where(5); +Stack trace: *[1] IsDiagonalMat( a ) @ *stdin*:3 ( ) diff --git a/tst/testspecial/print-formatting.g.out b/tst/testspecial/print-formatting.g.out index 984e623ac8..91e7af8741 100644 --- a/tst/testspecial/print-formatting.g.out +++ b/tst/testspecial/print-formatting.g.out @@ -22,7 +22,6 @@ gap> gap> # test formatting status for errout gap> 1/0; # trigger a break loop Error, Rational operations: must not be zero -Stack trace: not in any function at *stdin*:14 type 'quit;' to quit to outer loop brk> old := PrintFormattingStatus("*errout*"); diff --git a/tst/testspecial/repl-syntax-err.g.out b/tst/testspecial/repl-syntax-err.g.out index 9b4f6bc090..7f31dd0233 100644 --- a/tst/testspecial/repl-syntax-err.g.out +++ b/tst/testspecial/repl-syntax-err.g.out @@ -7,7 +7,6 @@ gap> # error, which wasn't reported correctly before the above issues was gap> # fixed. gap> Error(""): Error, -Stack trace: not in any function at *stdin*:9 you can 'quit;' to quit to outer loop, or you can 'return;' to continue diff --git a/tst/testspecial/stack-trace-depth.g.out b/tst/testspecial/stack-trace-depth.g.out index 7a30baca80..9c12a52a9a 100644 --- a/tst/testspecial/stack-trace-depth.g.out +++ b/tst/testspecial/stack-trace-depth.g.out @@ -49,6 +49,7 @@ you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> SetUserPreference("WhereDepth", 12); brk> Where(); +Stack trace: * [1] Error( "foo" ); @ *stdin*:3 [2] f11( ) @@ -75,6 +76,7 @@ brk> Where(); called from read-eval loop at *errin*:2 brk> SetUserPreference("WhereDepth", 5); brk> Where(); +Stack trace: *[1] Error( "foo" ); @ *stdin*:3 [2] f11( ) diff --git a/tst/testspecial/top-level-error.g.out b/tst/testspecial/top-level-error.g.out index 9ed8d6c077..f27f9df6d9 100644 --- a/tst/testspecial/top-level-error.g.out +++ b/tst/testspecial/top-level-error.g.out @@ -1,6 +1,5 @@ gap> Error("foo"); Error, foo -Stack trace: not in any function at *stdin*:2 you can 'quit;' to quit to outer loop, or you can 'return;' to continue diff --git a/tst/testspecial/trace.g.out b/tst/testspecial/trace.g.out index 3467715778..844962b4d0 100644 --- a/tst/testspecial/trace.g.out +++ b/tst/testspecial/trace.g.out @@ -31,7 +31,6 @@ gap> o(1,2,3,4,5,6); [ 1, 2, 3, 4, 5, 6 ] gap> o(1,2,3,4,5,6,7); # not (yet?) supported Error, sorry: cannot yet have X argument operations -Stack trace: not in any function at *stdin*:25 gap> gap> # with tracing @@ -59,7 +58,6 @@ gap> o(1,2,3,4,5,6); [ 1, 2, 3, 4, 5, 6 ] gap> o(1,2,3,4,5,6,7); Error, sorry: cannot yet have X argument operations -Stack trace: not in any function at *stdin*:36 gap> UntraceMethods( o ); # not (yet?) supported gap> @@ -80,7 +78,6 @@ gap> o(1,2,3,4,5,6); [ 1, 2, 3, 4, 5, 6 ] gap> o(1,2,3,4,5,6,7); # not (yet?) supported Error, sorry: cannot yet have X argument operations -Stack trace: not in any function at *stdin*:47 gap> gap> # @@ -113,7 +110,6 @@ gap> o(IsInt,2,3,4,5,6); [ , 2, 3, 4, 5, 6 ] gap> o(IsInt,2,3,4,5,6,7); # not (yet?) supported Error, sorry: cannot yet have X argument constructors -Stack trace: not in any function at *stdin*:70 gap> gap> # with tracing @@ -138,7 +134,6 @@ gap> o(IsInt,2,3,4,5,6); [ , 2, 3, 4, 5, 6 ] gap> o(IsInt,2,3,4,5,6,7); # not (yet?) supported Error, sorry: cannot yet have X argument constructors -Stack trace: not in any function at *stdin*:80 gap> UntraceMethods( o ); gap> @@ -157,6 +152,5 @@ gap> o(IsInt,2,3,4,5,6); [ , 2, 3, 4, 5, 6 ] gap> o(IsInt,2,3,4,5,6,7); # not (yet?) supported Error, sorry: cannot yet have X argument constructors -Stack trace: not in any function at *stdin*:90 gap> QUIT; diff --git a/tst/testspecial/up-down-env.g.out b/tst/testspecial/up-down-env.g.out index f27012aa67..93062e655b 100644 --- a/tst/testspecial/up-down-env.g.out +++ b/tst/testspecial/up-down-env.g.out @@ -55,7 +55,6 @@ brk> ## start a fresh execution context brk> ## brk> Read("top-level-error.g"); Error, foo -Stack trace: not in any function at top-level-error.g:1 you can 'quit;' to quit to outer loop, or you can 'return;' to continue @@ -63,7 +62,6 @@ brk_2> Where(20); not in any function at *errin*:1 brk_2> lvl; # since `Read` started a fresh execution context, we can't access lvl here Error, Variable: 'lvl' must have a value -Stack trace: not in any function at *errin*:2 brk_2> quit; brk> lvl; From a1246781ed9e7b3453ae6dc261eaf38cc850fa8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 01:14:45 +0200 Subject: [PATCH 33/50] build(deps): bump codecov/codecov-action from 6 to 7 (#6430) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 6 to 7. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v6...v7) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0159bdcfb8..e9937fed7f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -276,7 +276,7 @@ jobs: - name: "Gather coverage data" run: ${{ matrix.extra }} dev/ci-gather-coverage.sh - name: "Upload coverage data to Codecov" - uses: codecov/codecov-action@v6 + uses: codecov/codecov-action@v7 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -288,7 +288,7 @@ jobs: steps: - name: "Send Codecov notifications" - uses: codecov/codecov-action@v6 + uses: codecov/codecov-action@v7 with: token: ${{ secrets.CODECOV_TOKEN }} run_command: send-notifications From ba5ed0cf8b8f05b28a24da8f85fdbd609eaa9b0d Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 9 Jun 2026 02:38:24 +0200 Subject: [PATCH 34/50] Adjust conway polynomial error message (#6433) The 'return to continue' is redundant and potentially confusing. --- hpcgap/lib/ffeconway.gi | 2 +- lib/ffe.gd | 6 +++--- lib/ffeconway.gi | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hpcgap/lib/ffeconway.gi b/hpcgap/lib/ffeconway.gi index ff9d82145e..d148ad64f5 100644 --- a/hpcgap/lib/ffeconway.gi +++ b/hpcgap/lib/ffeconway.gi @@ -80,7 +80,7 @@ FFECONWAY.SetUpConwayStuff := function(p,d) if not IsCheapConwayPolynomial(p,d) then Error("Conway Polynomial ",p,"^",d, - " will need to computed and might be slow\n", "return to continue"); + " will need to be computed and might be slow"); fi; cp := CoefficientsOfUnivariatePolynomial(ConwayPolynomial(p,d)); diff --git a/lib/ffe.gd b/lib/ffe.gd index 3eeddef057..1bd089717a 100644 --- a/lib/ffe.gd +++ b/lib/ffe.gd @@ -118,9 +118,9 @@ ## ]]> ## Z(11,40); -## Error, Conway Polynomial 11^40 will need to computed and might be slow -## return to continue -## *[1] Error( "Conway Polynomial ", p, "^", d, " will need to computed and might be slow\n", "return to continue" ); +## Error, Conway Polynomial 11^40 will need to be computed and might be slow +## Stack trace: +## *[1] Error( "Conway Polynomial ", p, "^", d, " will need to be computed and might be slow" ); ## @ GAPROOT/lib/ffeconway.gi:81 ## [2] FFECONWAY.SetUpConwayStuff( p, d ); ## @ GAPROOT/lib/ffeconway.gi:140 diff --git a/lib/ffeconway.gi b/lib/ffeconway.gi index fd6f5b721d..04555686d4 100644 --- a/lib/ffeconway.gi +++ b/lib/ffeconway.gi @@ -78,7 +78,7 @@ FFECONWAY.SetUpConwayStuff := function(p,d) if not IsCheapConwayPolynomial(p,d) then Error("Conway Polynomial ",p,"^",d, - " will need to computed and might be slow\n", "return to continue"); + " will need to be computed and might be slow"); fi; cp := CoefficientsOfUnivariatePolynomial(ConwayPolynomial(p,d)); From 5dcc98eb8ea46ea8fd9e8cdecf507c4a0084a5e0 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 9 Jun 2026 02:43:58 +0200 Subject: [PATCH 35/50] Widen declaration for many matrix related functions (#6095) Also remove some now redundant methods. Before: gap> m:=RandomMat(256, 256, GF(1000000007));; gap> mat:=Matrix(IsZmodnZMatrixRep, GF(1000000007), m);; gap> RankMat(mat)=256; time; true 170 gap> DeterminantMat(mat); time; ZmodpZObj( 873487643, 1000000007 ) 23982 After: gap> m:=RandomMat(256, 256, GF(1000000007));; gap> mat:=Matrix(IsZmodnZMatrixRep, GF(1000000007), m);; gap> RankMat(mat)=256; time; true 161 gap> DeterminantMat(mat); time; ZmodpZObj( 873487643, 1000000007 ) 1949 --- lib/matobjnz.gi | 16 ------------ lib/matrix.gd | 68 ++++++++++++++++++++++++------------------------- lib/matrix.gi | 30 +++++++++++----------- 3 files changed, 49 insertions(+), 65 deletions(-) diff --git a/lib/matobjnz.gi b/lib/matobjnz.gi index c2edf17d3a..e2ac12cd69 100644 --- a/lib/matobjnz.gi +++ b/lib/matobjnz.gi @@ -1315,14 +1315,6 @@ InstallMethod( InverseSameMutability, "for a zmodnz matrix", return n; end ); -InstallMethod( RankMat, "for a zmodnz matrix", [ IsZmodnZMatrixRep ], -function( m ) - m:=MutableCopyMatrix(m); - m:=SemiEchelonMatDestructive(m); - if m<>fail then m:=Length(m.vectors);fi; - return m; -end); - #InstallMethodWithRandomSource( Randomize, # "for a random source and a mutable zmodnz matrix", @@ -1451,14 +1443,6 @@ InstallMethod( CompatibleVector, "for a zmodnz matrix", return NewZeroVector(IsZmodnZVectorRep,BaseDomain(v),NumberRows(v)); end ); -InstallMethod( DeterminantMat, "for a zmodnz matrix", [ IsZmodnZMatrixRep ], -function( a ) -local m; - m:=Size(BaseDomain(a)); - a:=List(a![ROWSPOS],x->x![ELSPOS]); - return ZmodnZObj(DeterminantMat(a),m); -end ); - # Minimal/Characteristic Polynomial stuff ############################################################################# diff --git a/lib/matrix.gd b/lib/matrix.gd index 4fe2262981..31ddbf47fb 100644 --- a/lib/matrix.gd +++ b/lib/matrix.gd @@ -296,7 +296,7 @@ DeclareSynonym( "DiagonalOfMat", DiagonalOfMatrix ); ## ## <#/GAPDoc> ## -DeclareAttribute( "BaseMat", IsMatrix ); +DeclareAttribute( "BaseMat", IsMatrixOrMatrixObj ); ############################################################################# ## @@ -323,7 +323,7 @@ DeclareAttribute( "BaseMat", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareOperation( "BaseMatDestructive", [ IsMatrix ] ); +DeclareOperation( "BaseMatDestructive", [ IsMatrixOrMatrixObj ] ); ############################################################################# ## @@ -345,7 +345,7 @@ DeclareOperation( "BaseMatDestructive", [ IsMatrix ] ); ## ## <#/GAPDoc> ## -DeclareAttribute( "BaseOrthogonalSpaceMat", IsMatrix ); +DeclareAttribute( "BaseOrthogonalSpaceMat", IsMatrixOrMatrixObj ); ############################################################################# @@ -372,7 +372,7 @@ DeclareAttribute( "BaseOrthogonalSpaceMat", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareAttribute( "DefaultFieldOfMatrix", IsMatrix ); +DeclareAttribute( "DefaultFieldOfMatrix", IsMatrixOrMatrixObj ); ############################################################################# @@ -396,7 +396,7 @@ DeclareAttribute( "DefaultFieldOfMatrix", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareAttribute( "DepthOfUpperTriangularMatrix", IsMatrix ); +DeclareAttribute( "DepthOfUpperTriangularMatrix", IsMatrixOrMatrixObj ); ############################################################################# @@ -503,7 +503,7 @@ DeclareSynonym( "DeterminantMatDivFree", DeterminantMatrixDivFree ); ## ## <#/GAPDoc> ## -DeclareAttribute( "DimensionsMat", IsMatrix ); +DeclareAttribute( "DimensionsMat", IsMatrixOrMatrixObj ); ############################################################################# @@ -550,7 +550,7 @@ DeclareAttribute( "DimensionsMat", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareOperation( "ElementaryDivisorsMat", [IsRing,IsMatrix] ); +DeclareOperation( "ElementaryDivisorsMat", [IsRing, IsMatrixOrMatrixObj] ); DeclareGlobalFunction( "ElementaryDivisorsMatDestructive" ); ############################################################################# @@ -623,7 +623,7 @@ DeclareGlobalFunction( "ElementaryDivisorsMatDestructive" ); ## ## <#/GAPDoc> ## -DeclareOperation( "ElementaryDivisorsTransformationsMat", [IsRing,IsMatrix] ); +DeclareOperation( "ElementaryDivisorsTransformationsMat", [IsRing, IsMatrixOrMatrixObj] ); DeclareGlobalFunction( "ElementaryDivisorsTransformationsMatDestructive" ); ############################################################################# @@ -640,7 +640,7 @@ DeclareGlobalFunction( "ElementaryDivisorsTransformationsMatDestructive" ); ## ## ## -DeclareOperation( "TriangulizedNullspaceMatNT", [ IsMatrix ] ); +DeclareOperation( "TriangulizedNullspaceMatNT", [ IsMatrixOrMatrixObj ] ); ############################################################################# @@ -666,8 +666,8 @@ DeclareOperation( "TriangulizedNullspaceMatNT", [ IsMatrix ] ); ## ## <#/GAPDoc> ## -DeclareAttribute( "NullspaceMat", IsMatrix ); -DeclareAttribute( "TriangulizedNullspaceMat", IsMatrix ); +DeclareAttribute( "NullspaceMat", IsMatrixOrMatrixObj ); +DeclareAttribute( "TriangulizedNullspaceMat", IsMatrixOrMatrixObj ); ############################################################################# @@ -706,8 +706,8 @@ DeclareAttribute( "TriangulizedNullspaceMat", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareOperation( "NullspaceMatDestructive", [ IsMatrix and IsMutable] ); -DeclareOperation( "TriangulizedNullspaceMatDestructive", [ IsMatrix and IsMutable] ); +DeclareOperation( "NullspaceMatDestructive", [ IsMatrixOrMatrixObj and IsMutable] ); +DeclareOperation( "TriangulizedNullspaceMatDestructive", [ IsMatrixOrMatrixObj and IsMutable] ); ############################################################################# @@ -779,7 +779,7 @@ DeclareOperation( "Eigenvalues", [ IsRing, IsMatrixOrMatrixObj ] ); ## ## <#/GAPDoc> ## -DeclareOperation( "Eigenspaces", [ IsRing, IsMatrix ] ); +DeclareOperation( "Eigenspaces", [ IsRing, IsMatrixOrMatrixObj ] ); ############################################################################# ## @@ -795,7 +795,7 @@ DeclareOperation( "Eigenspaces", [ IsRing, IsMatrix ] ); ## ## <#/GAPDoc> ## -DeclareOperation( "Eigenvectors", [ IsRing, IsMatrix ] ); +DeclareOperation( "Eigenvectors", [ IsRing, IsMatrixOrMatrixObj ] ); ############################################################################# @@ -926,7 +926,7 @@ DeclareSynonymAttr( "RankMatDestructive", RankMatrixDestructive ); ## ## <#/GAPDoc> ## -DeclareAttribute( "SemiEchelonMat", IsMatrix ); +DeclareAttribute( "SemiEchelonMat", IsMatrixOrMatrixObj ); ############################################################################# ## @@ -950,7 +950,7 @@ DeclareAttribute( "SemiEchelonMat", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareOperation( "SemiEchelonMatDestructive", [ IsMatrix and IsMutable] ); +DeclareOperation( "SemiEchelonMatDestructive", [ IsMatrixOrMatrixObj and IsMutable] ); ############################################################################# @@ -987,7 +987,7 @@ DeclareOperation( "SemiEchelonMatDestructive", [ IsMatrix and IsMutable] ); ## ## <#/GAPDoc> ## -DeclareAttribute( "SemiEchelonMatTransformation", IsMatrix ); +DeclareAttribute( "SemiEchelonMatTransformation", IsMatrixOrMatrixObj ); ############################################################################# ## @@ -1003,7 +1003,7 @@ DeclareAttribute( "SemiEchelonMatTransformation", IsMatrix ); ## ## DeclareOperation( "SemiEchelonMatTransformationDestructive", [ - IsMatrix and IsMutable ] ); + IsMatrixOrMatrixObj and IsMutable ] ); ############################################################################# @@ -1135,7 +1135,7 @@ DeclareSynonym( "MutableTransposedMat", TransposedMatMutable ); # needed? ## ## ## -DeclareOperation( "MutableTransposedMatDestructive", [IsMatrix and IsMutable] ); +DeclareOperation( "MutableTransposedMatDestructive", [IsMatrixOrMatrixObj and IsMutable] ); ############################################################################# @@ -1163,7 +1163,7 @@ DeclareOperation( "MutableTransposedMatDestructive", [IsMatrix and IsMutable] ); ## ## <#/GAPDoc> ## -DeclareOperation( "TransposedMatDestructive", [ IsMatrix ] ); +DeclareOperation( "TransposedMatDestructive", [ IsMatrixOrMatrixObj ] ); @@ -1186,7 +1186,7 @@ DeclareOperation( "TransposedMatDestructive", [ IsMatrix ] ); ## ## <#/GAPDoc> ## -DeclareProperty( "IsMonomialMatrix", IsMatrix ); +DeclareProperty( "IsMonomialMatrix", IsMatrixOrMatrixObj ); ############################################################################# @@ -1211,7 +1211,7 @@ DeclareProperty( "IsMonomialMatrix", IsMatrix ); ## ## <#/GAPDoc> ## -DeclareOperation( "InverseMatMod", [ IsMatrix, IsObject ] ); +DeclareOperation( "InverseMatMod", [ IsMatrixOrMatrixObj, IsObject ] ); ############################################################################# @@ -1246,11 +1246,11 @@ DeclareOperation( "KroneckerProduct", [ IsMatrixOrMatrixObj, IsMatrixOrMatrixObj ## ## ## -## Does thework for SolutionMat and SolutionMatDestructive. +## Does the work for SolutionMat and SolutionMatDestructive. ## ## ## -DeclareOperation( "SolutionMatNoCo", [ IsMatrix, IsRowVector ] ); +DeclareOperation( "SolutionMatNoCo", [ IsMatrixOrMatrixObj, IsRowVectorOrVectorObj ] ); ############################################################################# @@ -1268,7 +1268,7 @@ DeclareOperation( "SolutionMatNoCo", [ IsMatrix, IsRowVector ] ); ## ## <#/GAPDoc> ## -DeclareOperation( "SolutionMat", [ IsMatrix, IsRowVector ] ); +DeclareOperation( "SolutionMat", [ IsMatrixOrMatrixObj, IsRowVectorOrVectorObj ] ); ############################################################################# ## @@ -1300,7 +1300,7 @@ DeclareOperation( "SolutionMat", [ IsMatrix, IsRowVector ] ); ## <#/GAPDoc> ## DeclareOperation( "SolutionMatDestructive", - [ IsMatrix and IsMutable, IsRowVector ] ); + [ IsMatrixOrMatrixObj and IsMutable, IsRowVectorOrVectorObj ] ); ############################################################################ @@ -1326,7 +1326,7 @@ DeclareOperation( "SolutionMatDestructive", ## ## <#/GAPDoc> ## -DeclareOperation( "SumIntersectionMat", [ IsMatrix, IsMatrix ] ); +DeclareOperation( "SumIntersectionMat", [ IsMatrixOrMatrixObj, IsMatrixOrMatrixObj ] ); @@ -1349,7 +1349,7 @@ DeclareOperation( "SumIntersectionMat", [ IsMatrix, IsMatrix ] ); ## ## <#/GAPDoc> ## -DeclareOperation( "TriangulizedMat", [ IsMatrix ] ); +DeclareOperation( "TriangulizedMat", [ IsMatrixOrMatrixObj ] ); DeclareSynonym( "RREF", TriangulizedMat); ############################################################################# @@ -1380,7 +1380,7 @@ DeclareSynonym( "RREF", TriangulizedMat); ## ## <#/GAPDoc> ## -DeclareOperation( "TriangulizeMat", [ IsMatrix and IsMutable ] ); +DeclareOperation( "TriangulizeMat", [ IsMatrixOrMatrixObj and IsMutable ] ); ############################################################################# @@ -1574,7 +1574,7 @@ DeclareGlobalFunction( "BlownUpVector" ); ## ## <#/GAPDoc> ## -DeclareOperation( "DiagonalizeMat", [IsRing,IsMatrix and IsMutable] ); +DeclareOperation( "DiagonalizeMat", [IsRing, IsMatrixOrMatrixObj and IsMutable] ); ############################################################################# @@ -2199,7 +2199,7 @@ DeclareSynonymAttr( "TraceMat", TraceMatrix ); ## ## <#/GAPDoc> ## -DeclareAttribute( "JordanDecomposition", IsMatrix ); +DeclareAttribute( "JordanDecomposition", IsMatrixOrMatrixObj ); ############################################################################# @@ -2382,7 +2382,7 @@ DeclareOperation( "CharacteristicPolynomial", ## DeclareOperation("CharacteristicPolynomialMatrixNC", #IsField is not yet known - [IsRing,IsOrdinaryMatrix,IsPosInt]); + [IsRing,IsMatrixOrMatrixObj,IsPosInt]); ############################################################################# @@ -2400,7 +2400,7 @@ DeclareOperation("CharacteristicPolynomialMatrixNC", ## DeclareOperation("MinimalPolynomialMatrixNC", #IsField is not yet known - [IsRing,IsOrdinaryMatrix,IsPosInt]); + [IsRing,IsMatrixOrMatrixObj,IsPosInt]); ############################################################################# ## diff --git a/lib/matrix.gi b/lib/matrix.gi index 569d65c5b9..11b16fb563 100644 --- a/lib/matrix.gi +++ b/lib/matrix.gi @@ -805,7 +805,7 @@ InstallMethod( CharacteristicPolynomial, "spinning over field", fi; return false; end, - [ IsField, IsField, IsOrdinaryMatrix, IsPosInt ], + [ IsField, IsField, IsMatrixOrMatrixObj, IsPosInt ], function( F, E, mat, inum ) local B; @@ -824,7 +824,7 @@ InstallMethod( CharacteristicPolynomial, "spinning over field", InstallMethod( CharacteristicPolynomialMatrixNC, "spinning over field", IsElmsCollsX, - [ IsField, IsOrdinaryMatrix, IsPosInt ], + [ IsField, IsMatrixOrMatrixObj, IsPosInt ], Matrix_CharacteristicPolynomialSameField); InstallOtherMethod( CharacteristicPolynomial, @@ -868,7 +868,7 @@ InstallOtherMethod( CharacteristicPolynomialMatrixNC, InstallMethod( MinimalPolynomial, "spinning over field", IsElmsCollsX, - [ IsField, IsOrdinaryMatrix, IsPosInt ], + [ IsField, IsMatrixOrMatrixObj, IsPosInt ], function( F, mat,inum ) local fld, B; @@ -905,7 +905,7 @@ end); InstallMethod( MinimalPolynomialMatrixNC, "spinning over field", IsElmsCollsX, - [ IsField, IsOrdinaryMatrix, IsPosInt ], + [ IsField, IsMatrixOrMatrixObj, IsPosInt ], Matrix_MinimalPolynomialSameField); InstallOtherMethod( MinimalPolynomial, @@ -1597,7 +1597,7 @@ end); ## InstallMethod( DeterminantMatDestructive, "fraction-free method", - [ IsOrdinaryMatrix and IsMutable], + [ IsMatrixOrMatrixObj and IsMutable], function ( mat ) local det, sgn, row, zero, m, i, j, k, mult, row2, piv; @@ -1668,7 +1668,7 @@ end); ## through here also. ## InstallMethod( DeterminantMatDestructive,"non fraction free", - [ IsOrdinaryMatrix and IsFFECollColl and IsMutable], + [ IsMatrixOrMatrixObj and IsFFECollColl and IsMutable], function( mat ) local m, zero, det, sgn, k, j, row, l, row2, x; @@ -1743,7 +1743,7 @@ InstallMethod( DeterminantMat, end ); InstallMethod( DeterminantMatDestructive,"nonprime residue rings", - [ IsOrdinaryMatrix and + [ IsMatrixOrMatrixObj and CategoryCollections(CategoryCollections(IsZmodnZObjNonprime)) and IsMutable], DeterminantMatDivFree); @@ -1779,7 +1779,7 @@ InstallMethod( DeterminantMatDestructive,"nonprime residue rings", ## InstallMethod( DeterminantMatDivFree, "Division-free method", - [ IsMatrix ], + [ IsMatrixOrMatrixObj ], function ( M ) local u,v,w,i, ## indices a,b,c,x,y, ## temp indices @@ -2335,7 +2335,7 @@ end ); ## InstallMethod( NullspaceMat, "generic method for ordinary matrices", - [ IsOrdinaryMatrix ], + [ IsMatrixOrMatrixObj ], mat -> SemiEchelonMatTransformation(mat).relations ); InstallOtherMethod(NullspaceMat,"matrix objects",[IsMatrixObj], @@ -2356,7 +2356,7 @@ end); InstallMethod( NullspaceMatDestructive, "generic method for ordinary matrices", - [ IsOrdinaryMatrix and IsMutable], + [ IsMatrixOrMatrixObj and IsMutable], mat -> SemiEchelonMatTransformationDestructive(mat).relations ); InstallOtherMethod( TriangulizedNullspaceMat, @@ -2381,7 +2381,7 @@ end ); InstallMethod( TriangulizedNullspaceMatNT, "generic method", - [ IsOrdinaryMatrix ], + [ IsMatrixOrMatrixObj ], function( mat ) local nullspace, n, empty, i, k, row, zero, one;# @@ -2425,7 +2425,7 @@ InstallMethod( TriangulizedNullspaceMatNT, end ); #InstallMethod(TriangulizedNullspaceMat,"generic method", -# [IsOrdinaryMatrix], +# [IsMatrixOrMatrixObj], # function ( mat ) # # triangulize the transposed of the matrix # return TriangulizedNullspaceMatNT( @@ -2433,7 +2433,7 @@ end ); #end ); #InstallMethod(TriangulizedNullspaceMatDestructive,"generic method", -# [IsOrdinaryMatrix], +# [IsMatrixOrMatrixObj], # function ( mat ) # # triangulize the transposed of the matrix # return TriangulizedNullspaceMatNT( @@ -2545,7 +2545,7 @@ InstallOtherMethod( ProjectiveOrder, ## InstallOtherMethod( RankMatDestructive, "generic method for mutable matrices", - [ IsMatrix and IsMutable ], + [ IsMatrixOrMatrixObj and IsMutable ], function( mat ) mat:= SemiEchelonMatDestructive( mat ); if mat <> fail then @@ -2556,7 +2556,7 @@ InstallOtherMethod( RankMatDestructive, InstallOtherMethod( RankMat, "generic method for matrices", - [ IsMatrix ], + [ IsMatrixOrMatrixObj ], mat -> RankMatDestructive( MutableCopyMatrix( mat ) ) ); From 51da696ec766ecdead296b0598e70658c83919eb Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 10 Jun 2026 16:56:55 +0200 Subject: [PATCH 36/50] Further unify messages before break loop (#6434) * Align and clarify break loop instructions further * Adjust blocks to new late error msg * Regenerate tst/testspecial --- doc/ref/debug.xml | 22 ++++++------ doc/ref/language.xml | 4 +-- doc/ref/methsel.xml | 4 +-- doc/ref/mloop.xml | 34 +++++++++---------- doc/ref/types.xml | 2 +- doc/tut/group.xml | 2 +- doc/tut/lists.xml | 2 +- doc/tut/migrat.xml | 4 +-- doc/tut/opers.xml | 2 +- lib/error.g | 2 +- lib/ffe.gd | 4 +-- lib/grpfp.gd | 6 ++-- lib/grpfp.gi | 6 ++-- lib/init.g | 4 +-- lib/integer.gd | 4 +-- lib/integer.gi | 2 +- lib/methsel2.g | 2 +- lib/oper1.g | 4 +-- src/cyclotom.c | 2 +- src/error.c | 6 ++-- src/gaptime.c | 4 +-- src/vec8bit.c | 8 ++--- src/vecgf2.c | 4 +-- .../64bit/low-mem-list-types.g.out | 6 ++-- tst/testspecial/64bit/low-mem-plist-1.g.out | 4 +-- tst/testspecial/64bit/low-mem-plist-2.g.out | 4 +-- tst/testspecial/backtrace.g.out | 34 +++++++++---------- tst/testspecial/backtrace2.g.out | 8 ++--- tst/testspecial/bad-add.g.out | 2 +- tst/testspecial/bad-array-double-1.g.out | 2 +- tst/testspecial/bad-array-int-0.g.out | 2 +- tst/testspecial/bad-array-int-1.g.out | 2 +- tst/testspecial/bad-array-string.g.out | 2 +- tst/testspecial/bad-array-undef-0.g.out | 2 +- tst/testspecial/bad-array-undef-1.g.out | 2 +- tst/testspecial/bad-minus.g.out | 2 +- tst/testspecial/break-loop-loop.g.out | 4 +-- tst/testspecial/broken-test.g.out | 18 +++++----- .../bugfix-2019-09-27-LastPV.g.out | 2 +- tst/testspecial/current-env.g.out | 4 +-- tst/testspecial/debug-var.g.out | 16 ++++----- .../error-in-InputTextString.g.out | 2 +- .../func-and-proc-call-trace.g.out | 32 ++++++++--------- tst/testspecial/last-access.g.out | 4 +-- tst/testspecial/line-continuation.g.out | 8 ++--- tst/testspecial/mem-overflow.g.out | 4 +-- tst/testspecial/method-not-found-where.g.out | 2 +- tst/testspecial/method-not-found.g.out | 2 +- tst/testspecial/print-formatting.g.out | 2 +- tst/testspecial/repl-syntax-err.g.out | 4 +-- tst/testspecial/stack-depth-func.g.out | 8 ++--- tst/testspecial/stack-depth-func2.g.out | 8 ++--- tst/testspecial/stack-depth-rec.g.out | 8 ++--- tst/testspecial/stack-trace-depth.g.out | 4 +-- tst/testspecial/stack-trace-label.g.out | 4 +-- tst/testspecial/syntax-tree-error.g.out | 4 +-- tst/testspecial/top-level-error.g.out | 4 +-- tst/testspecial/up-down-env.g.out | 6 ++-- 58 files changed, 178 insertions(+), 178 deletions(-) diff --git a/doc/ref/debug.xml b/doc/ref/debug.xml index 92f55cff95..5f5b77f9d7 100644 --- a/doc/ref/debug.xml +++ b/doc/ref/debug.xml @@ -43,7 +43,7 @@ gap> IsNormal(2,2); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `IsNormal' on 2 arguments called from read-eval loop at *stdin*:1 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> ]]>

@@ -923,8 +923,8 @@ Stack trace: [2] dive( depth - 1 ); @ *stdin*:1 ... at *stdin*:4 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; gap> dive(11000); Error, recursion depth trap (5000) @@ -934,8 +934,8 @@ Stack trace: [2] dive( depth - 1 ); @ *stdin*:1 ... at *stdin*:5 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; Error, recursion depth trap (10000) Stack trace: @@ -944,8 +944,8 @@ Stack trace: [2] dive( depth - 1 ); @ *stdin*:1 ... at *stdin*:5 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; gap> ]]> @@ -988,8 +988,8 @@ Stack trace: [2] dive( depth - 1 ); @ *stdin*:4 ... at *stdin*:12 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; Error, recursion depth trap (2000) Stack trace: @@ -998,8 +998,8 @@ Stack trace: [2] dive( depth - 1 ); @ *stdin*:4 ... at *stdin*:12 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> GetRecursionDepth(); 0 brk> return; diff --git a/doc/ref/language.xml b/doc/ref/language.xml index b4fbfefcaa..b0e03199ff 100644 --- a/doc/ref/language.xml +++ b/doc/ref/language.xml @@ -717,7 +717,7 @@ gap> MakeReadOnlyGlobal("xx"); gap> xx := 16; Error, Variable: 'xx' is read only not in any function at *stdin*:3 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> IsReadOnlyGlobal("xx"); true @@ -1566,7 +1566,7 @@ Stack trace: @ *stdin*:2 ( ) called from read-eval loop at *stdin*:3 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> ]]>

diff --git a/doc/ref/methsel.xml b/doc/ref/methsel.xml index 1ce2674710..5e88dabef2 100644 --- a/doc/ref/methsel.xml +++ b/doc/ref/methsel.xml @@ -127,13 +127,13 @@ gap> XCons(IsFullTransformationMonoid,4); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `XCons' on 2 arguments called from read-eval loop at *stdin*:8 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> XCons(IsNilpotentGroup,4); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `XCons' on 2 arguments called from read-eval loop at *stdin*:8 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> ]]> diff --git a/doc/ref/mloop.xml b/doc/ref/mloop.xml index a13c30e6c8..8b9aef83fa 100644 --- a/doc/ref/mloop.xml +++ b/doc/ref/mloop.xml @@ -478,7 +478,7 @@ indicate that you are in a break loop. gap> 1/0; Error, Rational operations: must not be zero not in any function at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop ]]>

If errors occur within a break loop &GAP; enters another break loop at a @@ -488,7 +488,7 @@ If errors occur within a break loop &GAP; enters another break loop at a brk> 1/0; Error, Rational operations: must not be zero not in any function at *errin*:1 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk_2> ]]>

@@ -567,8 +567,8 @@ function( ) ... end gap> Error("!\n"); Error, ! Hello -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; ]]>

@@ -634,8 +634,8 @@ Here is a somewhat trivial demonstration of the use of gap> ErrorNoTraceBack("Gidday!", " How's", " it", " going?\n"); Error, Gidday! How's it going? -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; ]]>

@@ -645,8 +645,8 @@ Now we call with the same arguments to show the difference. gap> Error("Gidday!", " How's", " it", " going?\n"); Error, Gidday! How's it going? Hello -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; ]]>

@@ -668,7 +668,7 @@ gap> OnBreak := Where;; Break loop message When a break loop is entered by a call to -the message at the end starting with you can 'quit;' to ... +the message at the end starting with you can enter 'quit;' to ... is produced by the function OnBreakMessage, which just like is a user-configurable global variable @@ -676,8 +676,8 @@ that is a function with no arguments.

OnBreakMessage(); # By default, OnBreakMessage prints the following -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue ]]>

Perhaps you are familiar with what's possible in a break loop, and so @@ -751,8 +751,8 @@ Error, user interrupt @ GAPROOT/lib/stbc.gi:18 ( ) called from read-eval loop at *stdin*:2 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> Where(2); *[1] genlabels := Filtered( genlabels, function ( x ) return pnt ^ sgs[x] = pnt; @@ -825,8 +825,8 @@ gap> test:= function( n ) > if n > 3 then Error( "!\n" ); fi; test( n+1 ); end;; gap> test( 1 ); Error, ! -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> Where(); Stack trace: *[1] Error( "!\n" ); @@ -908,8 +908,8 @@ Stack trace: @ *stdin*:7 ( ) called from read-eval loop at *stdin*:8 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> x; 1 brk> DownEnv(1); diff --git a/doc/ref/types.xml b/doc/ref/types.xml index cc80d788a6..b49fe1ad2f 100644 --- a/doc/ref/types.xml +++ b/doc/ref/types.xml @@ -603,7 +603,7 @@ for an object. gap> Setter( prop )( Rationals, false ); Error, You cannot set an "and-filter" except to true not in any function at *stdin*:8 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> ]]> diff --git a/doc/tut/group.xml b/doc/tut/group.xml index f8b1020368..a47c55dec9 100644 --- a/doc/tut/group.xml +++ b/doc/tut/group.xml @@ -933,7 +933,7 @@ Stack trace: @ GAPROOT/lib/mapping.gi:262 ( ) called from read-eval loop at *stdin*:7 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; ]]>

diff --git a/doc/tut/lists.xml b/doc/tut/lists.xml index 0361f480bb..e2f8393cc6 100644 --- a/doc/tut/lists.xml +++ b/doc/tut/lists.xml @@ -343,7 +343,7 @@ gap> list[3][5] := 'w';; list; copy; gap> copy[3][5] := 'w'; Error, List Assignment: must be a mutable list not in any function at *stdin*:3 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; ]]>

diff --git a/doc/tut/migrat.xml b/doc/tut/migrat.xml index 13cdad7898..cf182c4fc2 100644 --- a/doc/tut/migrat.xml +++ b/doc/tut/migrat.xml @@ -856,8 +856,8 @@ gap> test:= function( n ) > if n > 3 then Error( "!\n" ); fi; test( n+1 ); end;; gap> test( 1 ); Error, ! -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> Where(); Stack trace: *[1] Error( "!\n" ); diff --git a/doc/tut/opers.xml b/doc/tut/opers.xml index 6413348e73..313bdc7faf 100644 --- a/doc/tut/opers.xml +++ b/doc/tut/opers.xml @@ -218,7 +218,7 @@ stops with an error message of the form Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `Size' on 1 arguments called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop ]]>

You would get an error message as above if you asked for Size( 1 ). diff --git a/lib/error.g b/lib/error.g index 0daa77277a..3a81bebffd 100644 --- a/lib/error.g +++ b/lib/error.g @@ -449,7 +449,7 @@ BIND_GLOBAL("ErrorNoReturn", function(arg) rec( context := ParentLVars(GetCurrentLVars()), mayReturnVoid := false, - lateMessage := "type 'quit;' to quit to outer loop", + lateMessage := "you can enter 'quit;' to quit to outer loop", ), arg); end); diff --git a/lib/ffe.gd b/lib/ffe.gd index 1bd089717a..aa93c7a24f 100644 --- a/lib/ffe.gd +++ b/lib/ffe.gd @@ -128,8 +128,8 @@ ## @ GAPROOT/lib/ffeconway.gi:167 ## ( ) ## called from read-eval loop at *stdin*:2 -## you can 'quit;' to quit to outer loop, or -## you can 'return;' to continue +## you can enter 'quit;' to quit to outer loop, or +## you can enter 'return;' to continue ## brk> ## ]]> ## diff --git a/lib/grpfp.gd b/lib/grpfp.gd index eaa41d6421..8e373a6ec3 100644 --- a/lib/grpfp.gd +++ b/lib/grpfp.gd @@ -90,9 +90,9 @@ fi; ## [5] CosetTableInWholeGroup( H ) ## @ GAPROOT/lib/grpfp.gi:1733 ## ... at *stdin*:3 -## type 'return;' if you want to continue with a new limit of 8192000 cosets, -## type 'quit;' if you want to quit the coset enumeration, -## type 'maxlimit := 0; return;' in order to continue without a limit +## you can enter 'return;' to continue with a new limit of 8192000 cosets, +## you can enter 'quit;' to abort the coset enumeration, +## you can enter 'maxlimit := 0; return;' in order to continue without a limit ## brk> quit; ## ]]> ##

diff --git a/lib/grpfp.gi b/lib/grpfp.gi index 3eaee5e44e..414ee482c8 100644 --- a/lib/grpfp.gi +++ b/lib/grpfp.gi @@ -1113,10 +1113,10 @@ BindGlobal("GTC_CosetTableFromGensAndRels",function(arg) # to give tidy instructions if one enters a break-loop SavedOnBreakMessage := OnBreakMessage; TCEOnBreakMessage := function(n) - Print( "type 'return;' if you want to continue with a new limit of ", + Print( "you can enter 'return;' to continue with a new limit of ", n, " cosets,\n", - "type 'quit;' if you want to quit the coset enumeration,\n", - "type 'maxlimit := 0; return;' in order to continue without a ", + "you can enter 'quit;' to abort the coset enumeration,\n", + "you can enter 'maxlimit := 0; return;' in order to continue without a ", "limit\n" ); OnBreakMessage := SavedOnBreakMessage; end; diff --git a/lib/init.g b/lib/init.g index 82c828d242..f6061f1e58 100644 --- a/lib/init.g +++ b/lib/init.g @@ -34,8 +34,8 @@ OnBreak := function() Print("An error has occurred before the traceback ", ## break loop. ## OnBreakMessage := function() - Print("you can 'quit;' to quit to outer loop, or\n", - "you can 'return;' to continue\n"); + Print("you can enter 'quit;' to quit to outer loop, or\n", + "you can enter 'return;' to continue\n"); end; ############################################################################# diff --git a/lib/integer.gd b/lib/integer.gd index c2ae9c8ac8..29be88cae8 100644 --- a/lib/integer.gd +++ b/lib/integer.gd @@ -254,8 +254,8 @@ DeclareGlobalFunction( "BestQuoInt" ); ## @ GAPROOT/lib/integer.gi:391 ## ( ) ## called from read-eval loop at *stdin*:2 -## you can 'quit;' to quit to outer loop, or -## you can 'return;' to continue +## you can enter 'quit;' to quit to outer loop, or +## you can enter 'return;' to continue ## brk> ## ]]> ## diff --git a/lib/integer.gi b/lib/integer.gi index b5da9421d7..9928ff6cb3 100644 --- a/lib/integer.gi +++ b/lib/integer.gi @@ -727,7 +727,7 @@ InstallGlobalFunction(FactorsInt,function ( n ) return Factors(n_orig); else Error( "sorry, cannot factor ", tmp[2], - "\ntype 'return;' to try again with a larger number of trials in\n", + "\nyou can enter 'return;' to try again with a larger number of trials in\n", "FactorsRho (or use option 'RhoTrials')\n"); if ValueOption("RhoTrials") <> fail then rt := 5 * ValueOption("RhoTrials"); diff --git a/lib/methsel2.g b/lib/methsel2.g index 45a5f471b0..a56b928f5a 100644 --- a/lib/methsel2.g +++ b/lib/methsel2.g @@ -252,7 +252,7 @@ end; context := GetCurrentLVars(), tracebackContext := ParentLVars(GetCurrentLVars()), mayReturnVoid := false, - lateMessage := "type 'quit;' to quit to outer loop" + lateMessage := "you can enter 'quit;' to quit to outer loop" ), [ no_method_found ]); end; diff --git a/lib/oper1.g b/lib/oper1.g index 1abc10d131..23550e1d7c 100644 --- a/lib/oper1.g +++ b/lib/oper1.g @@ -936,8 +936,8 @@ end); ## @ GAPROOT/lib/oper1.g:1007 ## ( ) ## called from read-eval loop at *stdin*:3 -## you can 'quit;' to quit to outer loop, or -## you can 'return;' to continue +## you can enter 'quit;' to quit to outer loop, or +## you can enter 'return;' to continue ## brk> quit; ## ]]> ##

diff --git a/src/cyclotom.c b/src/cyclotom.c index 9c56dde8e3..17b61a3c03 100644 --- a/src/cyclotom.c +++ b/src/cyclotom.c @@ -836,7 +836,7 @@ static UInt FindCommonField(UInt nl, UInt nr, UInt *ml, UInt *mr) "This computation requires a cyclotomic field of degree %d, larger " "than the current limit of %d", n, (Int)CyclotomicsLimit, - "you can 'return;' after raising the limit with SetCyclotomicsLimit"); + "you can enter 'return;' after raising the limit with SetCyclotomicsLimit"); } // Finish up diff --git a/src/error.c b/src/error.c index b392cd4302..325a661234 100644 --- a/src/error.c +++ b/src/error.c @@ -493,10 +493,10 @@ void ErrorMayQuitNrAtLeastArgs(Int narg, Int actual) void ErrorReturnVoid(const Char * msg, Int arg1, Int arg2, const Char * msg2) { if (msg2 == 0) { - msg2 = "you can 'return;' to continue"; + msg2 = "you can enter 'return;' to continue"; } - Obj lateMsg = MakeString("you can 'quit;' to quit to outer loop, or\n"); + Obj lateMsg = MakeString("you can enter 'quit;' to quit to outer loop, or\n"); AppendString(lateMsg, MakeString(msg2)); CallErrorInner(msg, arg1, arg2, 0, 1, lateMsg); } @@ -507,7 +507,7 @@ void ErrorReturnVoid(const Char * msg, Int arg1, Int arg2, const Char * msg2) */ void ErrorMayQuit(const Char * msg, Int arg1, Int arg2) { - Obj LateMsg = MakeString("type 'quit;' to quit to outer loop"); + Obj LateMsg = MakeString("you can enter 'quit;' to quit to outer loop"); CallErrorInner(msg, arg1, arg2, 0, 0, LateMsg); Panic("ErrorMayQuit must not return"); } diff --git a/src/gaptime.c b/src/gaptime.c index affa0895ac..4bc40fe55f 100644 --- a/src/gaptime.c +++ b/src/gaptime.c @@ -315,7 +315,7 @@ static Obj FuncSleep(Obj self, Obj secs) if (HaveInterrupt()) { ClearError(); // The interrupt may still be pending ErrorReturnVoid("user interrupt in sleep", 0, 0, - "you can 'return;' as if the sleep was finished"); + "you can enter 'return;' as if the sleep was finished"); } return 0; @@ -339,7 +339,7 @@ static Obj FuncMicroSleep(Obj self, Obj msecs) ClearError(); // The interrupt may still be pending ErrorReturnVoid( "user interrupt in microsleep", 0, 0, - "you can 'return;' as if the microsleep was finished"); + "you can enter 'return;' as if the microsleep was finished"); } return 0; diff --git a/src/vec8bit.c b/src/vec8bit.c index 1b583895a8..83f34e0657 100644 --- a/src/vec8bit.c +++ b/src/vec8bit.c @@ -3002,7 +3002,7 @@ void ASS_VEC8BIT(Obj list, Obj pos, Obj elm) ErrorReturnVoid("List assignment would increase length of " "locked compressed vector", 0, 0, - "you can 'return;' to ignore the assignment"); + "you can enter 'return;' to ignore the assignment"); return; } ResizeWordSizedBag(list, SIZE_VEC8BIT(p, elts)); @@ -3094,7 +3094,7 @@ static Obj FuncUNB_VEC8BIT(Obj self, Obj list, Obj pos) if (True == DoFilter(IsLockedRepresentationVector, list)) { ErrorReturnVoid( "Unbind of entry of locked compressed vector is forbidden", 0, 0, - "you can 'return;' to ignore the assignment"); + "you can enter 'return;' to ignore the assignment"); return 0; } @@ -3220,7 +3220,7 @@ static Obj FuncAPPEND_VEC8BIT(Obj self, Obj vecl, Obj vecr) lenr = LEN_VEC8BIT(vecr); if (True == DoFilter(IsLockedRepresentationVector, vecl) && lenr > 0) { ErrorReturnVoid("Append to locked compressed vector is forbidden", 0, - 0, "you can 'return;' to ignore the operation"); + 0, "you can enter 'return;' to ignore the operation"); return 0; } info = GetFieldInfo8Bit(FIELD_VEC8BIT(vecl)); @@ -4369,7 +4369,7 @@ static void ResizeVec8Bit(Obj vec, UInt newlen, UInt knownclean) if (True == DoFilter(IsLockedRepresentationVector, vec)) { ErrorReturnVoid("Resize of locked compressed vector is forbidden", 0, - 0, "you can 'return;' to ignore the operation"); + 0, "you can enter 'return;' to ignore the operation"); return; } diff --git a/src/vecgf2.c b/src/vecgf2.c index c484531c5f..d61c046c3a 100644 --- a/src/vecgf2.c +++ b/src/vecgf2.c @@ -3826,7 +3826,7 @@ FuncREDUCE_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) if (len2a == 0) { ErrorReturnVoid("ReduceCoeffs: second argument must not be zero", 0, - 0, "you can 'return;' to skip the reduction"); + 0, "you can enter 'return;' to skip the reduction"); return 0; } @@ -3872,7 +3872,7 @@ FuncQUOTREM_COEFFS_GF2VEC(Obj self, Obj vec1, Obj len1, Obj vec2, Obj len2) } if (len2a == 0) { ErrorReturnVoid("QuotremCoeffs: second argument must not be zero", 0, - 0, "you can 'return;' to skip the reduction"); + 0, "you can enter 'return;' to skip the reduction"); return 0; } diff --git a/tst/testspecial/64bit/low-mem-list-types.g.out b/tst/testspecial/64bit/low-mem-list-types.g.out index b8c7f74302..87dff93393 100644 --- a/tst/testspecial/64bit/low-mem-list-types.g.out +++ b/tst/testspecial/64bit/low-mem-list-types.g.out @@ -1,16 +1,16 @@ gap> ListWithIdenticalEntries(2^50, 'a'); Error, Cannot allocate 1125899906842633 bytes: cannot extend the workspace any more!! not in any function at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> ListWithIdenticalEntries(2^50, true); Error, Cannot allocate 140737488355336 bytes: cannot extend the workspace any more!! not in any function at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> ListWithIdenticalEntries(2^50, 2); Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!! not in any function at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> quit; diff --git a/tst/testspecial/64bit/low-mem-plist-1.g.out b/tst/testspecial/64bit/low-mem-plist-1.g.out index f3bdaee9b0..921fd7e60e 100644 --- a/tst/testspecial/64bit/low-mem-plist-1.g.out +++ b/tst/testspecial/64bit/low-mem-plist-1.g.out @@ -3,12 +3,12 @@ gap> l := []; gap> l[2^50] := 1; Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!!!! not in any function at *stdin*:3 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> l[2^50] := 2; Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!!!! not in any function at *stdin*:3 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> l[3] := 3; 3 diff --git a/tst/testspecial/64bit/low-mem-plist-2.g.out b/tst/testspecial/64bit/low-mem-plist-2.g.out index 3d430e5bb8..757b353f3d 100644 --- a/tst/testspecial/64bit/low-mem-plist-2.g.out +++ b/tst/testspecial/64bit/low-mem-plist-2.g.out @@ -1,11 +1,11 @@ gap> EmptyPlist(2^50); Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!! not in any function at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> EmptyPlist(2^50); Error, Cannot allocate 9007199254741000 bytes: cannot extend the workspace any more!! not in any function at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> quit; diff --git a/tst/testspecial/backtrace.g.out b/tst/testspecial/backtrace.g.out index c29cadf6fc..053849a831 100644 --- a/tst/testspecial/backtrace.g.out +++ b/tst/testspecial/backtrace.g.out @@ -18,7 +18,7 @@ Stack trace: @ *stdin*:11 ( ) called from read-eval loop at *stdin*:13 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] l[[ 1 .. 3 ]] := 1; @@ -45,7 +45,7 @@ Stack trace: @ *stdin*:15 ( ) called from read-eval loop at *stdin*:16 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] 1 / 0 @@ -73,7 +73,7 @@ fi; @ *stdin*:18 ( ) called from read-eval loop at *stdin*:19 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] if x then @@ -106,7 +106,7 @@ fi; @ *stdin*:21 ( ) called from read-eval loop at *stdin*:22 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] if 1 then @@ -140,7 +140,7 @@ fi; @ *stdin*:24 ( ) called from read-eval loop at *stdin*:25 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] if 1 < 0 then @@ -176,7 +176,7 @@ od; @ *stdin*:27 ( ) called from read-eval loop at *stdin*:28 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] while 1 do @@ -210,8 +210,8 @@ od; @ *stdin*:30 ( ) called from read-eval loop at *stdin*:31 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> Where(); Stack trace: *[1] Error( "You cannot loop over the integer ", n, " did you mean the range [1..", n, "]" ); @@ -252,7 +252,7 @@ od; @ *stdin*:33 ( ) called from read-eval loop at *stdin*:34 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] for i in true do @@ -285,7 +285,7 @@ od; @ *stdin*:35 ( ) called from read-eval loop at *stdin*:36 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] for i in true do @@ -320,7 +320,7 @@ od; @ *stdin*:37 ( ) called from read-eval loop at *stdin*:38 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] for i in true do @@ -355,7 +355,7 @@ od; @ *stdin*:39 ( ) called from read-eval loop at *stdin*:40 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] for i in true do @@ -389,7 +389,7 @@ until 1; @ *stdin*:41 ( ) called from read-eval loop at *stdin*:42 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] repeat @@ -420,7 +420,7 @@ Stack trace: @ *stdin*:44 ( ) called from read-eval loop at *stdin*:45 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] Assert( 0, 1 ); @@ -447,7 +447,7 @@ Stack trace: @ *stdin*:47 ( ) called from read-eval loop at *stdin*:48 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] Assert( 0, 1, "hello" ); @@ -483,7 +483,7 @@ Stack trace: @ *stdin*:55 ( ) called from read-eval loop at *stdin*:56 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> Where(); Stack trace: *[1] return m[i][j]; @@ -531,5 +531,5 @@ Stack trace: @ GAPROOT/lib/oper1.g:LINE ( ) called from read-eval loop at *stdin*:61 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/backtrace2.g.out b/tst/testspecial/backtrace2.g.out index 51ade71f0c..2633405b76 100644 --- a/tst/testspecial/backtrace2.g.out +++ b/tst/testspecial/backtrace2.g.out @@ -35,8 +35,8 @@ Stack trace: @ *stdin*:26 ( ) called from read-eval loop at *stdin*:28 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> n; Where(); 3 Stack trace: @@ -137,7 +137,7 @@ Stack trace: @ *stdin*:37 ( ) called from read-eval loop at *stdin*:39 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> n; Where(); 3 Stack trace: @@ -240,7 +240,7 @@ Stack trace: @ *stdin*:49 ( ) called from read-eval loop at *stdin*:51 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> n; Where(); 3 Stack trace: diff --git a/tst/testspecial/bad-add.g.out b/tst/testspecial/bad-add.g.out index 9259da66d3..0dcbbfff42 100644 --- a/tst/testspecial/bad-add.g.out +++ b/tst/testspecial/bad-add.g.out @@ -10,5 +10,5 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-array-double-1.g.out b/tst/testspecial/bad-array-double-1.g.out index a68076d65a..05de996ca7 100644 --- a/tst/testspecial/bad-array-double-1.g.out +++ b/tst/testspecial/bad-array-double-1.g.out @@ -10,5 +10,5 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-array-int-0.g.out b/tst/testspecial/bad-array-int-0.g.out index 17e703a17a..2a307b9437 100644 --- a/tst/testspecial/bad-array-int-0.g.out +++ b/tst/testspecial/bad-array-int-0.g.out @@ -12,5 +12,5 @@ Stack trace: @ *stdin*:5 ( ) called from read-eval loop at *stdin*:7 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-array-int-1.g.out b/tst/testspecial/bad-array-int-1.g.out index cd7a87a095..ae359c3547 100644 --- a/tst/testspecial/bad-array-int-1.g.out +++ b/tst/testspecial/bad-array-int-1.g.out @@ -9,5 +9,5 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-array-string.g.out b/tst/testspecial/bad-array-string.g.out index d0bd81ee20..34dd31bbd0 100644 --- a/tst/testspecial/bad-array-string.g.out +++ b/tst/testspecial/bad-array-string.g.out @@ -10,5 +10,5 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-array-undef-0.g.out b/tst/testspecial/bad-array-undef-0.g.out index 5ea205de9a..8ce908cbd9 100644 --- a/tst/testspecial/bad-array-undef-0.g.out +++ b/tst/testspecial/bad-array-undef-0.g.out @@ -10,5 +10,5 @@ Stack trace: @ *stdin*:4 ( ) called from read-eval loop at *stdin*:6 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-array-undef-1.g.out b/tst/testspecial/bad-array-undef-1.g.out index 7efcc85219..d172c4f20f 100644 --- a/tst/testspecial/bad-array-undef-1.g.out +++ b/tst/testspecial/bad-array-undef-1.g.out @@ -11,5 +11,5 @@ Stack trace: @ *stdin*:5 ( ) called from read-eval loop at *stdin*:7 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/bad-minus.g.out b/tst/testspecial/bad-minus.g.out index ec55c46e87..42a34245bd 100644 --- a/tst/testspecial/bad-minus.g.out +++ b/tst/testspecial/bad-minus.g.out @@ -14,5 +14,5 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> QUIT; diff --git a/tst/testspecial/break-loop-loop.g.out b/tst/testspecial/break-loop-loop.g.out index 4da0087abd..c1f24f4ce9 100644 --- a/tst/testspecial/break-loop-loop.g.out +++ b/tst/testspecial/break-loop-loop.g.out @@ -9,8 +9,8 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> x; 1 brk> y; diff --git a/tst/testspecial/broken-test.g.out b/tst/testspecial/broken-test.g.out index bbe429da39..f51326c8ce 100644 --- a/tst/testspecial/broken-test.g.out +++ b/tst/testspecial/broken-test.g.out @@ -9,7 +9,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-3.tst", rec(width := 800)); Error, Invalid test file at broken-test-3.tst:5 @@ -22,7 +22,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-4.tst", rec(width := 800)); Error, Invalid test file: Nested #@if at broken-test-4.tst:2 @@ -35,7 +35,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-5.tst", rec(width := 800)); Error, Invalid test file: two #@else at broken-test-5.tst:7 @@ -48,7 +48,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-6.tst", rec(width := 800)); Error, Invalid test file: Continuation prompt '> ' followed by a tab, expected a regular space at broken-test-6.tst:3 @@ -61,7 +61,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-7.tst", rec(width := 800)); Error, Invalid test file: #@elif after #@else at broken-test-7.tst:7 @@ -74,7 +74,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-8.tst", rec(width := 800)); Error, Invalid test file: #@elif without #@if at broken-test-8.tst:1 @@ -87,7 +87,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("broken-test-9.tst", rec(width := 800)); Error, Invalid test file: Unterminated #@if at broken-test-9.tst:7 @@ -100,7 +100,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("invalidtestfile.tst", rec(width := 800)); Error, Invalid test file at invalidtestfile.tst:7 @@ -113,7 +113,7 @@ Stack trace: @ GAPROOT/lib/test.gi:LINE ( ) called from read-eval loop at *stdin*:2 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Test("empty.tst", rec(width := 800)); #I Test: File does not contain any tests! diff --git a/tst/testspecial/bugfix-2019-09-27-LastPV.g.out b/tst/testspecial/bugfix-2019-09-27-LastPV.g.out index bfb7f37450..c10ae80f68 100644 --- a/tst/testspecial/bugfix-2019-09-27-LastPV.g.out +++ b/tst/testspecial/bugfix-2019-09-27-LastPV.g.out @@ -7,7 +7,7 @@ gap> old_OnBreak:=OnBreak;; gap> OnBreak:=fail;; # prevent backtrace with line numbers that keep chaning gap> View([[badgroup]]); # <- trigger break loop Error, Rational operations: must not be zero -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; [ [ gap> OnBreak:=old_OnBreak;; diff --git a/tst/testspecial/current-env.g.out b/tst/testspecial/current-env.g.out index e90991e7e2..68ec461013 100644 --- a/tst/testspecial/current-env.g.out +++ b/tst/testspecial/current-env.g.out @@ -16,8 +16,8 @@ od; @ *stdin*:6 ( ) called from read-eval loop at *stdin*:9 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> ContentsLVars(CurrentEnv()); rec( func := function( n ) ... end, names := [ "n" ], values := [ 1 ] ) brk> DownEnv(); ContentsLVars(CurrentEnv()); diff --git a/tst/testspecial/debug-var.g.out b/tst/testspecial/debug-var.g.out index ab72b2459f..bbff49cdd5 100644 --- a/tst/testspecial/debug-var.g.out +++ b/tst/testspecial/debug-var.g.out @@ -19,8 +19,8 @@ Stack trace: @ *stdin*:12 ( ) called from read-eval loop at *stdin*:14 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> brk> x; # access global 1 @@ -61,7 +61,7 @@ Stack trace: @ *stdin*:12 ( ) called from read-eval loop at *errin*:12 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk_2> quit; brk> brk> z; # access local @@ -80,7 +80,7 @@ Stack trace: @ *stdin*:12 ( ) called from read-eval loop at *errin*:17 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk_2> quit; brk> brk> return; @@ -106,8 +106,8 @@ Stack trace: @ *stdin*:12 ( ) called from read-eval loop at *stdin*:23 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> h(2); Error, foobar Stack trace: @@ -119,8 +119,8 @@ Stack trace: @ *stdin*:12 ( ) called from read-eval loop at *errin*:1 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk_2> brk_2> y; # access higher local as debug var 2 diff --git a/tst/testspecial/error-in-InputTextString.g.out b/tst/testspecial/error-in-InputTextString.g.out index 36b19d8b23..f27a402920 100644 --- a/tst/testspecial/error-in-InputTextString.g.out +++ b/tst/testspecial/error-in-InputTextString.g.out @@ -2,6 +2,6 @@ gap> Read(InputTextString("Print(1 + [()]);")); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `+' on 2 arguments called from read-eval loop at stream:1 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> QUIT; diff --git a/tst/testspecial/func-and-proc-call-trace.g.out b/tst/testspecial/func-and-proc-call-trace.g.out index 046b27f874..e58f4ef668 100644 --- a/tst/testspecial/func-and-proc-call-trace.g.out +++ b/tst/testspecial/func-and-proc-call-trace.g.out @@ -10,7 +10,7 @@ Stack trace: @ *stdin*:4 ( ) called from read-eval loop at *stdin*:6 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -27,7 +27,7 @@ Stack trace: @ *stdin*:9 ( ) called from read-eval loop at *stdin*:11 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -44,7 +44,7 @@ Stack trace: @ *stdin*:14 ( ) called from read-eval loop at *stdin*:16 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -61,7 +61,7 @@ Stack trace: @ *stdin*:19 ( ) called from read-eval loop at *stdin*:21 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -78,7 +78,7 @@ Stack trace: @ *stdin*:24 ( ) called from read-eval loop at *stdin*:26 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -95,7 +95,7 @@ Stack trace: @ *stdin*:29 ( ) called from read-eval loop at *stdin*:31 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -112,7 +112,7 @@ Stack trace: @ *stdin*:34 ( ) called from read-eval loop at *stdin*:36 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -129,7 +129,7 @@ Stack trace: @ *stdin*:39 ( ) called from read-eval loop at *stdin*:41 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -146,7 +146,7 @@ Stack trace: @ *stdin*:44 ( ) called from read-eval loop at *stdin*:46 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -163,7 +163,7 @@ Stack trace: @ *stdin*:49 ( ) called from read-eval loop at *stdin*:51 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -180,7 +180,7 @@ Stack trace: @ *stdin*:54 ( ) called from read-eval loop at *stdin*:56 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -197,7 +197,7 @@ Stack trace: @ *stdin*:59 ( ) called from read-eval loop at *stdin*:61 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -214,7 +214,7 @@ Stack trace: @ *stdin*:64 ( ) called from read-eval loop at *stdin*:66 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -231,7 +231,7 @@ Stack trace: @ *stdin*:69 ( ) called from read-eval loop at *stdin*:71 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -248,7 +248,7 @@ Stack trace: @ *stdin*:74 ( ) called from read-eval loop at *stdin*:76 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); @@ -265,7 +265,7 @@ Stack trace: @ *stdin*:79 ( ) called from read-eval loop at *stdin*:81 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> quit; gap> Print("\n\n"); diff --git a/tst/testspecial/last-access.g.out b/tst/testspecial/last-access.g.out index 78d756615f..2bc0c8131e 100644 --- a/tst/testspecial/last-access.g.out +++ b/tst/testspecial/last-access.g.out @@ -6,8 +6,8 @@ gap> 1;2;3;[last,last2,last3]; gap> Error("err"); Error, err not in any function at *stdin*:3 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> 1;2;3;[last,last2,last3]; 1 2 diff --git a/tst/testspecial/line-continuation.g.out b/tst/testspecial/line-continuation.g.out index 2f06f33fdc..a6ed2a8a24 100644 --- a/tst/testspecial/line-continuation.g.out +++ b/tst/testspecial/line-continuation.g.out @@ -11,8 +11,8 @@ Stack trace: @ GAPROOT/lib/string.gi:LINE ( ) called from read-eval loop at *stdin*:6 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; gap> EvalString("123\\\r\n45x;"); Error, Variable: '12345x' must have a value @@ -23,7 +23,7 @@ Stack trace: @ GAPROOT/lib/string.gi:LINE ( ) called from read-eval loop at *stdin*:6 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; gap> QUIT; diff --git a/tst/testspecial/mem-overflow.g.out b/tst/testspecial/mem-overflow.g.out index 1f9147a44c..9de037b50f 100644 --- a/tst/testspecial/mem-overflow.g.out +++ b/tst/testspecial/mem-overflow.g.out @@ -7,8 +7,8 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:3 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> # ... then we should be in a break loop. Exit that, perform some other computations. brk> quit; gap> Factorial(42); diff --git a/tst/testspecial/method-not-found-where.g.out b/tst/testspecial/method-not-found-where.g.out index eaaeaee161..5f80b728c7 100644 --- a/tst/testspecial/method-not-found-where.g.out +++ b/tst/testspecial/method-not-found-where.g.out @@ -8,7 +8,7 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:4 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> ShowMethods(1); #I Searching Method for IsDiagonalMatrix with 1 argument: #I Total: 3 entries diff --git a/tst/testspecial/method-not-found.g.out b/tst/testspecial/method-not-found.g.out index fa8a04ad87..2001ae951b 100644 --- a/tst/testspecial/method-not-found.g.out +++ b/tst/testspecial/method-not-found.g.out @@ -7,7 +7,7 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:3 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> return; 'return' cannot be used in this read-eval-print loop brk> QUIT; diff --git a/tst/testspecial/print-formatting.g.out b/tst/testspecial/print-formatting.g.out index 91e7af8741..11a0eb6932 100644 --- a/tst/testspecial/print-formatting.g.out +++ b/tst/testspecial/print-formatting.g.out @@ -23,7 +23,7 @@ gap> # test formatting status for errout gap> 1/0; # trigger a break loop Error, Rational operations: must not be zero not in any function at *stdin*:14 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> old := PrintFormattingStatus("*errout*"); true brk> SetPrintFormattingStatus("*errout*", false); diff --git a/tst/testspecial/repl-syntax-err.g.out b/tst/testspecial/repl-syntax-err.g.out index 7f31dd0233..783de07a05 100644 --- a/tst/testspecial/repl-syntax-err.g.out +++ b/tst/testspecial/repl-syntax-err.g.out @@ -8,8 +8,8 @@ gap> # fixed. gap> Error(""): Error, not in any function at *stdin*:9 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; Syntax error: ; expected Error(""): diff --git a/tst/testspecial/stack-depth-func.g.out b/tst/testspecial/stack-depth-func.g.out index 37a8116566..26446d3435 100644 --- a/tst/testspecial/stack-depth-func.g.out +++ b/tst/testspecial/stack-depth-func.g.out @@ -14,8 +14,8 @@ Stack trace: [5] f( ); @ *stdin*:2 ... at *stdin*:3 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; # try once more Error, recursion depth trap (10000) Stack trace: @@ -30,6 +30,6 @@ Stack trace: [5] f( ); @ *stdin*:2 ... at *stdin*:3 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/stack-depth-func2.g.out b/tst/testspecial/stack-depth-func2.g.out index d41cac1c18..f82d7ece2f 100644 --- a/tst/testspecial/stack-depth-func2.g.out +++ b/tst/testspecial/stack-depth-func2.g.out @@ -14,8 +14,8 @@ Stack trace: [5] f( ) @ *stdin*:2 ... at *stdin*:3 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; # try once more Error, recursion depth trap (10000) Stack trace: @@ -30,6 +30,6 @@ Stack trace: [5] f( ) @ *stdin*:2 ... at *stdin*:3 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/stack-depth-rec.g.out b/tst/testspecial/stack-depth-rec.g.out index 3a2f0bcb5a..88d55ca50e 100644 --- a/tst/testspecial/stack-depth-rec.g.out +++ b/tst/testspecial/stack-depth-rec.g.out @@ -82,8 +82,8 @@ Stack trace: [5] String( record.(nam) ) @ GAPROOT/lib/record.gi:LINE ... at *stdin*:4 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> return; # try once more Error, recursion depth trap (5000) Stack trace: @@ -98,6 +98,6 @@ Stack trace: [5] String( record.(nam) ) @ GAPROOT/lib/record.gi:LINE ... at *stdin*:4 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/stack-trace-depth.g.out b/tst/testspecial/stack-trace-depth.g.out index 9c12a52a9a..bb06fe9547 100644 --- a/tst/testspecial/stack-trace-depth.g.out +++ b/tst/testspecial/stack-trace-depth.g.out @@ -45,8 +45,8 @@ Stack trace: [5] f8( ) @ *stdin*:15 ... at *stdin*:35 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> SetUserPreference("WhereDepth", 12); brk> Where(); Stack trace: diff --git a/tst/testspecial/stack-trace-label.g.out b/tst/testspecial/stack-trace-label.g.out index a7a71b90c8..2397215b7c 100644 --- a/tst/testspecial/stack-trace-label.g.out +++ b/tst/testspecial/stack-trace-label.g.out @@ -8,7 +8,7 @@ Stack trace: @ *stdin*:3 ( ) called from read-eval loop at *stdin*:5 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> quit; gap> QUIT; diff --git a/tst/testspecial/syntax-tree-error.g.out b/tst/testspecial/syntax-tree-error.g.out index 96794103f1..bff4a4d368 100644 --- a/tst/testspecial/syntax-tree-error.g.out +++ b/tst/testspecial/syntax-tree-error.g.out @@ -12,6 +12,6 @@ Stack trace: *[1] ( ) called from read-eval loop at *stdin*:8 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/top-level-error.g.out b/tst/testspecial/top-level-error.g.out index f27f9df6d9..b4a6915bca 100644 --- a/tst/testspecial/top-level-error.g.out +++ b/tst/testspecial/top-level-error.g.out @@ -1,6 +1,6 @@ gap> Error("foo"); Error, foo not in any function at *stdin*:2 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk> QUIT; diff --git a/tst/testspecial/up-down-env.g.out b/tst/testspecial/up-down-env.g.out index 93062e655b..a3c9ea82b0 100644 --- a/tst/testspecial/up-down-env.g.out +++ b/tst/testspecial/up-down-env.g.out @@ -19,7 +19,7 @@ Stack trace: [5] f( lvl - 1 ) @ *stdin*:7 ... at *stdin*:8 -type 'quit;' to quit to outer loop +you can enter 'quit;' to quit to outer loop brk> UpEnv(1); lvl; 0 brk> DownEnv(1); lvl; @@ -56,8 +56,8 @@ brk> ## brk> Read("top-level-error.g"); Error, foo not in any function at top-level-error.g:1 -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue +you can enter 'quit;' to quit to outer loop, or +you can enter 'return;' to continue brk_2> Where(20); not in any function at *errin*:1 brk_2> lvl; # since `Read` started a fresh execution context, we can't access lvl here From 0ad351b446f620bfd50180b67550be63a532de69 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 10 Jun 2026 23:11:13 +0200 Subject: [PATCH 37/50] Remove dev/migratedoc.tex and doc/tut/migrat.xml (#6431) They are not referenced anywhere and nowadays at most of historical interest. --- dev/migratedoc.tex | 1141 ---------------------------------------- doc/tut/migrat.xml | 1227 -------------------------------------------- 2 files changed, 2368 deletions(-) delete mode 100644 dev/migratedoc.tex delete mode 100644 doc/tut/migrat.xml diff --git a/dev/migratedoc.tex b/dev/migratedoc.tex deleted file mode 100644 index 8e3f02270e..0000000000 --- a/dev/migratedoc.tex +++ /dev/null @@ -1,1141 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% -%W migratedoc.tex GAP documentation Thomas Breuer -%W & Frank Celler -%W & Martin Schoenert -%W & Heiko Theissen -%% -%% -%Y Copyright 1997, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany -%% -%% self-contained document with the former chapter -%% ``Migrating to GAP 4'' of the GAP Tutorial -%% -\input gapmacro -\BeginningOfBook{mig} -\TitlePage{ - \centerline{\titlefont GAP}\bigskip - \centerline{\secfont Release 4.5}\medskip - \centerline{\secfont May 2012}\bigskip\bigskip - \centerline{\titlefont Migrating to GAP 4}\vfill - \centerline{\secfont The GAP Group}\bigskip - \centerline{\secfont https://www.gap-system.org} -} -\TableOfContents -\FrontMatter -Copyright {\copyright} (1987-2012) for the core -part of the {\GAP} system by the {\GAP} Group. - -Most parts of the {\GAP} distribution, including -the core part of the {\GAP} system, are distributed -under the terms of the GNU General Public License -(see {\tt{https://www.gnu.org/licenses/gpl.html}} -or the file {\tt GPL} in the {\tt etc} directory -of the {\GAP} installation). - -More detailed information about copyright and -licenses of parts of this distribution can be -found in the {\GAP}~4 Reference manual -(see {\bf Reference: Copyright and License}). - -{\GAP} is developed over a long time and has -many authors and contributors. More detailed -information can be found in the {\GAP}~4 -Reference manual (see {\bf Reference: Authors and Maintainers}). - -\Chapters - -\Chapter{Migrating to GAP 4} - -This chapter is intended to give users who have experience with {\GAP}~3 -some information about what has changed in {\GAP}~4. -In particular, it informs about changed command line options -(see~"Changed Command Line Options"), -the new global variable `fail' (see~"Fail"), -some functions that have changed their behaviour -(see~"Changed Functionality") or their names -(see~"Changed Variable Names"), -and some conventions used for variable names (see~"Naming Conventions"). - -Then the new concepts of {\GAP}~4 are sketched, -first that of mutability or immutability (see~"Immutable Objects"), -with the explanation of related changes in functions that copy objects -(see~"Copy"), -then the concepts of operations and method selection, which are compared -with the use of operations records in {\GAP}~3 -(see~"Attributes vs. Record Components", "Operations Records", -and~"Operations vs. Dispatcher Functions"). - -More local changes affect the concepts of notions of generation -(see~"Different Notions of Generation"), -of parents (see~"Parents and Subgroups"), -of homomorphisms (see~"Homomorphisms vs. General Mappings", -"Homomorphisms vs. Factor Structures", -and~"Isomorphisms vs. Isomorphic Structures"), -how elements in finitely presented groups are treated -(see~"Elements of Finitely Presented Groups"), -how information about progress of computations can be obtained -(see~"The Info Mechanism"), -and how one gets information in a `break' loop -(see~"Debugging"). - -%Commented out: no longer provided with GAP 4.5 -%While a ``{\GAP}~3 compatibility mode'' is provided -%(see "Compatibility Mode"), -%its use will disable some of the new features of {\GAP}~4. -%Also it certainly can only try to provide partial compatibility. - -%For a detailed explanation of the new features and concepts of {\GAP}~4, -%see the manual ``Programming in GAP''. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Changed Command Line Options} - -In {\GAP}~4, the `-l' option is used to specify the *root directory* -(see ``GAP Root Directory'' in the {\GAP}~4 Reference Manual) -of the {\GAP} distribution, -which is the directory containing the `lib' and `doc' subdirectories. -Note that in {\GAP}~3 this option was used to specify the path to the -`lib' directory. - -The `-h' option of {\GAP}~3 has been removed, -the path(s) for the documentation are deduced automatically in {\GAP}~4. - -The option `-g' is now used to print information only about full garbage -collections. -The new option `-g -g' generates information about partial -garbage collections too. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Fail} - -There is a new global variable - -\>`fail'{fail instead of false} - -in {\GAP}~4. -It is intended as a return value of a function for the case that it -could not perform its task. -For example, `Inverse' returns `fail' if it is called with a singular -matrix, and `Position' returns `fail' if the second argument is not -contained in the list given as first argument. - -{\GAP}~3 handled such situations by either signalling an error, -for example if it was asked for the inverse of a singular matrix, -or by (mis)using `false' as return value, as in the example `Position'. -Note that in the first example, in {\GAP}~3 it was necessary to check -the invertibility of a matrix before one could safely ask for its -inverse, which meant that roughly the same work was done twice. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Changed Functionality} - -Some functions that were already available in {\GAP}~3 behave -differently in {\GAP}~4. This section lists them. - -\>Orbit( ,) - -The {\GAP}~3 manual promised that would be the first entry of the -resulting orbit. This was wrong already there in a few cases, therefore -{\GAP}~4 does not promise anything about the ordering of points in an orbit. - -\>Order( ) - -only takes the element and computes its multiplicative order. -%Calling `Order' with two arguments is permitted only in the -%{\GAP}~3 compatibility mode, see~"Compatibility Mode". -(Note that it does not make sense anymore to specify a group as -first argument w.r.t. which the order of the second argument shall -be computed, see~"Elements of Finitely Presented Groups".) - -\>Position( , ) - -If is not contained in the list then `fail' is returned -in {\GAP}~4 (see~"Fail"), whereas `false' was returned in {\GAP}~3. - - -\>PermGroupOps.ElementProperty( , [, ] ) - -In {\GAP}~3, this function took either two or three arguments, -the optional argument being a subgroup of that stabilizes -in the sense that for any element in , -either all elements or no element in the coset ` \* ' have the -property . - -The {\GAP}~4 function `ElementProperty', however, -takes between two and four arguments, -and the subgroup known from {\GAP}~3 has to be entered as the *fourth* -argument *not* the third. -(The third argument in the {\GAP}~4 function denotes a subgroup -stabilizing in the sense that either all elements or no element -in right cosets ` \* ' have the property .) - -(This discrepancy was discovered only in March~2002, -short before the release of {\GAP}~4.3.) - - -\>Print( , ... ) - -Objects may appear on the screen in a different way, -depending on whether they are printed by the read eval print loop -or by an explicit call of `Print'. -The reason is that the read eval print loop calls the operation `ViewObj' -and not `PrintObj', whereas `Print' calls `PrintObj' for each of its -arguments. -This permits the installation of methods for printing objects in a short form -in the read eval print loop while retaining `Print' to display -the object completely. -See also Section ``View and Print'' in the {\GAP}~4 Reference Manual. - -(`PrintObj' is installed as standard method `ViewObj', so it is -not really necessary to have a `ViewObj' method for an object.) - -\>PrintTo( , , ... ) - -In {\GAP}~3, `PrintTo' could be (mis)used to ``redirect'' the text -*printed* by a function (that is, *not* only the output of a function) -to a file by entering the function call as second argument. -This was used mainly in order to avoid many calls of `AppendTo'. -In {\GAP}~4, this feature has disappeared. -One can use streams (see Chapter ``Streams'' in the {\GAP}~4 Reference Manual) -instead in order to write files efficiently. - -\break - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Changed Variable Names} - -\indextt{AgGroup} -\indextt{ApplyFunc} -\indextt{Backtrace} -\indextt{CharTable} -\indextt{Denominator} -\indextt{DepthVector} -\indextt{Elements} -\indextt{IsBijection} -\indextt{IsFunc} -\indextt{IsMat} -\indextt{IsRec} -\indextt{IsSet} -\indextt{LengthWord} -\indextt{NOfCyc} -\indextt{Numerator} -\indextt{RandomInvertableMat} -\indextt{RecFields} -\indextt{X} - -Some functions have changed their name without changing the -functionality. -A -- probably incomplete -- list follows -\begintt - GAP 3 GAP 4 - - AgGroup PcGroup # (also composita) - ApplyFunc CallFuncList - Backtrace Where - CharTable CharacterTable # (also composita) - Denominator DenominatorRat - DepthVector PositionNonZero - Elements AsSSortedList - IsBijection IsBijective - IsFunc IsFunction - IsMat IsMatrix - IsRec IsRecord - IsSet IsSSortedList - LengthWord Length - NOfCyc Conductor - Numerator NumeratorRat - NormedVector NormedRowVector - Operation Action # (also composita) - Order(G,g) Order(g) - OrderMat Order - OrderPerm Order - RandomInvertableMat RandomInvertibleMat - RecFields RecNames - X Indeterminate -\endtt - -%See Section~"Compatibility Mode" for a way to make the old names -%available again. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Naming Conventions} - -The way functions are named has been unified in {\GAP}~4. -This might help to memorize or even guess names of library functions. - -If a variable name consists of several words then the first -letter of each word is capitalized. - -If the first part of the name of a function is a verb then the function -may modify its argument(s) but does not return anything, -for example `Append' appends the list given as second argument to the -list given as first argument. -Otherwise the function returns an object without changing the arguments, -for example `Concatenation' returns the concatenation of the lists -given as arguments. - -If the name of a function contains the word `By' then the return value is -thought of as built in a certain way from the parts given as arguments. -For example, `GroupByGenerators' returns a group built from its group -generators, and creating a group as a factor group of a given group -by a normal subgroup can be done by taking the image of -`NaturalHomomorphismByNormalSubgroup' -(see also~"Homomorphisms vs. Factor Structures"). -Other examples of ```By''' functions are `GroupHomomorphismByImages' and -`UnivariateLaurentPolynomialByCoefficients'. - -If the name of a function contains the word `Of' then the return value is -thought of as information deduced from the arguments. -Usually such functions are attributes -(see ``Attributes'' in the {\GAP}~4 Reference Manual). -Examples are `GeneratorsOfGroup', which returns a list of generators for -the group entered as argument, or `DiagonalOfMat'. - -For the setter and tester functions of an attribute -(see~"Attributes vs. Record Components" in this document -and ``Attributes'' in the {\GAP}~4 Reference Manual) -the names `Set' resp.~`Has' are available. - -If the name of a function ends with `NC' then there is another -function with the same name except that the `NC' is missing. -`NC' stands for ``no check''. -When is called then it checks whether its arguments are valid, -and if so then it calls . -The functions `SubgroupNC' and `Subgroup' are a typical example. - -The idea is that the possibly time consuming check of the arguments -can be omitted if one is sure that they are unnecessary. -For example, if an algorithm produces generators of the derived subgroup -of a group then it is guaranteed that they lie in the original group; -`Subgroup' would check this, and `SubgroupNC' omits the check. - -Needless to say, all these rules are not followed slavishly, -for example there is one operation `Zero' instead of two operations -`ZeroOfElement' and `ZeroOfAdditiveGroup'. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Immutable Objects} - -{\GAP}~4 supports ``immutable'' objects. Such objects cannot be -changed, attempting to do so issues an error. Typically attribute -values are immutable, and also the results of those binary arithmetic -operations where both arguments are immutable. -For example, `[1..100]+[1..100]' is a -mutable list and `2 \* Immutable([1..100])' is an immutable -list, both are equal to the (mutable) list `[2,4..200]'. - -There is no way to *make* an immutable object mutable, one can only -get a mutable copy by `ShallowCopy'. The other way round, -`MakeImmutable' makes a (mutable or immutable) object and all its -subobjects immutable; one must be very careful to use `MakeImmutable' -only for those objects that are really newly created, for such objects -the advantage over `Immutable' is that no copy is made. - -More about immutability can be found in Sections ``Immutability'' in -the {\GAP}~4 Tutorial and ``Mutability and Copyability'' in the {\GAP}~4 -Reference Manual. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Copy} - -\indextt{StructuralCopy} -\indextt{ShallowCopy} -The function `Copy' of {\GAP}~3 is not supported in {\GAP}~4. This -function was used to create a copy of its argument with -the properties that and had no subobjects in common and -that if two subobjects of were identical then also the -corresponding subobjects of were identical. - -The possibility of having immutable objects (see~"Immutable Objects") can and -should be used to avoid unnecessary copying. -Namely, given an immutable object one needs to copy it only if one wants -to get a modified object, and in such a situation usually it is -sufficient to use `ShallowCopy', or at least one knows how deep one must -copy in order to do the changes one has in mind. - -For example, suppose you have a matrix group, and you want to -construct a list of matrices by modifying the group generators. This -list of generators is immutable, so you call `ShallowCopy' to get a -mutable list that contains the same matrices. If you only want to -exchange some of them, or to append some other matrices, this shallow -copy is already what you need. So suppose that you are interested in -a list of matrices where some rows are also changed. For that, you -call `ShallowCopy' for the matrices in question, and you get matrices -whose rows can be changed. If you want to change single entries in -some rows, `ShallowCopy' must be called to get mutable copies of these -rows. Note that in all these situations there is no danger to change, -i.e., to destroy the original generators of the matrix group. - -If one needs the facility of the `Copy' function of {\GAP}~3 to get a -copy with the same structure then one can use the new {\GAP}~4 -function `StructuralCopy'. It returns a structural copy that has no -*mutable* subobject in common with its argument. So if -`StructuralCopy' is called with an immutable object then this object -itself is returned, and if `StructuralCopy' is called with a mutable -list of immutable objects then a shallow copy of this list is -returned. - -Note that `ShallowCopy' now is an operation. So if you create your -own type of (copyable) objects then you must define what a shallow -copy of these objects is, and install an appropriate method. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Attributes vs. Record Components} - -In {\GAP}~3, many complex objects were represented via records, for -example all domains. Information about these objects was stored in -components of these records. For the user, this was usually not -relevant, since there were functions for computing information about -the objects in question. For example, if one was interested in the -size of a group then one could call `Size'. - -But since it was guaranteed that the size of a domain was stored -as value of the component `size', it was allowed to access `.size' -if this component was bound, and a check for this was possible via -`IsBound( .size )'. - -In {\GAP}~4, only the access via functions is admissible. One reason -is the following basic rule. - -*From the information that a given {\GAP}~4 object is for example a -domain, one cannot conclude that this object has a certain -representation.* - -For attributes like `Size', {\GAP}~4 provides two related functions, -the *setter* and the *tester* of the attribute, which can be used to -set an attribute value and to check whether the value of an attribute -is already stored for an object (see also ``Attributes'' in the {\GAP}~4 -Reference Manual). For example, if is a domain in {\GAP}~4 then -`HasSize( )' is `true' if the size of is already stored, and -`false' otherwise. In the latter case, if you know that the size of - is then you may store it by `SetSize( , )'. - -Besides the flexibility in the internal representation of objects, -storing information only via function calls has also the advantage -that {\GAP}~4 is able to draw conclusions automatically. For example, -as soon as it is stored that a group is nilpotent, it is also stored -that it is solvable, see Chapters ``Types of Objects'' and -``Method Selection'' in the {\GAP}~4 Reference Manual for the details. - -As a consequence, you cannot put your favourite information into a -domain by assigning it to a new component like -`.myPrivateInfo'. Instead you can introduce a new attribute and -then use its setter, -see Section ``Attributes'' in the {\GAP}~4 Reference Manual. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Different Notions of Generation} - -As in {\GAP}~3, a *domain* in {\GAP}~4 is a structured set. - -The same set can have different structures, for example a field can be -regarded as a ring or as an algebra or vector space over a subfield. - -In {\GAP}~3, however, an object representing a ring did not represent -a field, and an object representing a field did not represent a ring. -One reason for this was that the record component `generators' was -used to denote the appropriate generators of the domain. For a ring -, the component `.generators' was a list of ring generators, and -for a field , `.generators' was a list of field generators. - -{\GAP}~4 cleans this up, -see ``Notions of Generation'' in the {\GAP}~4 Tutorial. It supports -many different notions of generation, for example one can ask for -magma generators of a group or for generators of a field as an additive -group. A subtle but important distinction is that between generators -of an algebra and of an algebra-with-one. - -So the attributes `GeneratorsOfGroup', `GeneratorsOfMagma', -`GeneratorsOfRing', `GeneratorsOfField', `GeneratorsOfVectorSpace', -and so on, replace the access to the `generators' component. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Operations Records} - -Already in {\GAP}~3 there were several functions that were applicable -to many different kinds of objects, for example `Size' could be -applied to any domain, and the binary infix multiplication `*' could -be used to multiply two matrices, an integer with a row vector, or a -permutation with a permutation group. This was implemented as -follows. Functions like `Size' and `*' tried to find out what -situation was described by its arguments, and then it called a more -specific function to compute the desired information. These more -specific functions, let us call them *methods* as they are also called -in {\GAP}~4, were stored in so-called *operations records* of the -arguments. - -For example, every domain in {\GAP}~3 was represented as a record, and -the operations record was stored in the record component `operations'. -If `Size' was called for the domain then the method to compute the -size of the domain was found as value of the `Size' component of the -operations record. - -This was fine for functions taking only one argument, and in principle -it is possible that for those functions an object stored an optimal -method in its operations record. But in the case of more arguments -this is not possible. In a multiplication of two objects in {\GAP}~3, -one had to choose between the methods stored in the operations records -of the arguments, and if for example the method stored for the left -operand was called, this method had to handle all possible right -operands. - -So operations records turned out to be not flexible enough. In -{\GAP}~4, operations records are not supported -%(see~"Compatibility Mode" for a possibility to use your {\GAP}~3 -%code that utilizes operations records, at least to some extent). -A detailed description -of the new mechanism to select methods can be found in -Chapter ``Method Selection'' in the {\GAP}~4 Reference Manual. - -An important point is that the new mechanism allows {\GAP} to take the -relation between arguments into account. So it is possible (and -recommended) to install different methods for different relations -between the arguments. Note that such methods need not do the -extensive argument checking that was necessary in {\GAP}~3, because -most of the checks are done already by the method selection mechanism. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Operations vs. Dispatcher Functions} - -{\GAP}~3 functions like `Size', `CommutatorSubgroup', or -`SylowSubgroup' did mainly call an appropriate method (see~"Operations -Records") after they had checked their arguments. Such functions were -called *dispatchers* in {\GAP}~3. In {\GAP}~4, many dispatchers have -been replaced by *operations*, due to the fact that methods are no -longer stored in operations records (see ``Method Selection'' in -in the {\GAP}~4 Reference Manual for the details). - -Most dispatchers taking only one argument were treated in a special -way in {\GAP}~3, they had the additional task of storing computed -values and using these values in subsequent calls. For example, the -dispatcher `Size' first checked whether the size of the argument was -already stored, and if so then this value was returned; otherwise a -method was called, the value returned by this method was stored in the -argument, and then returned by `Size'. - -In {\GAP}~4, computed values of operations that take one argument -(these operations are called *attributes*) are also stored, only the -mechanism to achieve this has changed, see the sections ``Attributes'' -and ``Properties'' in the {\GAP}~4 Reference Manual. - -So the behaviour of `Size' is the same in {\GAP}~3 and {\GAP}~4. But -note that in {\GAP}~4, it is not possible to access `.size', -see~"Attributes vs. Record Components". As described in~"Operations -Records", {\GAP}~4 does not admit ``bypassing the dispatcher'' by -calling for example `.operations.Size'. This was done in {\GAP}~3 -often for efficiency reasons, but the method selection mechanism of -{\GAP}~4 is fast enough to make this unnecessary. - -If you had written your own dispatchers and put your own methods into -existing operations records then this code will not work in {\GAP}~4. -See ``Creating New Objects'' and ``Method Selection'' in the {\GAP}~4 -Reference Manual for a description of how to define operations and -to install methods. - -Finally, some functions in {\GAP}~3 were hidden in -operations records, e.g., `PermGroupOps.MovedPoints'. -These functions became proper operations in {\GAP}~4. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Parents and Subgroups} - -In {\GAP}~3 there was a strict distinction between parent groups and -subgroups. -The use of the name ``parent'' (instead of ``supergroup'') -was chosen to indicate that the parent of an object was more than just -useful information. -In fact the main reason for the introduction of parents was to provide -a common roof for example for all groups of polycyclic words that -belonged to the same PC-presentation, or for all subgroups of a finitely -presented group (see~"Elements of Finitely Presented Groups"). -A subgroup was never a parent group, and it was possible to create -subgroups only of parent groups. - -In {\GAP}~4 this common roof is provided already by the concept of -*families*, see Section ``Families'' in the {\GAP}~4 Reference Manual. -Thus it is no longer compulsory to use parent groups at all. -On the other hand, parents *may* be used in {\GAP}~4 to provide -information about an object, for example the normalizer of a group in its -parent group may be stored as an attribute value. -Note that there is no restriction on the supergroup that is set to be -the parent, -it is possible to create a subgroup of -any group, this group then being the parent of the new subgroup. -This permits for example chains of subgroups with respective parents, -of arbitrary length. - -As a consequence, the `Parent' command cannot be used in {\GAP}~4 to -test whether the two arguments of `CommutatorSubgroup' fit together, -this is now a question that concerns the relation between the families -of the groups. So the 2-argument version of `Parent' and the now -meaningless function `IsParent' have been abolished. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Homomorphisms vs. General Mappings} - -In {\GAP}~3 there had been a confusion between group homomorphisms and -general mappings, as `GroupHomomorphismByImages' created only a -general mapping that did *not* store whether it was a mapping. This -caused expensive, unwanted, and unnecessary tests whether the mapping -was in fact a group homomorphism. Moreover, the ``official'' -workaround to set some components of the mapping record was quite -unwieldy. - -In {\GAP}~4, `GroupHomomorphismByImages' checks whether the desired -mapping is indeed a group homomorphism; if so then this property is -stored in the returned mapping, otherwise `fail' is returned. If you -want to avoid the checks then you can use -`GroupHomomorphismByImagesNC'. If you want to check whether a general -mapping that respects the group operations is really a group -homomorphism, you can construct it via `GroupGeneralMappingByImages' -and then call `IsGroupHomomorphism' for it. (Note that -`IsGroupHomomorphism' returns `true' if and only if both -`IsGroupGeneralMapping' and `IsMapping' do, so one does in fact check -`IsMapping' in this case.) - -There is *no* function `IsHomomorphism' in {\GAP}~4, -since there are several different operations with respect to which a -mapping can be a homomorphism. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Homomorphisms vs. Factor Structures} - -If $F$ is a factor structure of $G$, with kernel $N$, complete -information about the connection between $F$ and $G$ is provided by -the *natural homomorphism*. - -In {\GAP}~3, the ``official way'' to construct this natural homomorphism -was to create first the factor structure $F$, and then to call -`NaturalHomomorphism' with the arguments $G$ and $F$. -For that, the data necessary to compute the homomorphism was stored in -$F$ when $F$ was constructed. - -In {\GAP}~4, factor structures are not treated in a special way, -in particular they do not store information about a homomorphism. -Instead, the more natural way is taken to construct the natural -homomorphism from $G$ and $N$ by `NaturalHomomorphismByNormalSubgroup' -if $N$ is a normal subgroup of the group $G$, -or by `NaturalHomomorphismByIdeal' if $N$ is an ideal in the ring $G$. -The factor $F$ can then be accessed as the image of this homomorphism, -and of course $G$ is the preimage and $N$ is the kernel. - -Note that {\GAP}~4 does not guarantee anything about the representation -of the factor $F$, it may be a permutation group or a polycyclically -presented group or another kind of group. -Also note that a natural homomorphism need not be surjective. - -A consequence of this change is that {\GAP}~4 does *not* allow you to -construct a natural homomorphism from the groups $G$ and $F$. - -The other common type of homomorphism in {\GAP} 3, ``operation -homomorphisms'', have been replaced (just a name change) by *action -homomorphisms*, which are handled in a similar fashion. That is, an -action homomorphism is constructed from an acting group, an action -domain, and a function describing the operation. The permutation -group arising by the induced action is then the image of this -operation homomorphism. - -The {\GAP}~3 function `Operation' is still supported, under the name `Action', -but from the original group and the result of `Action' it is not -possible to construct the action homomorphism. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Isomorphisms vs. Isomorphic Structures} - -In {\GAP}~3, a different representation of a group could be obtained by -calling `AgGroup' to get an isomorphic polycyclically presented group, -`PermGroup' to get an isomorphic permutation group, and so on. -The returned objects stored an isomorphism in the record component -`bijection'. - -For the same reason as in~"Homomorphisms vs. Factor Structures", -{\GAP}~4 puts emphasis on the isomorphism, -and the isomorphic object in the desired representation can be accessed -as its image. -So you can call `IsomorphismPcGroup' or `IsomorphismPermGroup' in order -to get an isomorphism to a polycyclically presented group or a -permutation group, respectively, and then call `Image' to get the -isomorphic group. - -Note that the image of an action homomorphism with trivial kernel is -also an isomorphic permutation group, but an action homomorphism need -not be surjective, since it may be easier to define it into the full -symmetric group. - -Further note that in {\GAP}~3, a usual application of isomorphisms to -polycyclically presented groups was to utilize the usually more -effective algorithms for solvable groups. However, the new concept of -polycyclic generating systems in {\GAP}~4 makes it possible to apply -these algorithms to arbitrary solvable groups, independent of the -representation. For example, {\GAP}~4 can handle polycyclic -generating systems of solvable permutation groups. So in many cases, -a change of the representation for efficiency reasons may be not -necessary any longer. - -In general `IsomorphismFpGroup' will define a presentation on generators -chosen by the algorithm. The corresponding elements of the original -group can be obtained by the command -\begintt -gens:=List(GeneratorsOfGroup(Image(isofp)),i->PreImagesRepresentative(isofp,i)); -\endtt -If a presentation in the given generators is needed, the command -`IsomorphismFpGroupByGenerators(, )' will produce one. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Elements of Finitely Presented Groups} - -Strictly speaking, {\GAP}~3 did not support elements of finitely -presented groups. Instead, the ``words in abstract generators'' of -the underlying free groups were (mis)used. This caused problems -whenever calculations with elements were involved, the most obvious -ones being wrong results of element comparisons. Also functions -that should in principle work for any group were not applicable to -finitely presented groups. In effect, a finitely presented group had -to be treated in a special way in {\GAP}~3. - -{\GAP}~4 distinguishes free groups and their elements from finitely -presented groups and their elements. Comparing two elements of a -finitely presented group will yield either the correct result or no -result at all. - -Note that in {\GAP}~4, the arithmetic and comparison operations for -group elements do not depend on a context provided by a group that -contains the elements. In particular, in {\GAP}~4 it is not -meaningful to call `Order( , )' for a group and an element -. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Polynomials} - -In {\GAP}~3, polynomials were defined over a field. So a polynomial over -`GF(3)' was different from a polynomial over `GF(9)', even if the -coefficients were exactly the same. - -{\GAP}~4 defines polynomials only over a characteristic. This makes it -possible for example to multiply a polynomial over `GF(3)' with a polynomial -over `GF(9)' without the need to convert the former to the larger field. - -However it has an effect on the result of `DefaultRing' for polynomials: -In {\GAP}~3 the default ring for a polynomial was the polynomial ring of the -field over which the polynomial was defined. In {\GAP}~4 no field is -associated, so (to avoid having to define the algebraic closure as the only -other sensible alternative) the default ring of a polynomial is the -`DefaultRing' of its coefficients. - -This has an effect on `Factors': If no ring is given, a polynomial is -factorized over its `DefaultRing' and so `Factors()' -might return different results. - -To be safe from this problem, if you are not working over prime fields, -rather call `Factors(,)' with the appropriate polynomial ring -and change your code accordingly. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{The Info Mechanism} - -Sometimes it is useful to get information about the progress of a -calculation. -Many {\GAP} functions contain statements to display such information -under certain conditions. - -In {\GAP}~3, these statements were calls to functions such as -`InfoGroup1' or `InfoGroup2', and if the user assigned `Print' to -these variables then this had the effect to switch on the printing of -information. -`InfoGroup2' was used for more detailed information than `InfoGroup1'. -One could switch off the printing again by assigning `Ignore' to the -variables, and `Ignore' was also the default value. - -{\GAP}~4 uses one function `Info' for the same purpose, -which is a function that takes as first argument an *info class* such as -`InfoGroup', as second argument an *info level*, and the print statements -as remaining arguments. -The level of an info class is set to by calling -`SetInfoLevel( , )'. -An `Info' statement is printed only if its second argument is smaller than -or equal to the current info level. -For example, -\beginexample -gap> test:= function( obj ) -> Info( InfoGroup, 2, "This is useful, isn't it?" ); -> return obj; -> end;; -gap> test( 1 ); -1 -gap> SetInfoLevel( InfoGroup, 2 ); -gap> test( 1 ); -#I This is useful, isn't it? -1 -\endexample - -As in {\GAP}~3, if an info statement is ignored then its arguments are -not evaluated. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Section{Debugging} - -\indextt{Backtrace} -\indextt{DownEnv} -\indextt{Where} -If {\GAP}~4 runs into an error or is interrupted, -it enters a break loop. -The command `Where( )', which replaces `Backtrace' of {\GAP}~3, -can be used to display lines of information about the current -function call stack. - -As in {\GAP}~3, access is only possible to the variables of the current -level in the function stack, -but in {\GAP}~4 the function `DownEnv', with a positive or negative -integer as argument, permits one to step down or up in the -stack. - -When interrupting, the first line printed by `Where' actually may be -one level higher, as the following example shows -\begintt -gap> OnBreak := function() Where(0); end;; # eliminate back-tracing on -gap> # entry to break loop -gap> test:= function( n ) -> if n > 3 then Error( "!\n" ); fi; test( n+1 ); end;; -gap> test( 1 ); -Error, ! -Entering break read-eval-print loop ... -you can 'quit;' to quit to outer loop, or -you can 'return;' to continue -brk> Where(); - called from -test( n + 1 ); called from -test( n + 1 ); called from -test( n + 1 ); called from -( ) called from read-eval-loop -brk> n; -4 -brk> DownEnv(); -brk> n; -3 -brk> Where(); - called from -test( n + 1 ); called from -test( n + 1 ); called from -( ) called from read-eval-loop -brk> DownEnv( 2 ); -brk> n; -1 -brk> Where(); - called from -( ) called from read-eval-loop -brk> DownEnv( -2 ); -brk> n; -3 -brk> quit; -gap> OnBreak := Where;; # restore OnBreak to its default value -\endtt - -For purposes of debugging, it can be helpful sometimes, to see what -information is stored within an object. In {\GAP}~3 this was possible using -`RecFields' because the objects in question were represented via records. -For component objects, {\GAP}~4 permits the same by -`NamesOfComponents( )', which will list all components present. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% \Section{Compatibility Mode} -% -% For users who want to use {\GAP}~3 code with as little changes as -% possible, a compatibility mode is provided by {\GAP}~4. -% This mode must be turned on explicitly by the user. -% -% It should be noted that this compatibility mode has not been tested -% thoroughly. -% -% The compatibility mode can be turned on by loading some of the following -% files with `ReadLib'. -% The different files address different aspects of compatibility. -% -% \beginitems -% `compat3a.g' & -% makes some {\GAP}~3 function names available that were changed -% in {\GAP}~4, -% and provides code for some {\GAP}~3 features that were -% deliberately left out from the {\GAP}~4 library. -% For example, -% almost all variable names concerning character theory that are -% mentioned in the {\GAP}~3 manual, -% such as `CharTable' and `SubgroupFusions', -% are available after `compat3a.g' has been read; -% the only exceptions are names of operations records. -% -% `compat3b.g' & -% implements the availability of ``components'' of domains; -% besides components that have no meaning for the rest of the {\GAP}~4 -% library, such as `.myInfo', there are components associated to -% attributes; for example `.size' is redirected to the call of the -% attribute `Size', `IsBound( .size )' to the call of its tester, -% and `.size:= ' to the call of its setter. -% (An important special case is the component `operations', see below.) -% -% `compat3c.g' & -% permits you to implement your own elements represented as records, -% and using operations records to provide a `Print' method and -% the basic arithmetic operations. -% When using operations records, it is probably a good idea to -% use *immutable* operations records; for example, if the results -% of arithmetic operations are records with operations records then -% this avoids to create shallow copies of the operations records -% in the call to `Immutable' for the results. -% \enditems -% -% The following features are accessible only via starting {\GAP} with -% the command line option `-O' and may damage some features of {\GAP}~4 -% permanently for the current session. -% -% With this option, also the files listed above are read automatically. -% -% \beginitems -% `compat3d.g' & -% provides some {\GAP}~3 functions like `Domain', simulates the -% {\GAP}~3 behaviour of `IsString' (to convert a list to string -% representation if possible), and replaces `fail' by `false'; -% these changes destroy parts of the functionality of {\GAP}~4. -% \enditems -% -% Some words concerning the simulation of operations records may be -% necessary. -% -% The operations records of the {\GAP}~3 library, such as `DomainOps' -% and `GroupOps', are available *only* for access to their components, -% whose values are {\GAP}~4 operations; for example, the value of both -% `DomainOps.Size' and `GroupOps.Size' is the operation `Size'. So it -% is *not* safely possible to delegate from a `Size' method in another -% operations record to `DomainOps.Size'. Also it is not possible to -% change these predefined operations records. -% -% If one wants to install individual methods for a given object -% via the mechanism of operations records then one can construct a new -% operations record with `OperationsRecord', assign the desired methods -% to components of this record, and then assign the operations record to -% `.operations'. Whenever an operation that is associated with a -% component of the operations record is called with as first -% argument, the value of is chosen as the method. -% -% In the case of the binary operations `=', `\<', `+', `-', `*', `/', -% `Comm', and `LeftQuotient', -% this also happens if is the right-hand argument. -% As in {\GAP}~3, if both arguments of one of the above binary operations -% have operations records containing a function for this operation, -% then the function in the operations record of the right-hand argument -% is chosen. -% -% We give a small example how the compatibility mode works. -% -% Suppose we want to deal with new objects that are derived from known -% field elements by distorting their multiplication. Namely, let $a'$ -% and $b'$ be the new objects corresponding to the field elements $a$, -% $b$, and define $a' \* b' = a b - a - b + 2$. -% -% In {\GAP}~3, this problem was solved by representing each new object -% by a record that stored the corresponding ``old'' object and an -% operations record, where the latter was a record containing the -% functions applicable to the new object. After the library file -% `compat3c.g' has been read, we can use this construction of the -% operations record and of the new objects. Note that operations -% records must be created with the function `OperationsRecord' (this was -% also the norm in {\GAP}~3), starting with an empty record would not work. -% For our intended application, we thus start with the following two -% lines of code. -% -% \begintt -% gap> ReadLib( "compat3c.g" ); -% gap> MyOps:= OperationsRecord( "MyOps" );; -% HasMyOps := NewFilter( "HasMyOps" ); -% \endtt -% -% In order to make the translation from {\GAP}~3 code to {\GAP}~4 -% easier, {\GAP} prints the definition of filters associated with -% operations records and the method installations for operations -% corresponding to components of the operations records. The output -% line printed by {\GAP} after the call of `OperationsRecord' is one -% such case. -% -% Now we add our multiplication function to the operations record, -% and again {\GAP}~4 prints a translation to {\GAP}~4 code. -% -% \begintt -% gap> MyOps.\* := function( a, b ) -% > return rec( x:= a.x * b.x - a.x - b.x + 2, -% > operations := MyOps ); -% > end;; -% # If the following method installation matches the requirements -% # of the operation `PROD' then `InstallMethod' should be used. -% # It might be useful to replace the rank `SUM_FLAGS' by `0'. -% InstallOtherMethod( PROD, -% "for object with `MyOps' as first argument", -% true, -% [ HasMyOps, IsObject ], SUM_FLAGS, -% MyOps.\* ); -% -% # For binary infix operators, a second method is installed -% # for the case that the object with `MyOps' is the right operand; -% # since this case has higher priority in GAP 3, the method is -% # installed with higher rank `SUM_FLAGS + 1'. -% InstallOtherMethod( PROD, -% "for object with `MyOps' as second argument", -% true, -% [ IsObject, HasMyOps ], SUM_FLAGS + 1, -% MyOps.\* ); -% \endtt -% -% Let us look how this installation works. -% -% \begintt -% gap> a:= rec( x:= 3, operations:= MyOps ); -% rec( x := 3, operations := MyOps ) -% gap> b:= rec( x:= 5, operations:= MyOps ); -% rec( x := 5, operations := MyOps ) -% gap> a * b; -% rec( x := 9, operations := MyOps ) -% \endtt -% -% (In more complicated cases, we might run into problems, but this was -% already the case in {\GAP}~3. For example, suppose we want to support -% the multiplication of two operands having different operations -% records; then it is not clear which of the two multiplication -% functions is to be chosen, and in {\GAP}~3, the only way out was to -% change the multiplication functions, in order to make them aware of -% such situations.) -% -% If we are now interested to translate the code to {\GAP}~4 in the -% sense that no compatibility mode is needed, we can use what {\GAP}~4 -% has printed above. (The same example is dealt with in Section ``An -% Example -- Designing Arithmetic Operations'' in the {\GAP}~4 Reference -% Manual.) -% -% The objects will no longer be records with `operations' component. -% Instead of records we may use so-called component objects -% with record-like access to components, -% and instead of the `operations' component, we give the objects a -% type that has the filter `HasMyOps' set. -% \begintt -% HasMyOps := NewFilter( "HasMyOps" ); -% MyType := NewType( NewFamily( "MyFamily" ), -% HasMyOps and IsComponentObjectRep ); -% \endtt -% (More about families and representations in this context can be found -% in the same chapter of the {\GAP}~4 Reference Manual mentioned above.) -% -% The next step is to write a function that creates a new object. -% It may look as follows. -% \begintt -% MyObject := function( val ) -% return Objectify( MyType, rec( x:= val ) ); -% end; -% \endtt -% -% The multiplication function shall return an object with the -% filter `HasMyOp', so we change it as follows. -% \begintt -% gap> MyMult := function( a, b ) -% > return MyObject( x:= a!.x * b!.x - a!.x - b!.x + 2 ); -% > end;; -% \endtt -% Note that the component access for these objects -% works via `!.' instead of `.'; -% further note that no operations record needs to appear here, -% the filter takes its role. -% -% Finally, we install the multiplication for at least one argument -% with the new filter, as had been printed by {\GAP}~4 in the -% session shown above. -% \begintt -% InstallOtherMethod( PROD, -% "for object with `MyOps' as first argument", -% true, -% [ HasMyOps, IsObject ], 0, -% MyMult ); -% -% InstallOtherMethod( PROD, -% "for object with `MyOps' as second argument", -% true, -% [ IsObject, HasMyOps ], 1, -% MyMult ); -% \endtt -% And now the example works (again). -% \begintt -% gap> a:= MyObject( 3 ); -% -% gap> b:= MyObject( 5 ); -% -% gap> a * b; -% -% gap> last!.x -% 9 -% \endtt -% -% We may install a method to print our objects in a nice way; -% we could have done this for the operations record `MyOps' -% in the compatibility mode, -% the printed output would look similar to the following. -% \begintt -% InstallOtherMethod( PRINT_OBJ, -% "for object with `MyOps' as first argument", -% true, -% [ HasMyOps ], 0, -% function( obj ) Print( "MyObject( ", obj!.x, " )" ); end ); -% \endtt -% -% Now the example behaves as follows. -% \begintt -% gap> a; b; a * b; -% MyObject( 3 ) -% MyObject( 5 ) -% MyObject( 9 ) -% \endtt -% -% Maybe now we want to improve the installation. -% The multiplication function we want to use is apparently -% thought only for the case that *both* operands have -% the filter `HasMyOps' (and a component `x'). -% So it is reasonable to replace the two methods for -% the multiplication by one method for which both arguments -% are required to have the filter. -% \begintt -% InstallOtherMethod( PROD, -% "for two objects with `MyOps'", -% true, -% [ HasMyOps, HasMyOps ], 0, -% MyMult ); -% \endtt -% -% At first sight, the {\GAP}~4 approach seems to be much more -% complicated. -% But the last example shows that in {\GAP}~4, -% each method can be installed more specifically for the appropriate -% situation. -% Moreover, it is for example possible to install a method -% for the multiplication of an integer and a `HasMyOps' object; -% note that --contrary to the situation in {\GAP}~3-- -% such a method is independent from already existing methods -% in the sense that these need not be changed when -% new functionality is added. -% -% Another example that uses this part of the compatibility mode can be -% found in the file `tst/compat3.tst' of the {\GAP}~4 distribution. - -\EndOfBook - diff --git a/doc/tut/migrat.xml b/doc/tut/migrat.xml deleted file mode 100644 index cf182c4fc2..0000000000 --- a/doc/tut/migrat.xml +++ /dev/null @@ -1,1227 +0,0 @@ - - - - - - - - -Migrating to &GAP; 4 - -This chapter is intended to give users who have experience with &GAP; 3 -some information about what has changed in &GAP; 4. -

-In particular, it informs about changed command line options -(see ), -the new global variable fail (see ), -some functions that have changed their behaviour -(see ) or their names -(see ), -and some conventions used for variable names (see ). -

-Then the new concepts of &GAP; 4 are sketched, -first that of mutability or immutability (see ), -with the explanation of related changes in functions that copy objects -(see ), -then the concepts of operations and method selection, which are compared -with the use of operations records in &GAP; 3 -(see , , -and ). -

-More local changes affect the concepts of notions of generation -(see ), -of parents (see ), -of homomorphisms (see , -, -and ), -how elements in finitely presented groups are treated -(see ), -how information about progress of computations can be obtained -(see ), -and how one gets information in a break loop -(see ). -

-While a &GAP; 3 compatibility mode is provided -(see ), -its use will disable some of the new features of &GAP; 4. -Also it certainly can only try to provide partial compatibility. -

-For a detailed explanation of the new features and concepts of &GAP; 4, -see the manual Programming in GAP. - - - -

-Changed Command Line Options - -In &GAP; 4, the -l option is used to specify the root directory -(see ) -of the &GAP; distribution, -which is the directory containing the lib and doc subdirectories. -Note that in &GAP; 3 this option was used to specify the path to the -lib directory. -

-The -h option of &GAP; 3 has been removed, -the path(s) for the documentation are deduced automatically in &GAP; 4. -

-The option -g is now used to print information only about full garbage -collections. -The new option -g -g generates information about partial -garbage collections too. - -

- - - -
-Fail - -There is a new global variable -fail instead of false -

- - - -in &GAP; 4. -It is intended as a return value of a function for the case that it -could not perform its task. -For example, Inverse returns fail if it is called with a singular -matrix, and Position returns fail if the second argument is not -contained in the list given as first argument. -

-&GAP; 3 handled such situations by either signalling an error, -for example if it was asked for the inverse of a singular matrix, -or by (mis)using false as return value, as in the example Position. -Note that in the first example, in &GAP; 3 it was necessary to check -the invertibility of a matrix before one could safely ask for its -inverse, which meant that roughly the same work was done twice. - - - -

- - - -
-Changed Functionality - -Some functions that were already available in &GAP; 3 behave -differently in &GAP; 4. This section lists them. -

- - - -The &GAP; 3 manual promised that pnt would be the first entry of the -resulting orbit. This was wrong already there in a few cases, therefore -&GAP; 4 does not promise anything about the ordering of points in an orbit. - - -

- - - -only takes the element g and computes its multiplicative order. -Calling Order with two arguments is permitted only in the -&GAP; 3 compatibility mode, see . -(Note that it does not make sense anymore to specify a group as -first argument w.r.t. which the order of the second argument shall -be computed, see .) - - -

- - - -If obj is not contained in the list list then fail is returned -in &GAP; 4 (see ), whereas false was returned in &GAP; 3. - - -

- - - -In &GAP; 3, this function took either two or three arguments, -the optional argument K being a subgroup of G that stabilizes prop -in the sense that for any element g in G, -either all elements or no element in the coset g * K have the -property prop. -

-The &GAP; 4 function ElementProperty, however, -takes between two and four arguments, -and the subgroup K known from &GAP; 3 has to be entered as the fourth -argument not the third. -(The third argument in the &GAP; 4 function denotes a subgroup U -stabilizing prop in the sense that either all elements or no element -in right cosets U * g have the property prop.) -

-(This discrepancy was discovered only in March 2002, -short before the release of &GAP; 4.3.) - - -

- - - -Objects may appear on the screen in a different way, -depending on whether they are printed by the read eval print loop -or by an explicit call of Print. -The reason is that the read eval print loop calls the operation ViewObj -and not PrintObj, whereas Print calls PrintObj for each of its -arguments. -This permits the installation of methods for printing objects in a short form -in the read eval print loop while retaining Print to display -the object completely. -See also Section . -

-(PrintObj is installed as standard method ViewObj, so it is -not really necessary to have a ViewObj method for an object.) - - -

- - - -In &GAP; 3, PrintTo could be (mis)used to redirect the text -printed by a function (that is, not only the output of a function) -to a file by entering the function call as second argument. -This was used mainly in order to avoid many calls of AppendTo. -In &GAP; 4, this feature has disappeared. -One can use streams (see Chapter ) -instead in order to write files efficiently. - - - -

- - - -
-Changed Variable Names - -AgGroup -ApplyFunc -Backtrace -CharTable -Denominator -DepthVector -Elements -IsBijection -IsFunc -IsMat -IsRec -IsSet -LengthWord -NOfCyc -Numerator -RandomInvertableMat -RecFields -X - -Some functions have changed their name without changing the -functionality. -A -- probably incomplete -- list follows -

- -

-See Section  for a way to make the old names -available again. - -

- - - -
-Naming Conventions - -The way functions are named has been unified in &GAP; 4. -This might help to memorize or even guess names of library functions. -

-If a variable name consists of several words then the first -letter of each word is capitalized. -

-If the first part of the name of a function is a verb then the function -may modify its argument(s) but does not return anything, -for example Append appends the list given as second argument to the -list given as first argument. -Otherwise the function returns an object without changing the arguments, -for example Concatenation returns the concatenation of the lists -given as arguments. -

-If the name of a function contains the word By then the return value is -thought of as built in a certain way from the parts given as arguments. -For example, GroupByGenerators returns a group built from its group -generators, and creating a group as a factor group of a given group -by a normal subgroup can be done by taking the image of -NaturalHomomorphismByNormalSubgroup -(see also ). -Other examples of By functions are GroupHomomorphismByImages and -UnivariateLaurentPolynomialByCoefficients. -

-If the name of a function contains the word Of then the return value is -thought of as information deduced from the arguments. -Usually such functions are attributes -(see  in this Tutorial and ). -Examples are GeneratorsOfGroup, which returns a list of generators for -the group entered as argument, or DiagonalOfMat. -

-For the setter and tester functions of an attribute attr -(see  in this Tutorial -and ) -the names Setattr resp. Hasattr are available. -

-If the name of a function fun1 ends with NC then there is another -function fun2 with the same name except that the NC is missing. -NC stands for no check. -When fun2 is called then it checks whether its arguments are valid, -and if so then it calls fun1. -The functions SubgroupNC and Subgroup are a typical example. -

-The idea is that the possibly time consuming check of the arguments -can be omitted if one is sure that they are unnecessary. -For example, if an algorithm produces generators of the derived subgroup -of a group then it is guaranteed that they lie in the original group; -Subgroup would check this, and SubgroupNC omits the check. -

-Needless to say, all these rules are not followed slavishly, -for example there is one operation Zero instead of two operations -ZeroOfElement and ZeroOfAdditiveGroup. - -

- - - -
-Immutable Objects - -&GAP; 4 supports immutable objects. Such objects cannot be -changed, attempting to do so issues an error. Typically attribute -values are immutable, and also the results of those binary arithmetic -operations where both arguments are immutable, -see Section . -For example, [ 1 .. 100 ] + [ 1 .. 100 ] is a -mutable list and 2 * Immutable( [ 1 .. 100 ] ) is an immutable -list, both are equal to the (mutable) list [ 2, 4 .. 200 ]. -

-There is no way to make an immutable object mutable, one can only -get a mutable copy by ShallowCopy. The other way round, -MakeImmutable makes a (mutable or immutable) object and all its -subobjects immutable; one must be very careful to use MakeImmutable -only for those objects that are really newly created, for such objects -the advantage over Immutable is that no copy is made. -

-More about immutability can be found in Sections  in -this tutorial and . - -

- - - -
-Copy - -StructuralCopy -ShallowCopy -The function Copy of &GAP; 3 is not supported in &GAP; 4. This -function was used to create a copy cop of its argument obj with -the properties that cop and obj had no subobjects in common and -that if two subobjects of obj were identical then also the -corresponding subobjects of cop were identical. -

-The possibility of having immutable objects (see ) can and -should be used to avoid unnecessary copying. -Namely, given an immutable object one needs to copy it only if one wants -to get a modified object, and in such a situation usually it is -sufficient to use ShallowCopy, or at least one knows how deep one must -copy in order to do the changes one has in mind. -

-For example, suppose you have a matrix group, and you want to -construct a list of matrices by modifying the group generators. This -list of generators is immutable, so you call ShallowCopy to get a -mutable list that contains the same matrices. If you only want to -exchange some of them, or to append some other matrices, this shallow -copy is already what you need. So suppose that you are interested in -a list of matrices where some rows are also changed. For that, you -call ShallowCopy for the matrices in question, and you get matrices -whose rows can be changed. If you want to change single entries in -some rows, ShallowCopy must be called to get mutable copies of these -rows. Note that in all these situations there is no danger to change, -i.e., to destroy the original generators of the matrix group. -

-If one needs the facility of the Copy function of &GAP; 3 to get a -copy with the same structure then one can use the new &GAP; 4 -function StructuralCopy. It returns a structural copy that has no -mutable subobject in common with its argument. So if -StructuralCopy is called with an immutable object then this object -itself is returned, and if StructuralCopy is called with a mutable -list of immutable objects then a shallow copy of this list is -returned. -

-Note that ShallowCopy now is an operation. So if you create your -own type of (copyable) objects then you must define what a shallow -copy of these objects is, and install an appropriate method. - -

- - - -
-Attributes vs. Record Components - -In &GAP; 3, many complex objects were represented via records, for -example all domains. Information about these objects was stored in -components of these records. For the user, this was usually not -relevant, since there were functions for computing information about -the objects in question. For example, if one was interested in the -size of a group then one could call Size. -

-But since it was guaranteed that the size of a domain D was stored -as value of the component size, it was allowed to access D.size -if this component was bound, and a check for this was possible via -IsBound( D.size ). -

-In &GAP; 4, only the access via functions is admissible. One reason -is the following basic rule. -

-From the information that a given &GAP; 4 object is for example a -domain, one cannot conclude that this object has a certain -representation. -

-For attributes like Size, &GAP; 4 provides two related functions, -the setter and the tester of the attribute, which can be used to -set an attribute value and to check whether the value of an attribute -is already stored for an object (see also ). For example, if D is a domain in &GAP; 4 then -HasSize( D ) is true if the size of D is already stored, and -false otherwise. In the latter case, if you know that the size of -D is size then you may store it by SetSize( D, size ). -

-Besides the flexibility in the internal representation of objects, -storing information only via function calls has also the advantage -that &GAP; 4 is able to draw conclusions automatically. For example, -as soon as it is stored that a group is nilpotent, it is also stored -that it is solvable, see Chapters  and  -for the details. -

-As a consequence, you cannot put your favourite information into a -domain D by assigning it to a new component like -D.myPrivateInfo. Instead you can introduce a new attribute and -then use its setter, see . - -

- - - -
-Different Notions of Generation - -As in &GAP; 3, a domain in &GAP; 4 is a structured set. -

-The same set can have different structures, for example a field can be -regarded as a ring or as an algebra or vector space over a subfield. -

-In &GAP; 3, however, an object representing a ring did not represent -a field, and an object representing a field did not represent a ring. -One reason for this was that the record component generators was -used to denote the appropriate generators of the domain. For a ring -R, the component R.generators was a list of ring generators, and -for a field F, F.generators was a list of field generators. -

-&GAP; 4 cleans this up, see . It supports -many different notions of generation, for example one can ask for -magma generators of a group or for generators of a field as an additive -group. A subtle but important distinction is that between generators -of an algebra and of an algebra-with-one. -

-So the attributes GeneratorsOfGroup, GeneratorsOfMagma, -GeneratorsOfRing, GeneratorsOfField, GeneratorsOfVectorSpace, -and so on, replace the access to the generators component. - -

- - - -
-Operations Records - -Already in &GAP; 3 there were several functions that were applicable -to many different kinds of objects, for example Size could be -applied to any domain, and the binary infix multiplication * could -be used to multiply two matrices, an integer with a row vector, or a -permutation with a permutation group. This was implemented as -follows. Functions like Size and * tried to find out what -situation was described by its arguments, and then it called a more -specific function to compute the desired information. These more -specific functions, let us call them methods as they are also called -in &GAP; 4, were stored in so-called operations records of the -arguments. -

-For example, every domain in &GAP; 3 was represented as a record, and -the operations record was stored in the record component operations. -If Size was called for the domain then the method to compute the -size of the domain was found as value of the Size component of the -operations record. -

-This was fine for functions taking only one argument, and in principle -it is possible that for those functions an object stored an optimal -method in its operations record. But in the case of more arguments -this is not possible. In a multiplication of two objects in &GAP; 3, -one had to choose between the methods stored in the operations records -of the arguments, and if for example the method stored for the left -operand was called, this method had to handle all possible right -operands. -

-So operations records turned out to be not flexible enough. -In &GAP; 4, operations records are not supported -(see  for a possibility -to use your &GAP; 3 code that utilizes operations records, -at least to some extent). -A detailed description -of the new mechanism to select methods can be found in -Chapter . -

-An important point is that the new mechanism allows &GAP; to take the -relation between arguments into account. So it is possible (and -recommended) to install different methods for different relations -between the arguments. Note that such methods need not do the -extensive argument checking that was necessary in &GAP; 3, because -most of the checks are done already by the method selection mechanism. - -

- - - -
-Operations vs. Dispatcher Functions - -&GAP; 3 functions like Size, CommutatorSubgroup, or -SylowSubgroup did mainly call an appropriate method -(see ) -after they had checked their arguments. -Such functions were -called dispatchers in &GAP; 3. In &GAP; 4, many dispatchers have -been replaced by operations, due to the fact that methods are no -longer stored in operations records (see  for the details). -

-Most dispatchers taking only one argument were treated in a special -way in &GAP; 3, they had the additional task of storing computed -values and using these values in subsequent calls. For example, the -dispatcher Size first checked whether the size of the argument was -already stored, and if so then this value was returned; otherwise a -method was called, the value returned by this method was stored in the -argument, and then returned by Size. -

-In &GAP; 4, computed values of operations that take one argument -(these operations are called attributes) are also stored, only the -mechanism to achieve this has changed, see  -and . -

-So the behaviour of Size is the same in &GAP; 3 and &GAP; 4. But -note that in &GAP; 4, it is not possible to access D.size, -see . -As described in , -&GAP; 4 does not admit bypassing the dispatcher by -calling for example D.operations.Size. This was done in &GAP; 3 -often for efficiency reasons, but the method selection mechanism of -&GAP; 4 is fast enough to make this unnecessary. -

-If you had written your own dispatchers and put your own methods into -existing operations records then this code will not work in &GAP; 4. -See  -and  -for a description of how to define operations -and to install methods. -

-Finally, some functions in &GAP; 3 were hidden in -operations records, e.g., PermGroupOps.MovedPoints. -These functions became proper operations in &GAP; 4. - -

- - - -
-Parents and Subgroups - -In &GAP; 3 there was a strict distinction between parent groups and -subgroups. -The use of the name parent (instead of supergroup) -was chosen to indicate that the parent of an object was more than just -useful information. -In fact the main reason for the introduction of parents was to provide -a common roof for example for all groups of polycyclic words that -belonged to the same PC-presentation, or for all subgroups of a finitely -presented group (see ). -A subgroup was never a parent group, and it was possible to create -subgroups only of parent groups. -

-In &GAP; 4 this common roof is provided already by the concept of -families, see . -Thus it is no longer compulsory to use parent groups at all. -On the other hand, parents may be used in &GAP; 4 to provide -information about an object, for example the normalizer of a group in its -parent group may be stored as an attribute value. -Note that there is no restriction on the supergroup that is set to be -the parent, -it is possible to create a subgroup of -any group, this group then being the parent of the new subgroup. -This permits for example chains of subgroups with respective parents, -of arbitrary length. -

-As a consequence, the Parent command cannot be used in &GAP; 4 to -test whether the two arguments of CommutatorSubgroup fit together, -this is now a question that concerns the relation between the families -of the groups. So the 2-argument version of Parent and the now -meaningless function IsParent have been abolished. - -

- - - -
-Homomorphisms vs. General Mappings - -In &GAP; 3 there had been a confusion between group homomorphisms and -general mappings, as GroupHomomorphismByImages created only a -general mapping that did not store whether it was a mapping. This -caused expensive, unwanted, and unnecessary tests whether the mapping -was in fact a group homomorphism. Moreover, the official -workaround to set some components of the mapping record was quite -unwieldy. -

-In &GAP; 4, GroupHomomorphismByImages checks whether the desired -mapping is indeed a group homomorphism; if so then this property is -stored in the returned mapping, otherwise fail is returned. If you -want to avoid the checks then you can use -GroupHomomorphismByImagesNC. If you want to check whether a general -mapping that respects the group operations is really a group -homomorphism, you can construct it via GroupGeneralMappingByImages -and then call IsGroupHomomorphism for it. (Note that -IsGroupHomomorphism returns true if and only if both -IsGroupGeneralMapping and IsMapping do, so one does in fact check -IsMapping in this case.) -

-There is no function IsHomomorphism in &GAP; 4, -since there are several different operations with respect to which a -mapping can be a homomorphism. - -

- - - -
-Homomorphisms vs. Factor Structures - -If F is a factor structure of G, with kernel N, complete -information about the connection between F and G is provided by -the natural homomorphism. -

-In &GAP; 3, the official way to construct this natural homomorphism -was to create first the factor structure F, and then to call -NaturalHomomorphism with the arguments G and F. -For that, the data necessary to compute the homomorphism was stored in -F when F was constructed. -

-In &GAP; 4, factor structures are not treated in a special way, -in particular they do not store information about a homomorphism. -Instead, the more natural way is taken to construct the natural -homomorphism from G and N by NaturalHomomorphismByNormalSubgroup -if N is a normal subgroup of the group G, -or by NaturalHomomorphismByIdeal if N is an ideal in the ring G. -The factor F can then be accessed as the image of this homomorphism, -and of course G is the preimage and N is the kernel. -

-Note that &GAP; 4 does not guarantee anything about the representation -of the factor F, it may be a permutation group or a polycyclically -presented group or another kind of group. -Also note that a natural homomorphism need not be surjective. -

-A consequence of this change is that &GAP; 4 does not allow you to -construct a natural homomorphism from the groups G and F. -

-The other common type of homomorphism in &GAP; 3, operation -homomorphisms, have been replaced (just a name change) by action -homomorphisms, which are handled in a similar fashion. That is, an -action homomorphism is constructed from an acting group, an action -domain, and a function describing the operation. The permutation -group arising by the induced action is then the image of this -operation homomorphism. -

-The &GAP; 3 function Operation is still supported, under the name Action, -but from the original group and the result of Action it is not -possible to construct the action homomorphism. - -

- - - -
-Isomorphisms vs. Isomorphic Structures - -In &GAP; 3, a different representation of a group could be obtained by -calling AgGroup to get an isomorphic polycyclically presented group, -PermGroup to get an isomorphic permutation group, and so on. -The returned objects stored an isomorphism in the record component -bijection. -

-For the same reason as in , -&GAP; 4 puts emphasis on the isomorphism, -and the isomorphic object in the desired representation can be accessed -as its image. -So you can call IsomorphismPcGroup or IsomorphismPermGroup in order -to get an isomorphism to a polycyclically presented group or a -permutation group, respectively, and then call Image to get the -isomorphic group. -

-Note that the image of an action homomorphism with trivial kernel is -also an isomorphic permutation group, but an action homomorphism need -not be surjective, since it may be easier to define it into the full -symmetric group. -

-Further note that in &GAP; 3, a usual application of isomorphisms to -polycyclically presented groups was to utilize the usually more -effective algorithms for solvable groups. However, the new concept of -polycyclic generating systems in &GAP; 4 makes it possible to apply -these algorithms to arbitrary solvable groups, independent of the -representation. For example, &GAP; 4 can handle polycyclic -generating systems of solvable permutation groups. So in many cases, -a change of the representation for efficiency reasons may be not -necessary any longer. -

-In general IsomorphismFpGroup will define a presentation on generators -chosen by the algorithm. The corresponding elements of the original -group can be obtained by the command -

-PreImagesRepresentative(isofp,i)); -]]> -

-If a presentation in the given generators is needed, the command -IsomorphismFpGroupByGenerators(G, gens) will produce one. - -

- - - -
-Elements of Finitely Presented Groups - -Strictly speaking, &GAP; 3 did not support elements of finitely -presented groups. Instead, the words in abstract generators of -the underlying free groups were (mis)used. This caused problems -whenever calculations with elements were involved, the most obvious -ones being wrong results of element comparisons. Also functions -that should in principle work for any group were not applicable to -finitely presented groups. In effect, a finitely presented group had -to be treated in a special way in &GAP; 3. -

-&GAP; 4 distinguishes free groups and their elements from finitely -presented groups and their elements. Comparing two elements of a -finitely presented group will yield either the correct result or no -result at all. -

-Note that in &GAP; 4, the arithmetic and comparison operations for -group elements do not depend on a context provided by a group that -contains the elements. In particular, in &GAP; 4 it is not -meaningful to call Order( G, g ) for a group G and an element -g. - -

- - - -
-Polynomials - -In &GAP; 3, polynomials were defined over a field. So a polynomial over -GF(3) was different from a polynomial over GF(9), even if the -coefficients were exactly the same. -

-&GAP; 4 defines polynomials only over a characteristic. This makes it -possible for example to multiply a polynomial over GF(3) with a polynomial -over GF(9) without the need to convert the former to the larger field. -

-However it has an effect on the result of DefaultRing for polynomials: -In &GAP; 3 the default ring for a polynomial was the polynomial ring of the -field over which the polynomial was defined. In &GAP; 4 no field is -associated, so (to avoid having to define the algebraic closure as the only -other sensible alternative) the default ring of a polynomial is the -DefaultRing of its coefficients. -

-This has an effect on Factors: If no ring is given, a polynomial is -factorized over its DefaultRing and so Factors(poly) -might return different results. -

-To be safe from this problem, if you are not working over prime fields, -rather call Factors(pring,poly) with the appropriate polynomial ring -and change your code accordingly. - -

- - - -
-The Info Mechanism - -Sometimes it is useful to get information about the progress of a -calculation. -Many &GAP; functions contain statements to display such information -under certain conditions. -

-In &GAP; 3, these statements were calls to functions such as -InfoGroup1 or InfoGroup2, and if the user assigned Print to -these variables then this had the effect to switch on the printing of -information. -InfoGroup2 was used for more detailed information than InfoGroup1. -One could switch off the printing again by assigning Ignore to the -variables, and Ignore was also the default value. -

-&GAP; 4 uses one function Info for the same purpose, -which is a function that takes as first argument an info class such as -InfoGroup, as second argument an info level, and the print statements -as remaining arguments. -The level of an info class class is set to level by calling -SetInfoLevel( class, level ). -An Info statement is printed only if its second argument is smaller than -or equal to the current info level. -

- test:= function( obj ) -> Info( InfoGroup, 2, "This is useful, isn't it?" ); -> return obj; -> end;; -gap> test( 1 ); -1 -gap> SetInfoLevel( InfoGroup, 2 ); -gap> test( 1 ); -#I This is useful, isn't it? -1 -]]> -

-As in &GAP; 3, if an info statement is ignored then its arguments are -not evaluated. - -

- - - -
-Debugging - -Backtrace -DownEnv -Where -If &GAP; 4 runs into an error or is interrupted, -it enters a break loop. -The command Where( number ), which replaces Backtrace of &GAP; 3, -can be used to display number lines of information about the current -function call stack. -

-As in &GAP; 3, access is only possible to the variables of the current -level in the function stack, -but in &GAP; 4 the function DownEnv, with a positive or negative -integer as argument, permits one to step down or up in the -stack. -

-When interrupting, the first line printed by Where actually may be -one level higher, as shown below. -

- OnBreak := function() end;; # eliminate back-tracing on entry to break loop -gap> test:= function( n ) -> if n > 3 then Error( "!\n" ); fi; test( n+1 ); end;; -gap> test( 1 ); -Error, ! -you can enter 'quit;' to quit to outer loop, or -you can enter 'return;' to continue -brk> Where(); -Stack trace: -*[1] Error( "!\n" ); - @ *stdin*:3 - [2] test( n + 1 ); - @ *stdin*:3 - [3] test( n + 1 ); - @ *stdin*:3 - [4] test( n + 1 ); - @ *stdin*:3 -( ) - called from read-eval loop at *errin*:1 -brk> n; -4 -brk> DownEnv(); -brk> n; -3 -brk> Where(); -Stack trace: - [1] Error( "!\n" ); - @ *stdin*:3 -*[2] test( n + 1 ); - @ *stdin*:3 - [3] test( n + 1 ); - @ *stdin*:3 - [4] test( n + 1 ); - @ *stdin*:3 -( ) - called from read-eval loop at *errin*:5 -brk> DownEnv( 2 ); -brk> n; -1 -brk> Where(); -Stack trace: - [1] Error( "!\n" ); - @ *stdin*:3 - [2] test( n + 1 ); - @ *stdin*:3 - [3] test( n + 1 ); - @ *stdin*:3 -*[4] test( n + 1 ); - @ *stdin*:3 -( ) - called from read-eval loop at *errin*:8 -brk> DownEnv( -2 ); -brk> n; -3 -brk> quit; -gap> OnBreak := Where;; # restore OnBreak to its default value -]]> -

-For purposes of debugging, it can be helpful sometimes, to see what -information is stored within an object. In &GAP; 3 this was possible using -RecFields because the objects in question were represented via records. -For component objects, &GAP; 4 permits the same by -NamesOfComponents( object ), which will list all components present. - -

- - - -
-Compatibility Mode - -For users who want to use &GAP; 3 code with as little changes as -possible, a compatibility mode is provided by &GAP; 4. -This mode must be turned on explicitly by the user. -

-It should be noted that this compatibility mode has not been tested -thoroughly. -

-The compatibility mode can be turned on by loading some of the following -files with ReadLib. -The different files address different aspects of compatibility. -

- -compat3a.g - - makes some &GAP; 3 function names available that were changed - in &GAP; 4, - and provides code for some &GAP; 3 features that were - deliberately left out from the &GAP; 4 library. - For example, - almost all variable names concerning character theory that are - mentioned in the &GAP; 3 manual, - such as CharTable and SubgroupFusions, - are available after compat3a.g has been read; - the only exceptions are names of operations records. - -compat3b.g - - implements the availability of components of domains; - besides components that have no meaning for the rest of the &GAP; 4 - library, such as D.myInfo, there are components associated to - attributes; for example D.size is redirected to the call of the - attribute Size, IsBound( D.size ) to the call of its tester, - and D.size:= val to the call of its setter. - (An important special case is the component operations, see below.) - -compat3c.g - - permits you to implement your own elements represented as records, - and using operations records to provide a Print method and - the basic arithmetic operations. - When using operations records, it is probably a good idea to - use immutable operations records; for example, if the results - of arithmetic operations are records with operations records then - this avoids to create shallow copies of the operations records - in the call to Immutable for the results. - - -

-The following features are accessible only via starting &GAP; with -the command line option -O and may damage some features of &GAP; 4 -permanently for the current session. -

- With this option, also the files listed above are read automatically. -

- -compat3d.g - - provides some &GAP; 3 functions like Domain, simulates the - &GAP; 3 behaviour of IsString (to convert a list to string - representation if possible), and replaces fail by false; - these changes destroy parts of the functionality of &GAP; 4. - - -

-Some words concerning the simulation of operations records may be -necessary. -

-The operations records of the &GAP; 3 library, such as DomainOps -and GroupOps, are available only for access to their components, -whose values are &GAP; 4 operations; for example, the value of both -DomainOps.Size and GroupOps.Size is the operation Size. So it -is not safely possible to delegate from a Size method in another -operations record to DomainOps.Size. Also it is not possible to -change these predefined operations records. -

-If one wants to install individual methods for a given object obj -via the mechanism of operations records then one can construct a new -operations record with OperationsRecord, assign the desired methods -to components of this record, and then assign the operations record to -obj.operations. Whenever an operation that is associated with a -component nam of the operations record is called with obj as first -argument, the value of nam is chosen as the method. -

-In the case of the binary operations =, <, +, -, *, /, -Comm, and LeftQuotient, -this also happens if obj is the right-hand argument. -As in &GAP; 3, if both arguments of one of the above binary operations -have operations records containing a function for this operation, -then the function in the operations record of the right-hand argument -is chosen. -

-We give a small example how the compatibility mode works. -

-Suppose we want to deal with new objects that are derived from known -field elements by distorting their multiplication. Namely, let a' -and b' be the new objects corresponding to the field elements a, -b, and define a' * b' = a b - a - b + 2. -

-In &GAP; 3, this problem was solved by representing each new object -by a record that stored the corresponding old object and an -operations record, where the latter was a record containing the -functions applicable to the new object. After the library file -compat3c.g has been read, we can use this construction of the -operations record and of the new objects. Note that operations -records must be created with the function OperationsRecord (this was -also the norm in &GAP; 3), starting with an empty record would not work. -For our intended application, we thus start with the following two -lines of code. -

- ReadLib( "compat3c.g" ); -gap> MyOps:= OperationsRecord( "MyOps" );; -HasMyOps := NewFilter( "HasMyOps" ); -]]> -

-In order to make the translation from &GAP; 3 code to &GAP; 4 -easier, &GAP; prints the definition of filters associated with -operations records and the method installations for operations -corresponding to components of the operations records. The output -line printed by &GAP; after the call of OperationsRecord is one -such case. -

-Now we add our multiplication function to the operations record, -and again &GAP; 4 prints a translation to &GAP; 4 code. -

- MyOps.\* := function( a, b ) -> return rec( x:= a.x * b.x - a.x - b.x + 2, -> operations := MyOps ); -> end;; -# If the following method installation matches the requirements -# of the operation `PROD' then `InstallMethod' should be used. -# It might be useful to replace the rank `SUM_FLAGS' by `0'. -InstallOtherMethod( PROD, - "for object with `MyOps' as first argument", - true, - [ HasMyOps, IsObject ], SUM_FLAGS, - MyOps.\* ); - -# For binary infix operators, a second method is installed -# for the case that the object with `MyOps' is the right operand; -# since this case has higher priority in GAP 3, the method is -# installed with higher rank `SUM_FLAGS + 1'. -InstallOtherMethod( PROD, - "for object with `MyOps' as second argument", - true, - [ IsObject, HasMyOps ], SUM_FLAGS + 1, - MyOps.\* ); -]]> -

-Let us look how this installation works. -

- a:= rec( x:= 3, operations:= MyOps ); -rec( x := 3, operations := MyOps ) -gap> b:= rec( x:= 5, operations:= MyOps ); -rec( x := 5, operations := MyOps ) -gap> a * b; -rec( x := 9, operations := MyOps ) -]]> -

-(In more complicated cases, we might run into problems, but this was -already the case in &GAP; 3. For example, suppose we want to support -the multiplication of two operands having different operations -records; then it is not clear which of the two multiplication -functions is to be chosen, and in &GAP; 3, the only way out was to -change the multiplication functions, in order to make them aware of -such situations.) -

-If we are now interested to translate the code to &GAP; 4 in the -sense that no compatibility mode is needed, we can use what &GAP; 4 -has printed above. (The same example is dealt with in -Chapter .) -

-The objects will no longer be records with operations component. -Instead of records we may use so-called component objects -with record-like access to components, -and instead of the operations component, we give the objects a -type that has the filter HasMyOps set. -

- -

-(More about families and representations in this context can be found -in the chapter of Programming in &GAP; mentioned above.) -

-The next step is to write a function that creates a new object. -It may look as follows. -

- -

-The multiplication function shall return an object with the -filter HasMyOp, so we change it as follows. -

- MyMult := function( a, b ) -> return MyObject( x:= a!.x * b!.x - a!.x - b!.x + 2 ); -> end;; -]]> -

-Note that the component access for these objects -works via !. instead of .; -further note that no operations record needs to appear here, -the filter takes its role. -

-Finally, we install the multiplication for at least one argument -with the new filter, as had been printed by &GAP; 4 in the -session shown above. -

- -

-And now it works (again). -

- a:= MyObject( 3 ); - -gap> b:= MyObject( 5 ); - -gap> a * b; - -gap> last!.x -9 -]]> -

-We may install a method to print our objects in a nice way; -we could have done this for the operations record MyOps -in the compatibility mode, -the printed output would look similar to the following. -

- -

-Now output looks as follows. -

- a; b; a * b; -MyObject( 3 ) -MyObject( 5 ) -MyObject( 9 ) -]]> -

-Maybe now we want to improve the installation. -The multiplication function we want to use is apparently -thought only for the case that both operands have -the filter HasMyOps (and a component x). -So it is reasonable to replace the two methods for -the multiplication by one method for which both arguments -are required to have the filter. -

- -

-At first sight, the &GAP; 4 approach seems to be much more -complicated. -But the last example shows that in &GAP; 4, -each method can be installed more specifically for the appropriate -situation. -Moreover, it is for example possible to install a method -for the multiplication of an integer and a HasMyOps object; -note that --contrary to the situation in &GAP; 3-- -such a method is independent from already existing methods -in the sense that these need not be changed when -new functionality is added. -

-Another example that uses this part of the compatibility mode can be -found in the file tst/compat3.tst of the &GAP; 4 distribution. - - - - - - - - From f7afbcccb548cba489df99b474d7d7627f41df13 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 11 Jun 2026 09:16:17 +0200 Subject: [PATCH 38/50] Remove SingleCollector_CollectWordRunning (#6426) It does not seem to serve any purpose (anymore?) --- lib/rwspcsng.gi | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/rwspcsng.gi b/lib/rwspcsng.gi index 19cd81bcec..81bfcdb7a3 100644 --- a/lib/rwspcsng.gi +++ b/lib/rwspcsng.gi @@ -71,8 +71,6 @@ DeclareFilter( "IsDefaultRhsTypeSingleCollector" ); ## describing the polycyclic presentation, an exponent vector and a word ## in the corresponding free group. It collects into . ## -SingleCollector_CollectWordRunning := false; - BindGlobal( "SingleCollector_CollectWord", function( sc, v, w ) local cnj, # [g][h] contains g^h for g > h @@ -92,13 +90,7 @@ BindGlobal( "SingleCollector_CollectWord", function( sc, v, w ) tmp, # temporary avc; # g_i .. g_n commutes with g_avc[i]+1 .. g_n - # the collector is not reentrant - if SingleCollector_CollectWordRunning then - SingleCollector_CollectWordRunning := false; - Error( "collector is not reentrant" ); - fi; #Print( "#I using the GAP level single collector\n" ); - SingleCollector_CollectWordRunning := true; # contains the stack of words to insert nw := []; nw[1] := w; @@ -108,7 +100,6 @@ BindGlobal( "SingleCollector_CollectWord", function( sc, v, w ) # if we got the identity return if lw[1] = 0 then - SingleCollector_CollectWordRunning := false; return true; fi; @@ -238,7 +229,6 @@ BindGlobal( "SingleCollector_CollectWord", function( sc, v, w ) fi; fi; od; - SingleCollector_CollectWordRunning := false; return true; end ); From 4fea97426ec77cca945959cda2ccff2e043b4295 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 11 Jun 2026 13:29:42 +0200 Subject: [PATCH 39/50] kernel: cleanup CRC code (#6436) There was an incorrect comment claiming that SyGAPCRC only ever returns 0 in case of an error. There was also code that looked as if it ensured that (by checking if `crc` is 0 and if so replacing it by 1). But this code in fact was a no-op, and has been one since 1997, when the code was changed to return `crc >> 4` instead of `crc` -- yet both `0 >> 4` and `1 >> 4` are equal to 0. Regarding the other changes: - `(crc >> 8) & 0x00FFFFFFL` is the same as `crc >> 8` since `crc` is an unsigned 32 bit value - removed a comment from the 1990ies suggesting that `SyGAPCRC` should ignore whitespace and comment changes; but we will never do that (as it would be very difficult, break backwards compatibility, and have little practical use) - align right shift in SyGAPCRC and FuncCrcString: one was "emulating" a signed shift, the other didn't. This didn't cause a problem in practice because essentially every compiler in active uses nowadays implements signed right shifts; but the C standard does not require this. Now both use the same branchless emulation code which e.g. clang compiles down into a single instruction (GCC, MSVC, ICC do not, but that's fine, this code is not a bottleneck for anything) --- src/gap.c | 4 +--- src/sysfiles.c | 41 ++++++++++++++++++----------------------- src/sysfiles.h | 3 +-- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/gap.c b/src/gap.c index 711c0eb142..e88bcc8711 100644 --- a/src/gap.c +++ b/src/gap.c @@ -409,7 +409,6 @@ int realmain(int argc, const char * argv[]) { UInt type; // result of compile Obj func; // function (compiler) - Int4 crc; // crc of file to compile // initialize everything and read init.g which runs the GAP session InitializeGap(&argc, argc, argv, 1); @@ -425,12 +424,11 @@ int realmain(int argc, const char * argv[]) if (!CloseInput(&input)) { return 2; } - crc = SyGAPCRC(SyCompileInput); type = CompileFunc( MakeImmString(SyCompileOutput), func, MakeImmString(SyCompileName), - crc, + SyGAPCRC(SyCompileInput), MakeImmString(SyCompileMagic1) ); return ( type == 0 ) ? 1 : 0; } diff --git a/src/sysfiles.c b/src/sysfiles.c index b65033dbe1..98aeb14694 100644 --- a/src/sysfiles.c +++ b/src/sysfiles.c @@ -191,10 +191,7 @@ static ssize_t echoandcheck(int fid, const char *buf, size_t count) ** *F SyGAPCRC( ) . . . . . . . . . . . . . . . . . . crc of a GAP file ** -** This function should be clever and handle white spaces and comments but -** one has to make certain that such characters are not ignored in strings. -** -** This function *never* returns a 0 unless an error occurred. +** This function returns 0 for missing or unreadable files. */ static const UInt4 syCcitt32[ 256 ] = { @@ -248,7 +245,7 @@ Int4 SyGAPCRC( const Char * name ) UInt4 crc; UInt4 old; UInt4 new; - Int4 ch; + Int ch; Int fid; BOOL seen_nl; @@ -273,21 +270,18 @@ Int4 SyGAPCRC( const Char * name ) } else seen_nl = FALSE; - old = (crc >> 8) & 0x00FFFFFFL; - new = syCcitt32[ ( (UInt4)( crc ^ ch ) ) & 0xff ]; + old = crc >> 8; + new = syCcitt32[(crc ^ ch) & 0xff]; crc = old ^ new; } - if ( crc == 0 ) { - crc = 1; - } // and close it again SyFclose( fid ); - // Emulate a signed shift: - if (crc & 0x80000000L) - return (Int4) ((crc >> 4) | 0xF0000000L); - else - return (Int4) (crc >> 4); + + // Emulate a signed shift (the C compiler does not specify whether right + // shifts preserve signs or not; it seems more or less all compilers in + // active use these days do, but better safe than sorry) + return ((Int)((crc >> 4) ^ 0x08000000U)) - 0x08000000; } @@ -320,7 +314,7 @@ static Obj FuncCrcString(Obj self, Obj str) UInt4 new; UInt4 i, len; const Char *ptr; - Int4 ch; + Int ch; BOOL seen_nl; RequireStringRep(SELF_NAME, str); @@ -330,7 +324,7 @@ static Obj FuncCrcString(Obj self, Obj str) crc = 0x12345678L; seen_nl = FALSE; for (i = 0; i < len; i++) { - ch = (Int4)(ptr[i]); + ch = (Int)(ptr[i]); if ( ch == '\377' || ch == '\n' || ch == '\r' ) ch = '\n'; if ( ch == '\n' ) { @@ -341,14 +335,15 @@ static Obj FuncCrcString(Obj self, Obj str) } else seen_nl = FALSE; - old = (crc >> 8) & 0x00FFFFFFL; - new = syCcitt32[ ( (UInt4)( crc ^ ch ) ) & 0xff ]; + old = crc >> 8; + new = syCcitt32[(crc ^ ch) & 0xff]; crc = old ^ new; } - if ( crc == 0 ) { - crc = 1; - } - return INTOBJ_INT(((Int4) crc) >> 4); + + // Emulate a signed shift (the C compiler does not specify whether right + // shifts preserve signs or not; it seems more or less all compilers in + // active use these days do, but better safe than sorry) + return INTOBJ_INT(((Int)((crc >> 4) ^ 0x08000000U)) - 0x08000000); } // Get OS Kernel version. Used to discover if GAP is running inside diff --git a/src/sysfiles.h b/src/sysfiles.h index 046ea30b68..96799788ee 100644 --- a/src/sysfiles.h +++ b/src/sysfiles.h @@ -23,8 +23,7 @@ ** *F SyGAPCRC( ) . . . . . . . . . . . . . . . . . . crc of a GAP file ** -** This function should be clever and handle white spaces and comments but -** one has to certain that such characters are not ignored in strings. +** This function returns 0 for missing or unreadable files. */ Int4 SyGAPCRC(const Char * name); From 3cd543fffe76a210f349a657d34347cd9038cec1 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 11 Jun 2026 22:40:12 +0200 Subject: [PATCH 40/50] doc: fix typo (#6438) --- doc/ref/helpintf.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ref/helpintf.xml b/doc/ref/helpintf.xml index 6ed9b9be27..3daccf2773 100644 --- a/doc/ref/helpintf.xml +++ b/doc/ref/helpintf.xml @@ -164,7 +164,7 @@ gap> stream := InputTextFile( file );; This must return a text string or list of text lines which contains the chapter headers of the book info.bookname. -ShowSection( info ) +ShowSections( info ) This must return a text string or list of text lines which contains the section (and chapter) headers of the book info.bookname. From f49b3f874aeb638feded172754491369e942e0e7 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 18 Jun 2026 15:52:03 +0100 Subject: [PATCH 41/50] replaced 'return []' by 'return fail' --- lib/field.gi | 4 ++-- lib/fldabnum.gi | 4 ++-- lib/ghomfp.gi | 2 +- lib/liefam.gi | 2 +- lib/mapping.gi | 8 ++++---- lib/relation.gi | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/field.gi b/lib/field.gi index ff2e31c3ba..6223cf0535 100644 --- a/lib/field.gi +++ b/lib/field.gi @@ -1338,7 +1338,7 @@ InstallMethod( PreImagesElm, [ IsFieldHomomorphism, IsObject ], function ( hom, elm ) if not (elm in Range(hom)) then - return []; + return fail; fi; return PreImagesElm( hom, elm ); end ); @@ -1365,7 +1365,7 @@ InstallMethod( PreImagesSet, [ IsFieldHomomorphism, IsField ], function ( hom, elms ) if not IsSubset( Range(hom), elms ) then - return []; + return fail; fi; return PreImagesSet( hom, elms ); end ); diff --git a/lib/fldabnum.gi b/lib/fldabnum.gi index 6c5f22d030..cfc60cc6d9 100644 --- a/lib/fldabnum.gi +++ b/lib/fldabnum.gi @@ -1936,7 +1936,7 @@ InstallMethod( PreImagesElm, [ IsFieldHomomorphism and IsANFAutomorphismRep, IsScalar ], function ( aut, elm ) if not ( elm in Range(aut) ) then - return []; + return fail; fi; return PreImagesElmNC( aut, elm ); end ); @@ -1960,7 +1960,7 @@ InstallMethod( PreImagesSet, [ IsFieldHomomorphism and IsANFAutomorphismRep, IsField ], function ( aut, F ) if not IsSubset( Range(aut), F ) then - return []; + return fail; fi; return PreImagesSetNC( aut, F ); end ); diff --git a/lib/ghomfp.gi b/lib/ghomfp.gi index fc045d8289..86d7fa5a9f 100644 --- a/lib/ghomfp.gi +++ b/lib/ghomfp.gi @@ -630,7 +630,7 @@ InstallMethod( PreImagesSet, "map from (sub)group of fp group", [ IsFromFpGroupHomomorphism,IsGroup ],0, function(hom,u) if not IsSubset( Range(hom), u ) then - return []; + return fail; fi; return PreImagesSetNC(hom,u); end); diff --git a/lib/liefam.gi b/lib/liefam.gi index 0a5590b03d..0f9f70c53f 100644 --- a/lib/liefam.gi +++ b/lib/liefam.gi @@ -463,7 +463,7 @@ InstallMethod( PreImagesElm, IsLieObject and IsPackedElementDefaultRep ], 0, function( emb, elm ) if not ( elm in Range(emb) ) then - return []; + return fail; fi; return PreImagesElm( emb, elm ); end ); diff --git a/lib/mapping.gi b/lib/mapping.gi index f54e58ee2d..5069534ba6 100644 --- a/lib/mapping.gi +++ b/lib/mapping.gi @@ -1159,7 +1159,7 @@ InstallMethod( PreImagesElm, function ( map, elm ) if not ( elm in Image( map ) ) then - return []; + return fail; else return PreImagesElmNC( map, elm ); fi; @@ -1192,7 +1192,7 @@ InstallMethod( PreImagesElm, [ IsGeneralMapping and IsConstantTimeAccessGeneralMapping, IsObject ], 0, function( map, elm ) if not ( elm in Image( map ) ) then - return []; + return fail; else return PreImagesElmNC( map, elm ); fi; @@ -1233,7 +1233,7 @@ InstallMethod( PreImagesSet, im:= Image( map ); for elm in Enumerator( elms ) do if not (elm in im ) then - return []; + return fail; fi; od; return PreImagesSetNC( map, elms ); @@ -1331,7 +1331,7 @@ InstallMethod( PreImagesRepresentative, [ IsNonSPGeneralMapping, IsObject ], 0, function( map, elm ) if not elm in Image( map ) then - return []; + return fail; fi; return PreImagesRepresentativeNC( map, elm ); end ); diff --git a/lib/relation.gi b/lib/relation.gi index e349d50d5e..db6005a732 100644 --- a/lib/relation.gi +++ b/lib/relation.gi @@ -1001,7 +1001,7 @@ InstallMethod(PreImagesElm, true, [IsBinaryRelation and IsBinaryRelationOnPointsRep, IsPosInt], 0, function( rel, n ) if not ( n in Range(rel) ) then - return []; + return fail; fi; return PreImagesElm( rel, n ); end ); @@ -1855,7 +1855,7 @@ InstallMethod( PreImagesElm, IsObject],0, function( rel, elm ) if not ( elm in Range( rel ) ) then ##?? is there a Range(rel)? - return []; + return fail; fi; return PreImagesElmNC( rel, elm ); end); From f3dd6175d94c2aa25cfa74ed01f13487943f1503 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:20:59 +0200 Subject: [PATCH 42/50] build(deps): bump actions/checkout from 6 to 7 (#6444) Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 6 +++--- .github/workflows/gapjl.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/release.yml | 6 +++--- .github/workflows/update-gh-pages.yml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e9937fed7f..e2586f8e27 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -141,7 +141,7 @@ jobs: TEST_SUITES: ${{ matrix.test-suites }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: "Set up Python" uses: actions/setup-python@v6 @@ -341,7 +341,7 @@ jobs: - name: Install cross compile dependencies run: sudo apt-get install -q -y libgmp-dev:s390x libreadline-dev:s390x zlib1g-dev:s390x - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: ./autogen.sh @@ -407,7 +407,7 @@ jobs: env: AUTOCONF_VERSION: 2.71 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Download required GAP packages run: | diff --git a/.github/workflows/gapjl.yml b/.github/workflows/gapjl.yml index 626f1a52a1..54032f9ed4 100644 --- a/.github/workflows/gapjl.yml +++ b/.github/workflows/gapjl.yml @@ -44,7 +44,7 @@ jobs: steps: - name: Checkout GAP - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: path: 'GAPROOT' - name: "Set up Julia" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bbf8e68ac8..63eca8aeb6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-slim steps: - name: "Check out the repository" - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: "Set up Python" uses: actions/setup-python@v6 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eb4ce3c91b..8c2b84a1ba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,7 @@ jobs: name: "Validate release scripts" runs-on: ubuntu-slim steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: "Set up Python" uses: actions/setup-python@v6 @@ -72,7 +72,7 @@ jobs: # requires fetching the entire history. Therefore, we might as well do # that here when checking out the repo, which is what setting fetch-depth # to 0 accomplishes here. - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: fetch-depth: 0 @@ -207,7 +207,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: "Clone the Windows installer maker scripts" - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: gap-system/gap-windows ref: main diff --git a/.github/workflows/update-gh-pages.yml b/.github/workflows/update-gh-pages.yml index e1ebb2c57b..cbafbb0093 100644 --- a/.github/workflows/update-gh-pages.yml +++ b/.github/workflows/update-gh-pages.yml @@ -41,7 +41,7 @@ jobs: sudo apt-get update sudo apt-get install --no-install-recommends "${packages[@]}" - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Configure GAP run: | ./autogen.sh && ./configure From 853273799e003388376948131fb60a86c06855ed Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 23 Jun 2026 11:10:59 +0200 Subject: [PATCH 43/50] Remove InfoData, make INFO_CLASSES readonly (#6443) --- lib/info.gi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/info.gi b/lib/info.gi index 7436dfa86b..7c873f9661 100644 --- a/lib/info.gi +++ b/lib/info.gi @@ -45,11 +45,7 @@ DeclareRepresentation("IsInfoClassListRep", IsAtomicPositionalObjectRep); # A list of all created InfoClassListReps -INFO_CLASSES := []; - -# InfoData is unused, but we keep it for now, to avoid warnings in GAPDoc. -# TODO: remove InfoData -InfoData := rec(); +BIND_GLOBAL( "INFO_CLASSES", [] ); if IsHPCGAP then ShareInternalObj(INFO_CLASSES); From 16256d19fc45b83d55bb8174b57185364a5cbdbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 24 Jun 2026 15:32:06 +0200 Subject: [PATCH 44/50] Move over changes to the GAP.jl-CI job (#6445) Also treat readline headers as system includes. This avoids Homebrew readline header warnings under --enable-Werror. Co-authored-by: Max Horn Co-authored-by: Codex --- .github/workflows/gapjl.yml | 22 +++++++++++++++++++++- configure.ac | 4 ++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gapjl.yml b/.github/workflows/gapjl.yml index 54032f9ed4..f23b79ddab 100644 --- a/.github/workflows/gapjl.yml +++ b/.github/workflows/gapjl.yml @@ -67,11 +67,31 @@ jobs: - name: "Install dependencies (for macOS)" if: runner.os == 'macOS' run: | - brew install autoconf zlib # gmp pkg-config + # - autoconf, gmp, zlib are needed by GAP's build system + # - coreutils provides nproc + # - force use of Homebrew gcc to build GAP for proper stacktrace support + # Homebrew installs versioned binaries such as gcc-14 and g++-14, + # while later scripts expect unversioned gcc and g++ in PATH. + brew install autoconf gmp zlib gcc@14 coreutils + + # ensure gcc and g++ are available under those names (on macOS, + # these names are aliases for clang / clang++ out of the box) + shimdir="${HOME}/bin" + mkdir -p "${shimdir}" + ln -sf "$(brew --prefix)/bin/gcc-14" "${shimdir}/gcc" + ln -sf "$(brew --prefix)/bin/g++-14" "${shimdir}/g++" + echo "${shimdir}" >> "${GITHUB_PATH}" - name: "Build GAP" run: | mv GAPROOT /tmp/GAPROOT cd /tmp/GAPROOT + patchdir=$GAPJLPATH/.github/workflows/GAP_patches/master + if [ -d $patchdir ]; then + for f in $patchdir/*.patch; do + echo "Applying patch ${f}" + patch -p1 -d . < ${f} + done + fi ./autogen.sh ./configure --enable-Werror make -j`nproc` diff --git a/configure.ac b/configure.ac index 9320f18ce0..10b9b528f8 100644 --- a/configure.ac +++ b/configure.ac @@ -727,12 +727,12 @@ for READLINE_PREFIX in ${READLINE_SEARCH_PATH} ; do [DEFAULTS_EREADLINE],[ dnl ereadline is the name of GNU readline library on OpenBSD READLINE_PREFIX="" - READLINE_CPPFLAGS="-I/usr/local/include/ereadline" + READLINE_CPPFLAGS="-isystem /usr/local/include/ereadline" READLINE_LDFLAGS="" READLINE_LIBS="-lereadline" ], [*],[ - READLINE_CPPFLAGS="-I${READLINE_PREFIX}/include" + READLINE_CPPFLAGS="-isystem ${READLINE_PREFIX}/include" READLINE_LDFLAGS="-L${READLINE_PREFIX}/lib" READLINE_LIBS="-lreadline" ] From bd1a466de433d24532640f16dfda6a33e230a7a8 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Wed, 1 Jul 2026 05:15:02 -0600 Subject: [PATCH 45/50] Perfect groups data is licensed under GPL 2.0 or later (#6450) --- grp/perf13.grp | 2 +- grp/perf14.grp | 2 +- grp/perf15.grp | 2 +- grp/perf16.grp | 2 +- grp/perf17.grp | 2 +- grp/perf18.grp | 2 +- grp/perf19.grp | 2 +- grp/perf20.grp | 2 +- grp/perf21.grp | 2 +- grp/perf22.grp | 2 +- grp/perf23.grp | 2 +- grp/perf24.grp | 2 +- grp/perf25.grp | 2 +- grp/perf26.grp | 2 +- grp/perf28.grp | 2 +- grp/perf29.grp | 2 +- grp/perf30.grp | 2 +- grp/perf31.grp | 2 +- grp/perf32.grp | 2 +- grp/perf34.grp | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/grp/perf13.grp b/grp/perf13.grp index 0f9a715bf9..9a66aacec6 100644 --- a/grp/perf13.grp +++ b/grp/perf13.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[96]:=[# 61440.1 [[1,"abcde", diff --git a/grp/perf14.grp b/grp/perf14.grp index eccd748827..fe20d8d587 100644 --- a/grp/perf14.grp +++ b/grp/perf14.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[111]:=[# 86016.1 [[1,"abcd", diff --git a/grp/perf15.grp b/grp/perf15.grp index 3e466c5c5b..96880d1a09 100644 --- a/grp/perf15.grp +++ b/grp/perf15.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[131]:=[# 122880.1 [[1,"abcdef", diff --git a/grp/perf16.grp b/grp/perf16.grp index 31da9f936f..3d74dd9c6e 100644 --- a/grp/perf16.grp +++ b/grp/perf16.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[150]:=[# 172032.1 [[1,"abc", diff --git a/grp/perf17.grp b/grp/perf17.grp index dce726788d..9f569b8930 100644 --- a/grp/perf17.grp +++ b/grp/perf17.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[179]:=[# 245760.1 [[1,"abcde", diff --git a/grp/perf18.grp b/grp/perf18.grp index e142e995b2..66d6548ebd 100644 --- a/grp/perf18.grp +++ b/grp/perf18.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[200]:=[# 344064.1 [[1,"abcd", diff --git a/grp/perf19.grp b/grp/perf19.grp index abcc2320e7..cbe80ff733 100644 --- a/grp/perf19.grp +++ b/grp/perf19.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[210]:=[# 368640.1 [[1,"abcdef", diff --git a/grp/perf20.grp b/grp/perf20.grp index d9fec32164..d14b2567e8 100644 --- a/grp/perf20.grp +++ b/grp/perf20.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[244]:=[# 491520.1 [[1,"abcde", diff --git a/grp/perf21.grp b/grp/perf21.grp index 5488fdc506..0a723692a3 100644 --- a/grp/perf21.grp +++ b/grp/perf21.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[276]:=[# 688128.1 [[1,"abcde", diff --git a/grp/perf22.grp b/grp/perf22.grp index ab14628e3f..873de9394a 100644 --- a/grp/perf22.grp +++ b/grp/perf22.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later number:=[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 7, 1, 1, 1, 1, 3, 1, 1, 1, 7, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 5, 1, 1, 3, 1, 1, 9, 4, 1, 1, diff --git a/grp/perf23.grp b/grp/perf23.grp index b260d3a331..e7cc9f0523 100644 --- a/grp/perf23.grp +++ b/grp/perf23.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[330]:=[# 983040.1 [[1,"abcdef", diff --git a/grp/perf24.grp b/grp/perf24.grp index 672b2f4d84..b48d5514f9 100644 --- a/grp/perf24.grp +++ b/grp/perf24.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[332]:=[# 1008000.1 [[1,"abcdef", diff --git a/grp/perf25.grp b/grp/perf25.grp index 1e51e86fc2..a3967e1db6 100644 --- a/grp/perf25.grp +++ b/grp/perf25.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[355]:=[# 1180980.1 [[1,"abcde", diff --git a/grp/perf26.grp b/grp/perf26.grp index f7486d8e91..7af1e2a545 100644 --- a/grp/perf26.grp +++ b/grp/perf26.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[371]:=[# 1290240.1 [[1,"abcdefg", diff --git a/grp/perf28.grp b/grp/perf28.grp index 69b0382d26..c9f45efb72 100644 --- a/grp/perf28.grp +++ b/grp/perf28.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[382]:=[# 1382400.1 [[1,"abcdefg", diff --git a/grp/perf29.grp b/grp/perf29.grp index fcffbacfd0..dcdc30b9e0 100644 --- a/grp/perf29.grp +++ b/grp/perf29.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[396]:=[# 1474560.1 [[1,"abcdefg", diff --git a/grp/perf30.grp b/grp/perf30.grp index 09144844f8..948a0c1e02 100644 --- a/grp/perf30.grp +++ b/grp/perf30.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[421]:=[# 1749600.1 [[1,"abcdefgh", diff --git a/grp/perf31.grp b/grp/perf31.grp index ca3418d68a..afc2d69797 100644 --- a/grp/perf31.grp +++ b/grp/perf31.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[435]:=[# 1843200.1 [[1,"abcdef", diff --git a/grp/perf32.grp b/grp/perf32.grp index a33d812d03..ee0f128a89 100644 --- a/grp/perf32.grp +++ b/grp/perf32.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[436]:=[# 1843968.1 [[1,"abcdef", diff --git a/grp/perf34.grp b/grp/perf34.grp index e78fe08416..683173f859 100644 --- a/grp/perf34.grp +++ b/grp/perf34.grp @@ -5,7 +5,7 @@ ## This data was computed by Alexander Hulpke ## It is distributed under the artistic license 2.0 ## https://opensource.org/licenses/Artistic-2.0 -## as well as (dual licensing) under GPL 2 +## as well as (dual licensing) under GPL-2.0-or-later PERFGRP[452]:=[# 1975680.1 [[1,"abcd", From 29814efe44c3a1dfd5d9e7a2b784586a081adcc4 Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Wed, 1 Jul 2026 13:17:18 +0200 Subject: [PATCH 46/50] Add an argument check to `CodePcgs` (#6451) --- lib/randiso.gi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/randiso.gi b/lib/randiso.gi index 5331eb51c3..15b1d8c520 100644 --- a/lib/randiso.gi +++ b/lib/randiso.gi @@ -240,6 +240,11 @@ end ); InstallGlobalFunction( CodePcgs, function( pcgs ) local code, indices, l, mi, i, base, nt, r, j, size; + # Check the argument. + if not ( IsPcgs( pcgs ) and IsPrimeOrdersPcgs( pcgs ) ) then + Error( " must be a pcgs in 'IsPrimeOrdersPcgs'" ); + fi; + # basic structures l := Length( pcgs ); if l = 0 then From 19f7a2e60570f17ed7b5781be8d793ef4db03993 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 1 Jul 2026 14:43:49 +0200 Subject: [PATCH 47/50] kernel: make FormatOutput handle %g with null pointer (#6446) In case someone uses '%g' in a format string but fails to provide a matching argument. Moreover, make sure we don't use `arg2` more then once. --- src/io.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/io.c b/src/io.c index 9484c39a01..eac2600859 100644 --- a/src/io.c +++ b/src/io.c @@ -1513,8 +1513,6 @@ static Obj FuncALL_KEYWORDS(Obj self) ** '%g' the corresponding argument is the address of a T_STRING string ** object which is printed. This is similar to using '%s' to print ** CSTR_STRING(arg), but is safe during garbage collection. -** '%G' the corresponding argument is the address of an Obj which points -** to a string in STRING_REP format which is printed in '%S' format ** '%C' the corresponding argument is the address of an Obj which points ** to a string in STRING_REP format which is printed with C escapes ** '%d' the corresponding argument is a signed integer, which is printed. @@ -1556,7 +1554,7 @@ static inline void FormatOutput( } // handle the case of a missing argument - if (arg1 == 0 && (*p == 's' || *p == 'S' || *p == 'C' || *p == 'I')) { + if (arg1 == 0 && (*p == 's' || *p == 'g' || *p == 'C' || *p == 'I')) { put_a_char(state, '<'); put_a_char(state, 'n'); put_a_char(state, 'u'); @@ -1566,6 +1564,7 @@ static inline void FormatOutput( // on to the next argument arg1 = arg2; + arg2 = 0; } // '%d' print an integer @@ -1591,6 +1590,7 @@ static inline void FormatOutput( // on to the next argument arg1 = arg2; + arg2 = 0; } // '%s' or '%g' print a string @@ -1650,6 +1650,7 @@ static inline void FormatOutput( // on to the next argument arg1 = arg2; + arg2 = 0; } // '%C' print a string with the necessary C escapes @@ -1699,6 +1700,7 @@ static inline void FormatOutput( // on to the next argument arg1 = arg2; + arg2 = 0; } // '%I' print an identifier @@ -1742,12 +1744,14 @@ static inline void FormatOutput( // on to the next argument arg1 = arg2; + arg2 = 0; } // '%c' print a character else if ( *p == 'c' ) { put_a_char(state, (Char)arg1); arg1 = arg2; + arg2 = 0; } // '%%' print a '%' character From d22a930210add69fec59c3d5a7cb77d626057ff5 Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Wed, 1 Jul 2026 15:18:55 +0200 Subject: [PATCH 48/50] turn the global variable `RUN_IN_GGMBI` into a global option `Run_In_GGMBI` (#6442) --- doc/ref/grphomom.xml | 11 ++++++++ grp/glzmodmz.gi | 8 +++--- lib/fitfree.gi | 52 ++++++++++++++++++------------------ lib/grpmat.gi | 6 ++--- lib/grpnice.gd | 3 +++ lib/grpnice.gi | 36 +++++++++++++++---------- lib/maxsub.gi | 4 +-- lib/oprt.gi | 10 +++---- lib/schursym.gi | 10 +++---- tst/testinstall/ggmbi.tst | 56 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 132 insertions(+), 64 deletions(-) create mode 100644 tst/testinstall/ggmbi.tst diff --git a/doc/ref/grphomom.xml b/doc/ref/grphomom.xml index 9e4536c88a..3878ed73a0 100644 --- a/doc/ref/grphomom.xml +++ b/doc/ref/grphomom.xml @@ -372,6 +372,17 @@ are satisfied. +A technical remark:Run_In_GGMBI + +

+ +In order to avoid infinite recursions when constructing nice monomorphisms, +the global option Run_In_GGMBI is set to true in certain +situations. +The value of this option is checked in methods for the operations + and +. + <#Include Label="IsHandledByNiceMonomorphism"> <#Include Label="NiceMonomorphism"> <#Include Label="NiceObject"> diff --git a/grp/glzmodmz.gi b/grp/glzmodmz.gi index 9271ea6976..97d5e7ca77 100644 --- a/grp/glzmodmz.gi +++ b/grp/glzmodmz.gi @@ -379,7 +379,7 @@ local oper,n,R,o,nrit, if fp <>fail then # extend presentation bas:=Basis(sub,bas); - RUN_IN_GGMBI:=true; + PushOptions( rec( Run_In_GGMBI:= true ) ); hom:=GroupGeneralMappingByImagesNC(g,fp,gens,GeneratorsOfGroup(fp)); hom:=LiftFactorFpHom(hom,g,SubgroupNC(g,basm),rec( pcgs:=basm, @@ -392,7 +392,7 @@ local oper,n,R,o,nrit, return List(Coefficients(bas,e),Int); end )); - RUN_IN_GGMBI:=false; + PopOptions(); #simplify Image to avoid explosion of generator number fp:=Range(hom); if true then @@ -412,11 +412,9 @@ local oper,n,R,o,nrit, k:=TzPreImagesNewGens(e); k:=List(k,x->j[1][Position(OldGeneratorsOfPresentation(e),x)]); - RUN_IN_GGMBI:=true; hom:=GroupHomomorphismByImagesNC(g,fp, k, - GeneratorsOfGroup(fp)); - RUN_IN_GGMBI:=false; + GeneratorsOfGroup(fp) : Run_In_GGMBI:= true ); fi; SetIsomorphismFpGroup(g,hom); diff --git a/lib/fitfree.gi b/lib/fitfree.gi index a683e7964c..e8669473c0 100644 --- a/lib/fitfree.gi +++ b/lib/fitfree.gi @@ -54,10 +54,10 @@ local ffs,pcisom,rest,kpc,k,x,ker,r,pool,i,xx,pregens,iso; rest:=GroupHomomorphismByImages(U,Range(ffs.factorhom),GeneratorsOfGroup(U), List(GeneratorsOfGroup(U),x->ImagesRepresentative(ffs.factorhom,x))); else - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment rest:=GroupHomomorphismByImagesNC(U,Range(ffs.factorhom),GeneratorsOfGroup(U), List(GeneratorsOfGroup(U),x->ImagesRepresentative(ffs.factorhom,x))); - RUN_IN_GGMBI:=false; + PopOptions(); fi; Assert(1,rest<>fail); @@ -276,9 +276,9 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom,subsz,pcimgs; if IsPermGroup(U) and AssertionLevel()>1 then rest:=GroupHomomorphismByImages(U,Range(hom),gens,imgs); else - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment rest:=GroupHomomorphismByImagesNC(U,Range(hom),gens,imgs); - RUN_IN_GGMBI:=false; + PopOptions(); fi; Assert(1,rest<>fail); @@ -319,11 +319,11 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom,subsz,pcimgs; else r:=SubgroupNC(G,ipcgs); fi; - RUN_IN_GGMBI:=true; + PushOptions( rec( Run_In_GGMBI:= true ) ); pcisom:=GroupHomomorphismByImagesNC(r, SubgroupNC(Range(ffs.pcisom),pcisom), ipcgs,pcisom); - RUN_IN_GGMBI:=false; + PopOptions(); fi; r:=rec(inducedfrom:=ffs, pcgs:=ipcgs, @@ -920,10 +920,10 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs,gens; x->PreImagesRepresentativeNC(fphom,x)); sg:=List(sf,x->PreImagesRepresentativeNC(hom,x)); sp:=[]; - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(Group(sg,One(G)),fp,sg, GeneratorsOfGroup(fp)); - RUN_IN_GGMBI:=false; + PopOptions(); @@ -940,9 +940,9 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs,gens; Append(sp,mpcgs); else # extend presentation - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=LiftFactorFpHom(fphom,Source(fphom),false,mpcgs); - RUN_IN_GGMBI:=false; + PopOptions(); fp:=Image(fphom); sp:=Concatenation(sp,mpcgs); fi; @@ -954,10 +954,10 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs,gens; gens:=GeneratorsOfGroup(ocr.complement); sg:=gens{[1..Length(sg)]}; sp:=gens{[Length(sg)+1..Length(gens)]}; - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(ocr.complement,fp,gens, GeneratorsOfGroup(fp)); - RUN_IN_GGMBI:=false; + PopOptions(); fi; od; @@ -1241,11 +1241,11 @@ local s,d,c,act,o,i,j,h,p,hf,img,n,k,ns,all,hl,hcomp, # now do complements one by one for j in [1..Length(pcgs)] do h:=ClosureGroup(dser[j],gens); - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(h,fp, Concatenation(GeneratorsOfGroup(dser[j]),gens), Concatenation(List(GeneratorsOfGroup(dser[j]),x->One(fp)),imgs)); - RUN_IN_GGMBI:=false; + PopOptions(); ocr:=rec(group:=h,modulePcgs:=pcgs[j], factorfphom:=fphom); @@ -1257,18 +1257,18 @@ local s,d,c,act,o,i,j,h,p,hf,img,n,k,ns,all,hl,hcomp, if Size(b)>Size(s) then h:=ClosureGroup(b,gens); - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(h,fp, Concatenation(GeneratorsOfGroup(b),gens), Concatenation(List(GeneratorsOfGroup(b),x->One(fp)),imgs)); - RUN_IN_GGMBI:=false; + PopOptions(); # get elementary abelian series from b to s dser:=elabser(b,s); pcgs:=List([2..Length(dser)],x->ModuloPcgs(dser[x-1],dser[x])); for j in pcgs do - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=LiftFactorFpHom(fphom,Source(fphom),false,j); - RUN_IN_GGMBI:=false; + PopOptions(); od; gens:=MappingGeneratorsImages(fphom); imgs:=gens[2];gens:=gens[1]; @@ -1326,12 +1326,12 @@ local s,d,c,act,o,i,j,h,p,hf,img,n,k,ns,all,hl,hcomp, # now do complement to NS(k)/k for z in [1..Length(pcgs)] do h:=ClosureGroup(dser[z],cgens); - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(h,fp, Concatenation(GeneratorsOfGroup(dser[z]),cgens), Concatenation(List(GeneratorsOfGroup(dser[z]),x->One(fp)), imgs)); - RUN_IN_GGMBI:=false; + PopOptions(); ocr:=rec(group:=h,modulePcgs:=pcgs[z], factorfphom:=fphom); @@ -1413,10 +1413,10 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs, x->PreImagesRepresentativeNC(fphom,x)); sg:=List(sf,x->PreImagesRepresentativeNC(hom,x)); sp:=[]; - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(Group(sg,One(G)),fp,sg, GeneratorsOfGroup(fp)); - RUN_IN_GGMBI:=false; + PopOptions(); for d in [2..Length(ser.depths)] do mran:=[ser.depths[d-1]..len]; @@ -1431,9 +1431,9 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs, Append(sp,mpcgs); else # extend presentation - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=LiftFactorFpHom(fphom,Source(fphom),false,mpcgs); - RUN_IN_GGMBI:=false; + PopOptions(); fp:=Image(fphom); sp:=Concatenation(sp,mpcgs); fi; @@ -1445,10 +1445,10 @@ local ser,hom,s,fphom,sf,sg,sp,fp,d,head,mran,nran,mpcgs,ocr,len,pcgs, gens:=GeneratorsOfGroup(ocr.complement); sg:=gens{[1..Length(sg)]}; sp:=gens{[Length(sg)+1..Length(gens)]}; - RUN_IN_GGMBI:=true; # hack to skip Nice treatment + PushOptions( rec( Run_In_GGMBI:= true ) ); # hack to skip Nice treatment fphom:=GroupGeneralMappingByImagesNC(ocr.complement,fp,gens, GeneratorsOfGroup(fp)); - RUN_IN_GGMBI:=false; + PopOptions(); fi; od; diff --git a/lib/grpmat.gi b/lib/grpmat.gi index 69966bc7a2..25d07eab9b 100644 --- a/lib/grpmat.gi +++ b/lib/grpmat.gi @@ -424,13 +424,11 @@ local field, dict, acts, start, j, zerov, zero, dim, base, partbas, heads, SetRange(hom,R); SetImagesSource(hom,R); SetMappingGeneratorsImages(hom,[acts,permimg]); -# p:=RUN_IN_GGMBI; # no niceomorphism translation here -# RUN_IN_GGMBI:=true; +# # no niceomorphism translation here # SetAsGroupGeneralMappingByImages ( hom, GroupHomomorphismByImagesNC -# ( G, R, acts, permimg ) ); +# ( G, R, acts, permimg : Run_In_GGMBI:= true ) ); # # SetFilterObj( hom, IsActionHomomorphismByBase ); -# RUN_IN_GGMBI:=p; if act=OnRight or act=OnPoints then # only store for action on right. projective action needs is own call to # `LinearActionBase' as this will set other needed parameters. diff --git a/lib/grpnice.gd b/lib/grpnice.gd index e22d72c39a..8d7dee5536 100644 --- a/lib/grpnice.gd +++ b/lib/grpnice.gd @@ -189,6 +189,9 @@ InstallSubsetMaintenance( IsHandledByNiceMonomorphism, IsHandledByNiceMonomorphism and IsGroup, IsGroup); +# We recommend the (documented) global option `Run_In_GGMBI` +# instead of the global variable `RUN_IN_GGMBI`, +# but `RUN_IN_GGMBI` is still supported because GAP packages might use it. RUN_IN_GGMBI:=false; # If somebody would call `GHBI' to make a # NiceMonomorphism, we would get an infinite recursion. # This flag can be set to avoid GHBIs to be translated diff --git a/lib/grpnice.gi b/lib/grpnice.gi index 25f7d78045..faf214a1f3 100644 --- a/lib/grpnice.gi +++ b/lib/grpnice.gi @@ -927,16 +927,22 @@ InstallMethod( GroupGeneralMappingByImagesNC, "from a group handled by a niceomorphism",true, [ IsGroup and IsHandledByNiceMonomorphism, IsGroup, IsList, IsList ], 0, function( G, H, gens, imgs ) -local nice,geni,map2,tmp; - if RUN_IN_GGMBI=true then +local nice,geni,map2; + if ValueOption( "Run_In_GGMBI" ) = true then + TryNextMethod(); + elif RUN_IN_GGMBI = true then + # Code was called that does not know about the global option. + # Make it work but print a warning. + Info( InfoWarning, 1, + "use the global option 'Run_In_GGMBI' not the global variable ", + "'RUN_IN_GGMBI', see '?Run_In_GGMBI'" ); TryNextMethod(); fi; - tmp := RUN_IN_GGMBI; - RUN_IN_GGMBI:=true; + PushOptions( rec( Run_In_GGMBI:= true ) ); nice:=RestrictedNiceMonomorphism(G); geni:=List(gens,i->ImageElm(nice,i)); map2:=GroupGeneralMappingByImagesNC(NiceObject(G),H,geni,imgs); - RUN_IN_GGMBI:=tmp; + PopOptions(); return CompositionMapping(map2,nice); end ); @@ -956,18 +962,20 @@ InstallMethod( AsGroupGeneralMappingByImages, [IsGroupGeneralMapping and IsNiceMonomorphism], {} -> RankFilter( IsHandledByNiceMonomorphism ), function(hom) -local h, tmp; - # we actually want to use the next method with `RUN_IN_GGMBI' set to + # we actually want to use the next method with `Run_In_GGMBI' set to # `true'. Therefore we redispatch, but will skip this method the second # time. - if RUN_IN_GGMBI=true then + if ValueOption( "Run_In_GGMBI" ) = true then + TryNextMethod(); + elif RUN_IN_GGMBI = true then + # Code was called that does not know about the global option. + # Make it work but print a warning. + Info( InfoWarning, 1, + "use the global option 'Run_In_GGMBI' not the global variable ", + "'RUN_IN_GGMBI', see '?Run_In_GGMBI'" ); TryNextMethod(); fi; - tmp := RUN_IN_GGMBI; - RUN_IN_GGMBI:=true; - h:=AsGroupGeneralMappingByImages(hom); - RUN_IN_GGMBI:=tmp; - return h; + return AsGroupGeneralMappingByImages( hom : Run_In_GGMBI:= true ); end); ############################################################################# @@ -980,7 +988,7 @@ InstallMethod( PreImagesRepresentativeNC, "for PBG-Niceo", [ IsPreimagesByAsGroupGeneralMappingByImages and IsNiceMonomorphism, IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) -local p, tmp; +local p; # avoid the double dispatch for `AsGroupGeneralMappingByImages' tmp := RUN_IN_GGMBI; RUN_IN_GGMBI:=true; diff --git a/lib/maxsub.gi b/lib/maxsub.gi index d9a9923d6d..c69f873028 100644 --- a/lib/maxsub.gi +++ b/lib/maxsub.gi @@ -219,10 +219,8 @@ BindGlobal("MaximalSubgroupClassesSol",function(G) # if necessary extent the fphom if homliftlevel+1 START_TEST( "ggmbi.tst" ); + +# Test the situations where the global option 'Run_In_GGMBI' occurs. +# - Print warnings when the deprecated global variable is used. +# (Do not use groups that are larger than their natural modules, +# since they could be cached.) +gap> G:= Group( [ [ 0, -1 ], [ 1, 0 ] ] );; +gap> nice:= NiceMonomorphism( G );; +gap> RUN_IN_GGMBI:= true;; +gap> AsGroupGeneralMappingByImages( nice );; +#I use the global option 'Run_In_GGMBI' not the global variable 'RUN_IN_GGMBI', see '?Run_In_GGMBI' +#I use the global option 'Run_In_GGMBI' not the global variable 'RUN_IN_GGMBI', see '?Run_In_GGMBI' +gap> G:= Group( [ [ 0, -1 ], [ 1, 0 ] ] );; +gap> gens:= GeneratorsOfGroup( G );; +gap> IsHandledByNiceMonomorphism( G ); +true +gap> GroupGeneralMappingByImagesNC( G, G, gens, gens );; +#I use the global option 'Run_In_GGMBI' not the global variable 'RUN_IN_GGMBI', see '?Run_In_GGMBI' +gap> RUN_IN_GGMBI:= false;; + +# - Run some examples where the option gets set, +# and where no other tests were available. +gap> G:= GL( IsPermGroup, 2, 5 );; +gap> U:= SL( IsPermGroup, 2, 5 );; +gap> Size( FittingFreeSubgroupSetup( G, U ).ker ); +2 + +# +gap> G:= Image( IsomorphismPermGroup( SchurCover( AlternatingGroup( 6 ) ) ) );; +gap> Size( SylowViaRadical( G, 3 ) ); +27 + +# +gap> G:= GL( IsPermGroup, 2, 5 );; +gap> Length( HallViaRadical( G, [ 2 ] ) ); +1 +gap> Length( HallViaRadical( G, [ 3 ] ) ); +1 + +# +gap> G:= SymmetricGroup( 5 );; +gap> Size( Source( EpimorphismSchurCover( G ) ) ); +240 +gap> G:= AlternatingGroup( 5 );; +gap> Size( Source( EpimorphismSchurCover( G ) ) ); +120 + +# +gap> G:= Group( Z(3) * [ [ [ 1, 1 ], [ 0, 1 ] ] ] );; +gap> Size( Image( SparseActionHomomorphism( G, +> Elements( GF(3)^2 ), [ Z(3) * [ 1, 0 ] ], OnRight ) ) ); +6 + +# +gap> STOP_TEST( "ggmbi.tst" ); From 18001cd60259ca84dc031d2b1520c254f2c6f306 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Wed, 1 Jul 2026 09:42:08 -0700 Subject: [PATCH 49/50] Document the encoding used by CodePcGroup & PcGroupCode (#6441) --- lib/randiso.gd | 77 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/lib/randiso.gd b/lib/randiso.gd index 2a33d8b415..5f66f30e93 100644 --- a/lib/randiso.gd +++ b/lib/randiso.gd @@ -21,13 +21,63 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup ); ## ## ## -## returns the code corresponding to pcgs. +## returns the non-negative integer code corresponding to the finite pcgs +## pcgs, which must be in . +## The code stores the relative orders of pcgs and +## the right hand sides of the nontrivial power and commutator relations +## of the pc presentation defined by pcgs. This integer encoding of +## pc groups underlies the group construction method described in +## . +##

+## More precisely, let +## g_1,\ldots,g_l be the entries of pcgs, and let +## r_1,\ldots,r_l be their relative orders. If l=0, +## the code is 0. Otherwise put +## m = \max_i r_i - 1. If the relative orders are not all equal, +## the first l base m digits are +## r_1-2,\ldots,r_l-2, so the relative order part is +## \sum_{i=1}^l (r_i-2)m^{l-i}. If the relative orders are all +## equal, this part is omitted; on decoding the relative orders are then +## read from the factorisation of the supplied group order. +##

+## After the relative order part comes a bit mask of length +## l(l+1)/2-1. The bits, from least significant to most +## significant, correspond first to the power relations +## g_1^{r_1},\ldots,g_{l-1}^{r_{l-1}}, and then to the +## commutators [g_j,g_i] for +## 1 \leq i < j \leq l, ordered by increasing i and, for +## fixed i, increasing j. A bit is 1 exactly when +## the corresponding right hand side is nontrivial. The final power +## relation g_l^{r_l}=1 is not stored separately. +##

+## The nontrivial right hand sides, in the same order as their set bits, +## are stored as base |G| digits, where G is the group +## generated by pcgs. If +## x = g_1^{e_1} \cdots g_l^{e_l}, with +## 0 \leq e_i < r_i, then the digit for x is +## \sum_{i=1}^l e_i\prod_{k=i+1}^l r_k. Equivalently, this is +## the zero-based position of x in the canonical list +## g_1^{e_1}\cdots g_l^{e_l}, ordered according to the +## lexicographic order of the tuples e_1,\dots,e_l. +##

+## Thus if b is m^l when the relative order part is present +## and 1 otherwise, if u is the bit mask, and if +## a_1,\ldots,a_t are the digits for the nontrivial right hand +## sides, then the complete code is +## A + b(u + 2^{l(l+1)/2-1}(a_1 + |G|a_2 + \cdots + +## |G|^{t-1}a_t)), where A is the relative order part, or +## 0 if that part is omitted. ## G := CyclicGroup(512);; +## gap> G := CyclicGroup(8);; ## gap> p := Pcgs( G );; ## gap> CodePcgs( p ); -## 162895587718739690298008513020159 +## 323 ## ]]> +## In this example the relative orders are [2,2,2], so there is +## no relative order part. The nontrivial power tails are g_2 +## and g_3, with digits 2 and 1 in the canonical +## list. Hence the code is +## 1 + 2 + 2^5(2 + 8\cdot 1) = 323. ## ## ## <#/GAPDoc> @@ -43,11 +93,15 @@ DeclareGlobalFunction( "CodePcgs" ); ## ## ## -## returns the code for a pcgs of G. +## returns the code for the pcgs returned by Pcgs for G. +## The encoding is the one described for . ## G := DihedralGroup(512);; -## gap> CodePcGroup( G ); -## 2940208627577393070560341803949986912431725641726 +## gap> G := CyclicGroup(8);; +## gap> code := CodePcGroup( G ); +## 323 +## gap> H := PcGroupCode( code, Size( G ) );; +## gap> IsCyclic( H ) and Size( H ) = Size( G ); +## true ## ]]> ## ## @@ -69,6 +123,15 @@ DeclareGlobalFunction( "CodePcGroup" ); ## otherwise anything may happen. ## Valid codes are usually obtained by one of the functions ## or . +## The inverse construction uses the integer format described for +## . The length of the pcgs, and in the case where +## all relative orders are equal also the relative orders themselves, are +## recovered from the prime factorisation of size. +##

+## The same integer format is also used by Magma's +## SmallGroupEncoding and SmallGroupDecoding, and by +## OSCAR's encode for pc groups and +## pc_group( order, code ). ## G := SmallGroup( 24, 12 );; ## gap> p := Pcgs( G );; From 4a30040fe68d2cbaca44b3026ed08015c3188e9d Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 20 May 2026 09:13:46 +0100 Subject: [PATCH 50/50] re-edited library files, adding NC --- lib/mapping.gd | 4 +- lib/mapprep.gi | 4 +- lib/vspchom.gi.changed | 2256 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2260 insertions(+), 4 deletions(-) create mode 100644 lib/vspchom.gi.changed diff --git a/lib/mapping.gd b/lib/mapping.gd index 497fe25b85..2b391b67cb 100644 --- a/lib/mapping.gd +++ b/lib/mapping.gd @@ -751,7 +751,7 @@ DeclareAttribute( "ImagesSource", IsGeneralMapping ); ## ## is the set of preimages of the range of the general mapping map. ##

-## delegates to , +## delegates to , ## it is introduced only to store the preimage of map as attribute ## value. ## @@ -977,7 +977,7 @@ DeclareGlobalFunction( "Images" ); ## ## ## If elm is an element of the range of the general mapping -## map then returns the set of all +## map then returns the set of all ## preimages of elm under map. ##

## From &GAP; version 4.16.0 diff --git a/lib/mapprep.gi b/lib/mapprep.gi index 8b3ebe6fc2..8be5d05fc6 100644 --- a/lib/mapprep.gi +++ b/lib/mapprep.gi @@ -325,7 +325,7 @@ InstallMethod( PreImagesElm, [ IsCompositionMappingRep, IsObject ], 0, function( com, elm ) if not ( elm in Range(com) ) then - return []; + return fail; fi; return PreImagesElmNC( com, elm ); end ); @@ -2022,7 +2022,7 @@ InstallMethod( PreImagesElm, [ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm ) if not ( elm in Range(res) ) then - return []; + return fail; fi; return PreImagesElmNC( res, elm ); end ); diff --git a/lib/vspchom.gi.changed b/lib/vspchom.gi.changed new file mode 100644 index 0000000000..7fe397f6bd --- /dev/null +++ b/lib/vspchom.gi.changed @@ -0,0 +1,2256 @@ +############################################################################# +## +## This file is part of GAP, a system for computational discrete algebra. +## This file's authors include Thomas Breuer. +## +## 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 methods for general linear mappings of finite +## dimensional free left modules. +## +## There are two default representations of such general mappings, +## one by generators and images, the other by two bases and a matrix. +## +## Note that a matrix is not the appropriate object to represent a general +## linear mapping if it is not total or not single-valued; +## moreover, if one does not prescribe images of a basis but of an +## arbitrary generating system, one does not want to compute a basis at the +## time the general mapping is formed; +## finally, the matrix is not appropriate to compute preimages, whereas +## the general mapping by images behaves symmetrically in this respect. +## +## (The matrix is best for linear mappings used as arithmetic elements, +## for mapping elements of the source to the range and back; storing +## images and preimages avoids the matrix multiplication.) +## +## 1. methods for linear general mappings given by images +## 2. methods for linear mappings given by matrices +## 3. methods for vector spaces of linear mappings +## 4. methods for algebras of linear mappings +## 5. methods for full hom spaces +## + +#T TODO: +#T +#T specific representation for nat. hom. +#T (choice of coefficients instead of silly matrix) +#T AsLeftModuleGeneralMappingByImages, to allow id + id, c * id, -id, +#T Zero( id ), id + zero, - zero, c * zero, ... +#T \= methods for m.b.m. and g.m.b.i. (if bases coincide, compare data) +#T parent dependencies for nat. hom. + +#T put bases into mappings; +#T check that they are really bases of source/range! + + +############################################################################# +## +## 1. methods for linear general mappings given by images +## + +############################################################################# +## +#R IsLinearGeneralMappingByImagesDefaultRep +## +## is a default representation of $F$-linear general mappings between two +## free left modules $V$ and $W$ where $F$ is equal to the left acting +## domain of $V$ and of $W$. +## +#T (It would be possible to allow situations where $F$ is only contained +#T in the left acting domain of $W$; +#T this would lead to asymmetry w.r.t. taking the inverse general mapping.) +## +## Defining components are +## +## `generators' \: \\ +## list of vectors in $V$, +## +## `genimages' \: \\ +## list of vectors in $W$. +## +## The general mapping is defined as the linear closure of the relation +## that joins the $i$-th entry in `generators' and the $i$-th entry in +## `genimages'. +## +## If one wants to compute images, one needs the components +## `basispreimage' \: \\ +## a basis of the $F$-module generated by `generators', +## +## `imagesbasispreimage' \: \\ +## images of the basis vectors of `basispreimage', +## +## `corelations' \: \\ +## linearly independent generators for the corelation space, +## i.e., of the space of all row vectors such that +## `LinearCombination( , generators )' is zero in $V$. +## (The corresponding linear combinations of `genimages' +## generate the cokernel.) +## +## If these components are not yet bound, they are computed by +## `MakeImagesInfoLinearGeneralMappingByImages' when they are needed. +## If `generators' is a *basis* of a free left module then these +## components can be entered without extra work. +## +## If one wants to compute preimages, one needs the components +## `basisimage' \: \\ +## a basis of the $F$-module generated by `genimages', +## +## `preimagesbasisimage' \: \\ +## preimages of the basis vectors of `basisimage', +## +## `relations' \: \\ +## linearly independent generators for the relation space, +## i.e., of the space of all row vectors such that +## `LinearCombination( , genimages )' is zero in $W$. +## (The corresponding linear combinations of `generators' +## generate the kernel.) +## +## If these components are not yet bound, they are computed by +## `MakePreImagesInfoLinearGeneralMappingByImages' when they are needed. +## If `genimages' is a *basis* of a free left module then these +## components can be entered without extra work. +## +## Computed images and preimages of free left modules under linear mappings +## are always free left modules. +## If one needs more structure (e.g., that of an algebra) for an image or +## preimage then the linear mapping must have a special representation. +## +## Note that the inverse general mapping of a linear mapping defined by +## images is best handled if it uses the default method, +## since such an inverse general mapping delegates the tasks of computing +## (pre)images to the original general mapping. +## So the (pre)images info is computed only once. +#T but what about sums of such mappings? +#T better try to share info also in this case? +#T (share a list that is filled with the info later?) +## +DeclareRepresentation( "IsLinearGeneralMappingByImagesDefaultRep", + IsAttributeStoringRep, + [ "basisimage", "preimagesbasisimage", "corelations", + "basispreimage", "imagesbasispreimage", "relations", + "generators", "genimages" ] ); + +InstallTrueMethod( IsAdditiveElementWithInverse, + IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ); +InstallTrueMethod( IsLeftModuleGeneralMapping, + IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ); + + +############################################################################# +## +#M LeftModuleGeneralMappingByImages( , , , ) +## +InstallMethod( LeftModuleGeneralMappingByImages, + "for two free left modules and two homogeneous lists", + [ IsFreeLeftModule, IsFreeLeftModule, + IsHomogeneousList, IsHomogeneousList ], + function( S, R, gens, imgs ) + + local map; # general mapping from to , result + + # Check the arguments. + if Length( gens ) <> Length( imgs ) then + Error( " and must have the same length" ); + elif not IsSubset( S, gens ) then + Error( " must lie in " ); + elif not IsSubset( R, imgs ) then + Error( " must lie in " ); + elif LeftActingDomain( S ) <> LeftActingDomain( R ) then + Error( " and must have same left acting domain" ); + fi; + + # Make the general mapping. + map:= Objectify( TypeOfDefaultGeneralMapping( S, R, + IsSPGeneralMapping + and IsLeftModuleGeneralMapping + and IsLinearGeneralMappingByImagesDefaultRep ), + rec() ); + + SetMappingGeneratorsImages(map,[gens,imgs]); + # Handle the case that `gens' is a basis. + if IsBasis( gens ) then + map!.basispreimage := gens; + map!.imagesbasispreimage := imgs; + map!.corelations := Immutable( [] ); + fi; + + # Handle the case that `imgs' is a basis. + if IsBasis( imgs ) then + map!.basisimage := imgs; + map!.preimagesbasisimage := gens; + map!.relations := Immutable( [] ); + fi; + + # return the general mapping + return map; + end ); + + +############################################################################# +## +#M LeftModuleHomomorphismByImagesNC( , , , ) +## +InstallMethod( LeftModuleHomomorphismByImagesNC, + "for two left modules and two lists", + [ IsFreeLeftModule, IsFreeLeftModule, IsList, IsList ], + function( S, R, gens, imgs ) + local map; # homomorphism from to , result + map:= LeftModuleGeneralMappingByImages( S, R, gens, imgs ); + SetIsSingleValued( map, true ); + SetIsTotal( map, true ); + return map; + end ); + + +############################################################################# +## +#F LeftModuleHomomorphismByImages( , , , ) +## +InstallGlobalFunction( LeftModuleHomomorphismByImages, + function( S, R, gens, imgs ) + local hom; + hom:= LeftModuleGeneralMappingByImages( S, R, gens, imgs ); + if IsMapping( hom ) then + return LeftModuleHomomorphismByImagesNC( S, R, gens, imgs ); + else + return fail; + fi; +end ); + + +############################################################################# +## +#M AsLeftModuleGeneralMappingByImages( ) . for a lin. gen. mapping +## +InstallMethod( AsLeftModuleGeneralMappingByImages, + "for a linear g.m.b.i.", + [ IsLeftModuleGeneralMapping + and IsLinearGeneralMappingByImagesDefaultRep ], + IdFunc ); + + +############################################################################# +## +#M ImagesSource( ) . . . . . . . . . . . . . . . . for linear g.m.b.i. +## +InstallMethod( ImagesSource, + "for a linear g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + if IsBound( map!.basisimage ) then + return UnderlyingLeftModule( map!.basisimage ); + else + return SubmoduleNC( Range( map ), MappingGeneratorsImages(map)[2] ); +#T is it used that the second argument may be a basis object? + fi; + end ); + + +############################################################################# +## +#M PreImagesRange( ) . . . . . . . . . . . . . . . for linear g.m.b.i. +## +InstallMethod( PreImagesRange, + "for a linear g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + if IsBound( map!.basispreimage ) then + return UnderlyingLeftModule( map!.basispreimage ); + else + return SubmoduleNC( Source( map ), MappingGeneratorsImages(map)[1] ); +#T is it used that the second argument may be a basis object? + fi; + end ); + + +############################################################################# +## +#F MakeImagesInfoLinearGeneralMappingByImages( ) +## +## Provide the information for computing images, that is, set up +## the components `basispreimage', `imagesbasispreimage', `corelations'. +## +BindGlobal( "MakeImagesInfoLinearGeneralMappingByImages", function( map ) + local preimage, + ech, + mapi, + B; + + preimage:= PreImagesRange( map ); + mapi:= MappingGeneratorsImages( map ); + + if Dimension( preimage ) = 0 then + + # Set the entries explicitly. + map!.basispreimage := Basis( preimage ); + map!.corelations := IdentityMat( Length( mapi[2] ), + LeftActingDomain( preimage ) ); + map!.imagesbasispreimage := Immutable( [] ); + + elif IsGaussianRowSpace( Source( map ) ) then +#T operation MakeImagesInfo( map, source ) +#T to leave this to the method selection ? +#T or flag `IsFromGaussianSpace' ? + + # The images of the basis vectors are obtained on + # forming the linear combinations of images of generators + # given by `ech.coeffs'. + + ech:= SemiEchelonMatTransformation( mapi[1] ); + map!.basispreimage := SemiEchelonBasisNC( + preimage, ech.vectors ); + map!.corelations := Immutable( ech.relations ); + map!.imagesbasispreimage := Immutable( ech.coeffs * mapi[2] ); +#T problem if mapi[2] is a basis and if this does not store that it is a small list! + + else + + # Delegate the work to the associated row space. + B:= Basis( preimage ); + ech:= SemiEchelonMatTransformation( List( mapi[1], + x -> Coefficients( B, x ) ) ); + map!.basispreimage := BasisNC( preimage, + List( ech.vectors, + x -> LinearCombination( B, x ) ) ); + map!.corelations := Immutable( ech.relations ); + map!.imagesbasispreimage := Immutable( List( ech.coeffs, + x -> LinearCombination( mapi[2], x ) ) ); + + fi; +end ); + + +############################################################################# +## +#F MakePreImagesInfoLinearGeneralMappingByImages( ) +## +## Provide the information for computing preimages, that is, set up +## the components `basisimage', `preimagesbasisimage', `relations'. +## +BindGlobal( "MakePreImagesInfoLinearGeneralMappingByImages", function( map ) + local image, + ech, + mapi, + B; + + mapi:= MappingGeneratorsImages( map ); + image:= ImagesSource( map ); + + if Dimension( image ) = 0 then + + # Set the entries explicitly. + map!.basisimage := Basis( image ); + map!.relations := IdentityMat( Length( mapi[1] ), + LeftActingDomain( image ) ); + map!.preimagesbasisimage := Immutable( [] ); + + elif IsGaussianRowSpace( Range( map ) ) then + + # The preimages of the basis vectors are obtained on + # forming the linear combinations of preimages of genimages + # given by `ech.coeffs'. + ech:= SemiEchelonMatTransformation( mapi[2] ); + map!.basisimage := SemiEchelonBasisNC( image, ech.vectors ); + map!.relations := Immutable( ech.relations ); + map!.preimagesbasisimage := Immutable( ech.coeffs * mapi[1]); +#T problem if mapi[1] is a basis and if this does not store that it is a small list! + + else + + # Delegate the work to the associated row space. + B:= Basis( image ); + ech:= SemiEchelonMatTransformation( List( mapi[2], + x -> Coefficients( B, x ) ) ); + map!.basisimage := BasisNC( image, + List( ech.vectors, + x -> LinearCombination( B, x ) ) ); + map!.relations := Immutable( ech.relations ); + map!.preimagesbasisimage := Immutable( List( ech.coeffs, + row -> LinearCombination( + row, mapi[1] ) ) ); + + fi; +end ); + + +############################################################################# +## +#M CoKernelOfAdditiveGeneralMapping( ) . . . for left module g.m.b.i. +## +InstallMethod( CoKernelOfAdditiveGeneralMapping, + "for left module g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local genimages; + + # Form the linear combinations of the basis vectors for the + # corelation space with the `genimages' of `map'. + + if not IsBound( map!.corelations ) then + MakeImagesInfoLinearGeneralMappingByImages( map ); + fi; + genimages:= MappingGeneratorsImages(map)[2]; + return SubmoduleNC( Range( map ), + List( map!.corelations, + r -> LinearCombination( genimages, r ) ) ); + end ); + + +############################################################################# +## +#M IsSingleValued( ) . . . . . . . . . . . . for left module g.m.b.i. +## +InstallMethod( IsSingleValued, + "for left module g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local genimages; + + if not IsBound( map!.corelations ) then + MakeImagesInfoLinearGeneralMappingByImages( map ); + fi; + genimages:= MappingGeneratorsImages(map)[2]; + return ForAll( map!.corelations, + r -> IsZero( LinearCombination( genimages, r ) ) ); + end ); + + +############################################################################# +## +#M KernelOfAdditiveGeneralMapping( ) . . . . for left module g.m.b.i. +## +InstallMethod( KernelOfAdditiveGeneralMapping, + "for left module g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local generators; + + # Form the linear combinations of the basis vectors for the + # relation space with the `generators' of `map'. + + if not IsBound( map!.relations ) then + MakePreImagesInfoLinearGeneralMappingByImages( map ); + fi; + generators:= MappingGeneratorsImages(map)[1]; + return SubmoduleNC( Source( map ), + List( map!.relations, + r -> LinearCombination( generators, r ) ) ); + end ); + + +############################################################################# +## +#M IsInjective( ) . . . . . . . . . . . . . for left module g.m.b.i. +## +InstallMethod( IsInjective, + "for left module g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local generators; + + if not IsBound( map!.relations ) then + MakePreImagesInfoLinearGeneralMappingByImages( map ); + fi; + generators:= MappingGeneratorsImages(map)[1]; + return ForAll( map!.relations, + r -> IsZero( LinearCombination( generators, r ) ) ); + end ); + + +############################################################################# +## +#M ImagesRepresentative( , ) . . . . . for left module g.m.b.i. +## +InstallMethod( ImagesRepresentative, + "for left module g.m.b.i., and element", + FamSourceEqFamElm, + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsObject ], + function( map, elm ) + if not IsBound( map!.basispreimage ) then + MakeImagesInfoLinearGeneralMappingByImages( map ); + fi; + elm:= Coefficients( map!.basispreimage, elm ); + if elm = fail then + return fail; + elif IsEmpty( elm ) then + return Zero( Range( map ) ); + fi; + return LinearCombination( map!.imagesbasispreimage, elm ); + end ); + + +############################################################################# +## +#M PreImagesRepresentative( , ) . . . . for left module g.m.b.i. +#M PreImagesRepresentativeNC( , ) . . . for left module g.m.b.i. +## +InstallMethod( PreImagesRepresentativeNC, + "for left module g.m.b.i., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsObject ], + function( map, elm ) + if not IsBound( map!.basisimage ) then + MakePreImagesInfoLinearGeneralMappingByImages( map ); + fi; + elm:= Coefficients( map!.basisimage, elm ); + if elm = fail then + return fail; + fi; + return LinearCombination( map!.preimagesbasisimage, elm ); + end ); + +InstallMethod( PreImagesRepresentative, + "for left module g.m.b.i., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsObject ], + function( map, elm ) + if not ( elm in Image( map ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); + +############################################################################# +## +#M ViewObj( ) . . . . . . . . . . . . . . . for left module g.m.b.i. +## +InstallMethod( ViewObj, + "for a left module g.m.b.i", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local mapi; + + mapi:= MappingGeneratorsImages( map ); + View( mapi[1] ); + Print( " -> " ); + View( mapi[2] ); + end ); + + +############################################################################# +## +#M PrintObj( ) . . . . . . . . . . . . . . . for left module g.m.b.i. +## +InstallMethod( PrintObj, + "for a left module g.m.b.i", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local mapi; + + mapi:= MappingGeneratorsImages( map ); + Print( "LeftModuleGeneralMappingByImages( ", + Source( map ), ", ", Range( map ), ", ", + mapi[1], ", ", mapi[2], " )" ); + end ); + +InstallMethod( PrintObj, + "for a left module hom. b.i", + [ IsMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local mapi; + + mapi:= MappingGeneratorsImages( map ); + Print( "LeftModuleHomomorphismByImages( ", + Source( map ), ", ", Range( map ), ", ", + mapi[1], ", ", mapi[2], " )" ); + end ); + + +############################################################################# +## +#M \*( , ) . . . . . . . . . . . . for scalar and linear g.m.b.i. +## +InstallMethod( \*, + "for scalar and linear g.m.b.i.", + [ IsMultiplicativeElement, + IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( scalar, map ) + local mult, # the multiple of `map', result + mapi, # generators and images + F; # left acting domain + + # Check the scalar. + # (Maybe it is in fact another mapping, and we want to compose.) + if not IsInt( scalar ) + and not IsElmsColls( FamilyObj( scalar ), + FamilyObj( LeftActingDomain( Range( map ) ) ) ) then + TryNextMethod(); + fi; + + mapi:=MappingGeneratorsImages(map); + # Construct the linear general mapping (if possible). + mult:= LeftModuleGeneralMappingByImages( + Source( map ), Range( map ), mapi[1], + List( mapi[2], v -> scalar * v ) ); + + # Maintain info on the preimage side of the general mapping. + if IsBound( map!.basispreimage ) then + mult!.basispreimage := map!.basispreimage; + mult!.imagesbasispreimage := Immutable( + List( map!.imagesbasispreimage, v -> scalar * v ) ); + mult!.corelations := map!.corelations; + fi; + + # Being a mapping is preserved by scalar multiplication. + if HasIsSingleValued( map ) then + SetIsSingleValued( mult, IsSingleValued( map ) ); + fi; + if HasIsTotal( map ) then + SetIsTotal( mult, IsTotal( map ) ); + fi; + + # If the scalar is invertible in the left acting domain of the source + # then surjectivity and injectivity are maintained as well as the image. + F:= LeftActingDomain( Source( map ) ); + if scalar in F and IsUnit( F, scalar ) then + + if HasIsInjective( map ) then + SetIsInjective( mult, IsInjective( map ) ); + fi; + if HasIsSurjective( map ) then + SetIsSurjective( mult, IsSurjective( map ) ); + fi; + + if IsBound( map!.basisimage ) then + scalar:= Inverse( scalar ); + mult!.basisimage := map!.basisimage; + mult!.preimagesbasisimage := Immutable( + List( map!.preimagesbasisimage, v -> scalar * v ) ); + mult!.relations := map!.relations; + fi; + + fi; + + return mult; + end ); + + +############################################################################# +## +#M AdditiveInverseOp( ) . . . . . . . . . . . . . for linear g.m.b.i. +## +InstallMethod( AdditiveInverseOp, + "for linear g.m.b.i.", + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map ) + local ainv, # the additive inverse of `map', result + mapi; + + mapi:=MappingGeneratorsImages(map); + # Construct the linear general mapping (if possible). + ainv:= LeftModuleGeneralMappingByImages( + Source( map ), Range( map ), mapi[1], + List( mapi[2], AdditiveInverse ) ); + + # Maintain images and preimages info. + if IsBound( map!.basispreimage ) then + ainv!.basispreimage := map!.basispreimage; + ainv!.imagesbasispreimage := Immutable( + List( map!.imagesbasispreimage, AdditiveInverse ) ); + ainv!.corelations := map!.corelations; + fi; + if IsBound( map!.basisimage ) then + ainv!.basisimage := map!.basisimage; + ainv!.preimagesbasisimage := Immutable( + List( map!.preimagesbasisimage, AdditiveInverse ) ); + ainv!.relations := map!.relations; + fi; + + # Being a mapping is preserved by scalar multiplication. + if HasIsSingleValued( map ) then + SetIsSingleValued( ainv, IsSingleValued( map ) ); + fi; + if HasIsTotal( map ) then + SetIsTotal( ainv, IsTotal( map ) ); + fi; + + # Surjectivity and injectivity are maintained. + if HasIsInjective( map ) then + SetIsInjective( ainv, IsInjective( map ) ); + fi; + if HasIsSurjective( map ) then + SetIsSurjective( ainv, IsSurjective( map ) ); + fi; + + return ainv; + end ); + + +############################################################################# +## +#T \<( , ) +## +## method for two linear mappings from Gaussian spaces, use canonical bases? +## + + +############################################################################# +## +#M CompositionMapping2( , map1> ) for left mod. hom. & lin. g.m.b.i. +## +InstallMethod( CompositionMapping2, + "for left module hom. and linear g.m.b.i.", + FamSource1EqFamRange2, + [ IsLeftModuleHomomorphism, + IsLeftModuleGeneralMapping + and IsLinearGeneralMappingByImagesDefaultRep ], + function( map2, map1 ) + local comp, # composition of and , result + mapi1, + gens, + genimages; + + # Check that the linear mappings can be composed. + + mapi1:=MappingGeneratorsImages(map1); + # Compute images for the generators of `map1'. + if IsLinearGeneralMappingByImagesDefaultRep( map2 ) + and mapi1[2] = MappingGeneratorsImages(map2)[1] then + + gens := mapi1[1]; + genimages := MappingGeneratorsImages(map2)[2]; + + else + + gens:= mapi1[1]; + genimages:= List( mapi1[2], + v -> ImagesRepresentative( map2, v ) ); + + fi; + + # Construct the linear general mapping. + comp:= LeftModuleGeneralMappingByImages( + Source( map1 ), Range( map2 ), gens, genimages ); + + # Maintain images info (only if `gens' is not a basis). + if IsLinearGeneralMappingByImagesDefaultRep( comp ) + and not IsBound( comp!.basispreimage ) + and IsBound( map1!.basispreimage ) then + comp!.basispreimage := map1!.basispreimage; + comp!.corelations := map1!.corelations; + comp!.imagesbasispreimage := Immutable( + List( map1!.imagesbasispreimage, + v -> ImagesRepresentative( map2, v ) ) ); + fi; + + # Return the composition. + return comp; + end ); + + +############################################################################# +## +#M \+( , map2> ) . . . . . . . . . . . . . . . for two linear g.m.b.i. +## +## If both general mappings respect zero, additive inverses, scalar +## multiplication then the sum also does. +## +InstallOtherMethod( \+, + "for linear g.m.b.i. and general mapping", + IsIdenticalObj, + [ IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsGeneralMapping ], + function( map1, map2 ) + local gens, + genimages, + mapi1, + sum; + + # Check that the linear mappings can be added. + if Source( map1 ) <> Source( map2 ) + or Range( map1 ) <> Range( map2 ) then + Error( " and must have same source and range" ); + elif PreImagesRange( map1 ) <> PreImagesRange( map2 ) then + Error( " and must have same preimage" ); + fi; + + mapi1:=MappingGeneratorsImages(map1); + + if IsLinearGeneralMappingByImagesDefaultRep( map2 ) + and mapi1[1] = MappingGeneratorsImages(map2)[1] then + + # If the generators in both general mappings are the same, + # it suffices to add the images. + gens := mapi1[1]; + genimages := mapi1[2] + MappingGeneratorsImages(map2)[2]; + + else + + # Compute images of the generators of `map1' under `map2'. + # (Note that both general mappings must be described in terms of + # `generators' in order to keep the meaning of `corelations'.) + gens:= mapi1[1]; + genimages:= mapi1[2] + + List( mapi1[1], + v -> ImagesRepresentative( map2, v ) ); + + fi; + + # Construct the linear general mapping. + sum:= LeftModuleGeneralMappingByImages( + Source( map1 ), Range( map1 ), gens, genimages ); + + # Maintain images info (only if `gens' is not a basis). + if IsLinearGeneralMappingByImagesDefaultRep( sum ) + and IsLinearGeneralMappingByImagesDefaultRep( map2 ) + and not IsBound( sum!.basispreimage ) + and IsBound( map1!.basispreimage ) + and IsBound( map2!.basispreimage ) + and map1!.basispreimage = map2!.basispreimage then + sum!.basispreimage := map1!.basispreimage; + sum!.corelations := map1!.corelations; + sum!.imagesbasispreimage := + map1!.imagesbasispreimage + map2!.imagesbasispreimage; + fi; + + # Return the sum. + return sum; +end ); + +InstallOtherMethod( \+, + "for general mapping and linear g.m.b.i.", + IsIdenticalObj, + [ IsGeneralMapping, + IsGeneralMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map1, map2 ) + local gens, + genimages, + mapi2, + sum; + + # Check that the linear mappings can be added. + if Source( map1 ) <> Source( map2 ) + or Range( map1 ) <> Range( map2 ) then + Error( " and must have same source and range" ); + elif PreImagesRange( map1 ) <> PreImagesRange( map2 ) then + Error( " and must have same preimage" ); + fi; + + mapi2:=MappingGeneratorsImages(map2); + + if IsLinearGeneralMappingByImagesDefaultRep( map1 ) + and MappingGeneratorsImages(map1)[1]= mapi2[1] then + + # If the generators in both general mappings are the same, + # it suffices to add the images. + gens := mapi2[1]; + genimages := MappingGeneratorsImages(map1)[2] + mapi2[2]; + + else + + # Compute images of the generators of `map1' under `map2'. + # (Note that both general mappings must be described in terms of + # `generators' in order to keep the meaning of `corelations'.) + gens:= mapi2[1]; + genimages:= List( mapi2[1], + v -> ImagesRepresentative( map1, v ) ) + + mapi2[2]; + + fi; + + # Construct the linear general mapping. + sum:= LeftModuleGeneralMappingByImages( + Source( map1 ), Range( map1 ), gens, genimages ); + + # Maintain images info (only if `gens' is not a basis). + if IsLinearGeneralMappingByImagesDefaultRep( sum ) + and IsLinearGeneralMappingByImagesDefaultRep( map1 ) + and not IsBound( sum!.basispreimage ) + and IsBound( map1!.basispreimage ) + and IsBound( map2!.basispreimage ) + and map1!.basispreimage = map2!.basispreimage then + sum!.basispreimage := map1!.basispreimage; + sum!.corelations := map1!.corelations; + sum!.imagesbasispreimage := + map1!.imagesbasispreimage + map2!.imagesbasispreimage; + fi; + + # Return the sum. + return sum; +end ); + + +############################################################################# +## +#M \+( , ) . . . . . . . . . for two linear mappings by images +## +## The method for (total and single-valued general) mappings takes +## advantage from the fact that `generators' and `basispreimage' components +## need not be distinguished since the `corelations' component is empty. +## +InstallOtherMethod( \+, + "for linear m.b.i. and mapping", + IsIdenticalObj, + [ IsMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsMapping ], + function( map1, map2 ) + local gens, + genimages, + mapi1, + sum; + + # Check that the linear mappings can be added. + if Source( map1 ) <> Source( map2 ) + or Range( map1 ) <> Range( map2 ) then + Error( " and must have same source and range" ); + elif PreImagesRange( map1 ) <> PreImagesRange( map2 ) then + Error( " and must have same preimage" ); + fi; + + if IsBound( map1!.basispreimage ) then + + # Use the basis in the construction. + gens:= map1!.basispreimage; + + if IsLinearGeneralMappingByImagesDefaultRep( map2 ) + and IsBound( map2!.basispreimage ) + and map1!.basispreimage = map2!.basispreimage then + + genimages := map1!.imagesbasispreimage + map2!.imagesbasispreimage; + + else + + genimages:= map1!.imagesbasispreimage + + List( gens, + v -> ImagesRepresentative( map2, v ) ); + + fi; + + else + + mapi1:=MappingGeneratorsImages(map1); + + if IsLinearGeneralMappingByImagesDefaultRep( map2 ) + and mapi1[1] = MappingGeneratorsImages(map2)[1] then + + # If the generators in both general mappings are the same, + # it suffices to add the images. + gens := mapi1[1]; + genimages := mapi1[2] + MappingGeneratorsImages(map2)[2]; + + else + + # Compute images of the generators of `map1' under `map2'. + # (Note that both general mappings must be described in terms of + # `generators' in order to keep the meaning of `corelations'.) + gens:= mapi1[1]; + genimages:= mapi1[2] + + List( mapi1[1], + v -> ImagesRepresentative( map2, v ) ); + + fi; + fi; + + # Construct the linear mapping. + sum:= LeftModuleHomomorphismByImagesNC( + Source( map1 ), Range( map1 ), gens, genimages ); + + # Return the sum. + return sum; + end ); + +InstallOtherMethod( \+, + "for mapping and linear m.b.i.", + IsIdenticalObj, + [ IsMapping, + IsMapping and IsLinearGeneralMappingByImagesDefaultRep ], + function( map1, map2 ) + local gens, + genimages, + mapi2, + sum; + + # Check that the linear mappings can be added. + if Source( map1 ) <> Source( map2 ) + or Range( map1 ) <> Range( map2 ) then + Error( " and must have same source and range" ); + elif PreImagesRange( map1 ) <> PreImagesRange( map2 ) then + Error( " and must have same preimage" ); + fi; + + if IsBound( map2!.basispreimage ) then + + # Use the basis in the construction. + gens:= map2!.basispreimage; + + if IsLinearGeneralMappingByImagesDefaultRep( map1 ) + and IsBound( map1!.basispreimage ) + and map1!.basispreimage = map2!.basispreimage then + + genimages := map1!.imagesbasispreimage + map2!.imagesbasispreimage; + + else + + genimages:= List( gens, v -> ImagesRepresentative( map1, v ) ) + + map2!.imagesbasispreimage; + + fi; + + else + + mapi2:=MappingGeneratorsImages(map2); + + if IsLinearGeneralMappingByImagesDefaultRep( map1 ) + and MappingGeneratorsImages(map1)[1] = mapi2[1] then + + # If the generators in both general mappings are the same, + # it suffices to add the images. + gens := mapi2[1]; + genimages := MappingGeneratorsImages(map1)[2] + mapi2[2]; + + else + + # Compute images of the generators of `map2' under `map1'. + # (Note that both general mappings must be described in terms of + # `generators' in order to keep the meaning of `corelations'.) + gens:= mapi2[1]; + genimages:= List( mapi2[1], + v -> ImagesRepresentative( map1, v ) ) + + mapi2[2]; + + fi; + + fi; + + # Construct the linear mapping. + sum:= LeftModuleHomomorphismByImagesNC( + Source( map1 ), Range( map1 ), gens, genimages ); + + # Return the sum. + return sum; + end ); + + +############################################################################# +## +## 2. methods for linear mappings given by matrices +## + + +############################################################################# +## +#R IsLinearMappingByMatrixDefaultRep +## +## is another default representation of $F$-linear mappings between +## two free left modules $V$ and $W$ where $F$ is equal to the left acting +## domain of $V$ and of $W$. +## +## Defining components are +## +## `basissource' \: \\ +## basis of $V$, +## +## `basisrange' \: \\ +## basis of $W$, +## +## `matrix' \: \\ +## matrix over $F$, of dimensions $\dim(V)$ times $\dim(W)$. +## +## The mapping is defined as follows. +## The image of a vector in $V$ has coefficients +## `Coefficients( !.basissource ) * !.matrix' +## w.r.t. `!.basisrange'. +## +## If one wants to compute preimages, one needs the components +## `basisimage' \: \\ +## basis of the image of , +## +## `preimagesbasisimage' \: \\ +## preimages of the basis vectors of `basisimage', +## +## `relations' \: \\ +## linearly independent generators for the relation space, +## i.e., of the left null space of `!.matrix'. +## (The corresponding linear combinations of `basissource' +## generate the kernel.) +## +## If these components are not yet bound, they are computed by +## `MakePreImagesInfoLinearMappingByMatrix'. +## +## Computed images and preimages of free left modules under linear mappings +## are always free left modules. +## If one needs more structure (e.g., that of an algebra) for an image or +## preimage then the linear mapping must have a special representation. +## +## Note that the inverse general mapping of a linear mapping defined by +## a matrix is best handled if it uses the default method, +## since such an inverse general mapping delegates the tasks of computing +## (pre)images to the original general mapping. +## So the (pre)images info is computed only once. +#T but what about sums of such mappings? +#T better try to share info also in this case? +#T (share a list that is filled with the info later?) +## +DeclareRepresentation( + "IsLinearMappingByMatrixDefaultRep", + IsAttributeStoringRep, + [ "basissource", "basisrange", "matrix", + "basisimage", "preimagesbasisimage", "relations" ] ); + +InstallTrueMethod( IsAdditiveElementWithInverse, + IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ); +InstallTrueMethod( IsLeftModuleGeneralMapping, + IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ); + + +############################################################################# +## +#M LeftModuleHomomorphismByMatrix( , ,
) +## +## is the total and single-valued linear general mapping with a basis +## of the source and
a basis of the range, and the rows of the matrix +## being the coefficients vectors of the images of w.r.t. +##
. +## +InstallMethod( LeftModuleHomomorphismByMatrix, + "for two bases of free left modules and a matrix", + [ IsBasis, IsMatrix, IsBasis ], + function( BS, matrix, BR ) + local S, R, map; + + S:= UnderlyingLeftModule( BS ); + R:= UnderlyingLeftModule( BR ); + + # Check the arguments. + if Length( BS ) <> Length( matrix ) then + Error( " and must have the same length" ); + elif Length( BR ) <> Length( matrix[1] ) then + Error( "
and [1] must have the same length" ); + elif LeftActingDomain( S ) <> LeftActingDomain( R ) then + Error( " and must have same left acting domain" ); + fi; +#T check entries of the matrix? + + # Make the mapping. + map:= Objectify( TypeOfDefaultGeneralMapping( S, R, + IsSPGeneralMapping + and IsSingleValued + and IsTotal + and IsLeftModuleGeneralMapping + and IsLinearMappingByMatrixDefaultRep ), + rec( + basissource := BS, + matrix := Immutable( matrix ), + basisrange := BR + ) ); + + # return the mapping + return map; + end ); + + +############################################################################# +## +#F MakePreImagesInfoLinearMappingByMatrix( ) +## +## Provide the information for computing preimages, that is, set up +## the components `basisimage', `preimagesbasisimage', `relations'. +## +BindGlobal( "MakePreImagesInfoLinearMappingByMatrix", function( map ) + local ech, + B; + + ech:= SemiEchelonMatTransformation( map!.matrix ); + B:= Basis( Range( map ) ); + map!.basisimage := BasisNC( ImagesSource( map ), + List( ech.vectors, + x -> LinearCombination( B, x ) ) ); + map!.relations := Immutable( ech.relations ); + + map!.preimagesbasisimage := Immutable( List( ech.coeffs, + row -> LinearCombination( + map!.basissource, row ) ) ); +end ); + + +############################################################################# +## +#M KernelOfAdditiveGeneralMapping( ) . . . . . for left module m.b.m. +## +InstallMethod( KernelOfAdditiveGeneralMapping, + "for left module m.b.m.", + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ], + function( map ) + local generators, S; + + # Form the linear combinations of the basis vectors for the + # relation space with the `basissource' of `map'. + + if not IsBound( map!.relations ) then + MakePreImagesInfoLinearMappingByMatrix( map ); + fi; + generators:= BasisVectors( map!.basissource ); + S:= Source( map ); + return LeftModuleByGenerators( LeftActingDomain( S ), + List( map!.relations, + r -> LinearCombination( generators, r ) ), + Zero( S ) ); + end ); + + +############################################################################# +## +#M IsInjective( ) . . . . . . . . . . . . . . for left module m.b.m. +## +InstallMethod( IsInjective, + "for left module m.b.m.", + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ], + function( map ) + local generators; + + if not IsBound( map!.relations ) then + MakePreImagesInfoLinearMappingByMatrix( map ); + fi; + generators:= BasisVectors( map!.basissource ); + return ForAll( map!.relations, + r -> IsZero( LinearCombination( generators, r ) ) ); + end ); + + +############################################################################# +## +#M ImagesRepresentative( , ) . . . . . . for left module m.b.m. +## +InstallMethod( ImagesRepresentative, + "for left module m.b.m., and element", + FamSourceEqFamElm, + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep, + IsObject ], + function( map, elm ) + elm:= Coefficients( map!.basissource, elm ); + if elm <> fail then + elm:= LinearCombination( map!.basisrange, elm * map!.matrix ); + fi; + return elm; + end ); + + +############################################################################# +## +#M PreImagesRepresentativeNC( , ) . . . . for left module m.b.m. +## +InstallMethod( PreImagesRepresentativeNC, + "for left module m.b.m., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep, + IsObject ], + function( map, elm ) + if not IsBound( map!.basisimage ) then + MakePreImagesInfoLinearMappingByMatrix( map ); + fi; + elm:= Coefficients( map!.basisimage, elm ); + if elm = fail then + return fail; + fi; + return LinearCombination( map!.preimagesbasisimage, elm ); + end ); + +InstallMethod( PreImagesRepresentative, + "for left module m.b.m., and element", + FamRangeEqFamElm, + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep, + IsObject ], + function( map, elm ) + if not ( elm in Image( map ) ) then + return fail; + fi; + return PreImagesRepresentativeNC( map, elm ); + end ); + + +############################################################################# +## +#M ViewObj( ) . . . . . . . . . . . . . . . . for left module m.b.m. +## +InstallMethod( ViewObj, + "for a left module m.b.m.", + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ], + function( map ) + Print( " " ); + View( UnderlyingLeftModule( map!.basisrange ) ); + Print( ">" ); + end ); + + +############################################################################# +## +#M PrintObj( ) . . . . . . . . . . . . . . . . for left module m.b.m. +## +InstallMethod( PrintObj, + "for a left module m.b.m.", + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ], + function( map ) + Print( "LeftModuleHomomorphismByMatrix( ", + map!.basissource, ", ", map!.matrix, ", ", + map!.basisrange, " )" ); + end ); + + +############################################################################# +## +#M NaturalHomomorphismBySubspace( , ) . . . for free left modules +## +## Return the identity mapping. +## +InstallMethod( NaturalHomomorphismBySubspace, + "for left module and trivial left module", + IsIdenticalObj, + [ IsFreeLeftModule, IsFreeLeftModule and IsTrivial ], + SUM_FLAGS, # better than everything else + function( V, W ) + return IdentityMapping( V ); + end ); + + +############################################################################# +## +#F NaturalHomomorphismBySubspaceOntoFullRowSpace( , ) +## +InstallGlobalFunction( NaturalHomomorphismBySubspaceOntoFullRowSpace, + function( V, W ) + local F, + Wvectors, + mb, + compl, + gen, + B, + img, + canbas, + zero, + Bimgs, + nathom; + + # Check that the modules are finite dimensional. + if not IsFiniteDimensional( V ) or not IsFiniteDimensional( W ) then + TryNextMethod(); + elif not IsSubset( V, W ) then + Error( " must be contained in " ); + fi; + + # If the left acting domains are different, adjust them. + F:= LeftActingDomain( V ); + if F <> LeftActingDomain( W ) then + F:= Intersection2( F, LeftActingDomain( W ) ); + V:= AsLeftModule( F, V ); + W:= AsLeftModule( F, W ); + fi; + + # If `V' is equal to `W', return a zero mapping. + if Dimension( V ) = Dimension( W ) then + return ZeroMapping( V, FullRowModule( F, 0 ) ); + fi; + + # Compute a basis of `V' through a basis of `W'. + Wvectors:= BasisVectors( Basis( W ) ); + if IsEmpty( Wvectors ) then + mb:= MutableBasis( F, Wvectors, Zero( W ) ); + else + mb:= MutableBasis( F, Wvectors ); + fi; + compl:= []; + for gen in BasisVectors( Basis( V ) ) do + if CloseMutableBasis( mb, gen ) then + Add( compl, gen ); + fi; + od; + B:= BasisNC( V, Concatenation( Wvectors, compl ) ); + + # Compute the linear mapping by images. + img:= FullRowModule( F, Length( compl ) ); + canbas:= CanonicalBasis( img ); + zero:= Zero( img ); + Bimgs:= Concatenation( List( Wvectors, v -> zero ), + BasisVectors( canbas ) ); + nathom:= LeftModuleHomomorphismByMatrix( B, Bimgs, canbas ); +#T take a special representation for nat. hom.s, +#T (just compute coefficients, and then choose a subset ...) + SetIsSurjective( nathom, true ); + + # Enter the preimages info. + nathom!.basisimage:= canbas; + nathom!.preimagesbasisimage:= Immutable( compl ); +#T relations are not needed if the kernel is known ? + + SetKernelOfAdditiveGeneralMapping( nathom, W ); + + # Run the implications for the factor. + UseFactorRelation( V, W, img ); + + return nathom; + end ); + + +############################################################################# +## +#M NaturalHomomorphismBySubspace( , ) . . . for two free left modules +## +## return a left module m.b.m. +## +InstallMethod( NaturalHomomorphismBySubspace, + "for two finite dimensional free left modules", + IsIdenticalObj, + [ IsFreeLeftModule, IsFreeLeftModule ], + NaturalHomomorphismBySubspaceOntoFullRowSpace ); + + +############################################################################# +## +#M \*( , ) . . . . . . . . . . . . . for scalar and linear m.b.m. +## +InstallMethod( \*, + "for scalar and linear m.b.m.", + [ IsMultiplicativeElement, + IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ], + function( scalar, map ) + local mult, # the multiple of `map', result + F; # left acting domain + + # Check the scalar. + # (Maybe it is in fact another mapping, and we want to compose.) + if not IsInt( scalar ) + and not IsElmsColls( FamilyObj( scalar ), + FamilyObj( LeftActingDomain( Range( map ) ) ) ) then + TryNextMethod(); + fi; + + # Construct the linear mapping (if possible). + mult:= LeftModuleHomomorphismByMatrix( + map!.basissource, + scalar * map!.matrix, + map!.basisrange ); + + # If the scalar is invertible in the left acting domain of the source + # then surjectivity and injectivity are maintained as well as the image. + F:= LeftActingDomain( Source( map ) ); + if scalar in F and IsUnit( F, scalar ) then + + if HasIsInjective( map ) then + SetIsInjective( mult, IsInjective( map ) ); + fi; + if HasIsSurjective( map ) then + SetIsSurjective( mult, IsSurjective( map ) ); + fi; + + if IsBound( map!.basisimage ) then + scalar:= Inverse( scalar ); + mult!.basisimage := map!.basisimage; + mult!.preimagesbasisimage := Immutable( + List( map!.preimagesbasisimage, v -> scalar * v ) ); + mult!.relations := map!.relations; + fi; + + fi; + + return mult; + end ); + + +############################################################################# +## +#M AdditiveInverseOp( ) . . . . . . . . . . . . . . for linear m.b.m. +## +InstallMethod( AdditiveInverseOp, + "for linear m.b.m.", + [ IsGeneralMapping and IsLinearMappingByMatrixDefaultRep ], + function( map ) + local ainv; # the additive inverse of `map', result + + # Construct the linear general mapping (if possible). + ainv:= LeftModuleHomomorphismByMatrix( + map!.basissource, + AdditiveInverse( map!.matrix ), + map!.basisrange ); + + # Maintain preimages info. + if IsBound( map!.basisimage ) then + ainv!.basisimage := map!.basisimage; + ainv!.preimagesbasisimage := Immutable( + List( map!.preimagesbasisimage, AdditiveInverse ) ); + ainv!.relations := map!.relations; + fi; + + # Surjectivity and injectivity are maintained. + if HasIsInjective( map ) then + SetIsInjective( ainv, IsInjective( map ) ); + fi; + if HasIsSurjective( map ) then + SetIsSurjective( ainv, IsSurjective( map ) ); + fi; + + return ainv; + end ); + + +############################################################################# +## +#M CompositionMapping2( , map1> ) . for left mod. hom. & lin. m.b.m. +## +InstallMethod( CompositionMapping2, + "for left module hom. and linear m.b.m.", + FamSource1EqFamRange2, + [ IsLeftModuleHomomorphism, + IsLeftModuleHomomorphism and IsLinearMappingByMatrixDefaultRep ], + function( map2, map1 ) + local comp, # composition of and , result + BR, # basis of the range of `map2' + mat2; # matrix corresponding to `map2' + + # Compute images for the generators of `map1'. + if IsLinearMappingByMatrixDefaultRep( map2 ) + and map1!.basisrange = map2!.basissource then + + BR := map2!.basisrange; + mat2 := map2!.matrix; + + else + + BR:= Range( map2 ); + if not IsFiniteDimensional( BR ) then + TryNextMethod(); + fi; + BR:= Basis( BR ); + mat2:= List( BasisVectors( map1!.basisrange ), + v -> Coefficients( BR, ImagesRepresentative( map2, v ) ) ); + + fi; + + # Construct the linear mapping. + comp:= LeftModuleHomomorphismByMatrix( map1!.basissource, + map1!.matrix * mat2, BR ); + + # Return the composition. + return comp; + end ); + + +############################################################################# +## +#M \+( , map2> ) . . . . . . . . . . . . . . . . for two linear m.b.m. +## +## Two general mappings that respect addition can be added pointwise +## if their images are equal and their preimages are equal. +## The sum does also respect addition. +## +## If both general mappings respect zero, additive inverses, scalar +## multiplication then the sum also does. +## +BindGlobal( "SumOfMBMAndMapping", function( map1, map2 ) + local sum; + + # Check that the linear mappings can be added. + if Source( map1 ) <> Source( map2 ) + or Range( map1 ) <> Range( map2 ) then + Error( " and must have same source and range" ); + fi; + + if IsLinearMappingByMatrixDefaultRep( map2 ) + and map1!.basissource = map2!.basissource + and map1!.basisrange = map2!.basisrange then + + # If the bases in both mappings are the same, + # it suffices to add the matrices. + sum:= LeftModuleHomomorphismByMatrix( + map1!.basissource, + map1!.matrix + map2!.matrix, + map1!.basisrange ); + + else + + # Compute images of the generators of `map1' under `map2'. + sum:= LeftModuleHomomorphismByMatrix( + map1!.basissource, + map1!.matrix + + List( BasisVectors( map1!.basissource ), + v -> Coefficients( map1!.basisrange, + ImagesRepresentative( map2, v ) ) ), + map1!.basisrange ); + + fi; + + # Return the sum. + return sum; +end ); + +BindGlobal( "SumOfMappingAndMBM", function( map1, map2 ) + local sum; + + # Check that the linear mappings can be added. + if Source( map1 ) <> Source( map2 ) + or Range( map1 ) <> Range( map2 ) then + Error( " and must have same source and range" ); + fi; + + if IsLinearMappingByMatrixDefaultRep( map1 ) + and map1!.basissource = map2!.basissource + and map1!.basisrange = map2!.basisrange then + + # If the bases in both mappings are the same, + # it suffices to add the matrices. + sum:= LeftModuleHomomorphismByMatrix( + map1!.basissource, + map1!.matrix + map2!.matrix, + map1!.basisrange ); + + else + + # Compute images of the generators of `map2' under `map1'. + sum:= LeftModuleHomomorphismByMatrix( + map2!.basissource, + List( BasisVectors( map2!.basissource ), + v -> Coefficients( map2!.basisrange, + ImagesRepresentative( map1, v ) ) ) + + map2!.matrix, + map2!.basisrange ); + + fi; + + # Return the sum. + return sum; +end ); + +InstallOtherMethod( \+, + "for linear m.b.m. and mapping", + IsIdenticalObj, + [ IsMapping and IsLinearMappingByMatrixDefaultRep, + IsMapping ], + SumOfMBMAndMapping ); + +InstallOtherMethod( \+, + "for mapping and linear m.b.m.", + IsIdenticalObj, + [ IsMapping, + IsMapping and IsLinearMappingByMatrixDefaultRep ], + SumOfMappingAndMBM ); + + +############################################################################# +## +#M \+( , ) . . . . for mapping by matrix and mapping by images +## +InstallMethod( \+, + "for linear m.b.m. and linear m.b.i.", + IsIdenticalObj, + [ IsMapping and IsLinearMappingByMatrixDefaultRep, + IsMapping and IsLinearGeneralMappingByImagesDefaultRep ], + SumOfMBMAndMapping ); + +InstallMethod( \+, + "for linear m.b.i. and linear m.b.m.", + IsIdenticalObj, + [ IsMapping and IsLinearGeneralMappingByImagesDefaultRep, + IsMapping and IsLinearMappingByMatrixDefaultRep ], + SumOfMappingAndMBM ); + + +############################################################################# +## +## 3. methods for vector spaces of linear mappings +## + + +############################################################################# +## +#M NiceFreeLeftModuleInfo( ) . . . . . . for a space of linear mappings +#M NiceVector( , ) . . for space of lin. mappings, and lin. mapping +#M UglyVector( , ) . . . for space of linear mappings, and matrix +## +InstallHandlingByNiceBasis( "IsLinearMappingsModule", rec( + detect := function( F, gens, V, zero ) + local S, R; + if not IsGeneralMappingCollection( V ) then + return false; + fi; + gens:= AsList( gens ); + if IsEmpty( gens ) then + S:= Source( zero ); + R:= Range( zero ); + else + S:= Source( gens[1] ); + R:= Range( gens[1] ); + fi; + + # Check that the mappings have left modules as source and range. + if not IsLeftModule( S ) + or not IsLeftModule( R ) + or not ForAll( gens, IsMapping ) then + return false; + fi; + + # Check that all generators have the same source and range, + # and that source and range are in fact left modules. + if ForAny( gens, map -> Source( map ) <> S ) + or ForAny( gens, map -> Range( map ) <> R ) then + return false; + fi; + return true; + end, + + NiceFreeLeftModuleInfo := function( V ) + local F, z, S, R; + F:= LeftActingDomain( V ); + z:= Zero( V ); + S:= Source( z ); + R:= Range( z ); + + # Write `S' and `R' over `F' (necessary for the nice left module). + if LeftActingDomain( S ) <> F then + S:= AsLeftModule( F, S ); + R:= AsLeftModule( F, R ); + fi; + + return rec( basissource := Basis( S ), + basisrange := Basis( R ) ); + end, + + NiceVector := function( V, v ) + local info, M, i, c; + info:= NiceFreeLeftModuleInfo( V ); + if IsLinearMappingByMatrixDefaultRep( v ) + and info.basissource = v!.basissource + and info.basisrange = v!.basisrange then + M:= v!.matrix; + else + M:= []; + for i in BasisVectors( info.basissource ) do + c:= Coefficients( info.basisrange, ImagesRepresentative( v, i ) ); + if c = fail then + return fail; + fi; + Add( M, c ); + od; + fi; + return M; + end, + + UglyVector := function( V, mat ) + local info; + info:= NiceFreeLeftModuleInfo( V ); + return LeftModuleHomomorphismByMatrix( info.basissource, + mat, info.basisrange ); + end ) ); + + +############################################################################# +## +## 4. methods for algebras of linear mappings +## + + +############################################################################# +## +#M RingByGenerators( ) . . ring generated by a list of lin. mappings +## +## If is a list of linear mappings of finite vector spaces then +## we construct a hom algebra over the prime field. +## +InstallOtherMethod( RingByGenerators, + "for a list of linear mappings of finite vector spaces", + [ IsGeneralMappingCollection ], + function( maps ) + local S; + + maps:= AsList( maps ); + if IsEmpty( maps ) then + Error( "need at least one element" ); + fi; + if not ForAll( maps, IsLeftModuleHomomorphism ) then + TryNextMethod(); + fi; + S:= Source( maps[1] ); + if IsVectorSpace( S ) + and IsFFECollection( LeftActingDomain( S ) ) then + return FLMLORByGenerators( GF( Characteristic( S ) ), maps ); + elif IsVectorSpace( S ) + and IsCyclotomicCollection( LeftActingDomain( S ) ) then + return FLMLORByGenerators( Integers, maps ); + else + TryNextMethod(); + fi; + end ); + + +############################################################################# +## +#M DefaultRingByGenerators( ) . . ring cont. a list of lin. mappings +## +## If is a list of mappings of vector spaces then +## we construct an algebra over the prime field. +## (So this may differ from the result of `RingByGenerators' if the +## characteristic is zero.) +## +InstallOtherMethod( DefaultRingByGenerators, + "for a list of linear mappings of vector spaces", + [ IsGeneralMappingCollection ], + function( maps ) + local S; + maps:= AsList( maps ); + if IsEmpty( maps ) then + Error( "need at least one element" ); + fi; + if not ForAll( maps, IsLeftModuleHomomorphism ) then + TryNextMethod(); + fi; + S:= Source( maps[1] ); + if IsVectorSpace( S ) + and IsFFECollection( LeftActingDomain( S ) ) then + return FLMLORByGenerators( GF( Characteristic( S ) ), maps ); + elif IsVectorSpace( S ) + and IsCyclotomicCollection( LeftActingDomain( S ) ) then + return FLMLORByGenerators( Rationals, maps ); + else + TryNextMethod(); + fi; + end ); + + +############################################################################# +## +#M RingWithOneByGenerators( ) . . . . . for a list of linear mappings +## +## If is a list of linear mappings of a finite vector space then +## we construct a hom algebra-with-one over the prime field. +## +InstallOtherMethod( RingWithOneByGenerators, + "for a list of linear mappings of finite vector spaces", + [ IsGeneralMappingCollection ], + function( maps ) + local S; + + maps:= AsList( maps ); + if IsEmpty( maps ) then + Error( "need at least one element" ); + fi; + if not ForAll( maps, IsLeftModuleHomomorphism ) then + TryNextMethod(); + fi; + S:= Source( maps[1] ); + if IsVectorSpace( S ) + and IsFFECollection( LeftActingDomain( S ) ) + and S = Range( maps[1] ) then + return FLMLORWithOneByGenerators( GF( Characteristic( S ) ), maps ); + elif IsVectorSpace( S ) + and IsCyclotomicCollection( LeftActingDomain( S ) ) then + return FLMLORWithOneByGenerators( Integers, maps ); + else + TryNextMethod(); + fi; + end ); + + +############################################################################# +## +#M IsGeneratorsOfFLMLOR( , ) +#M IsGeneratorsOfFLMLORWithOne( , ) +## +#T check that sources and ranges coincide: +#T if ForAny( maps, map -> Source( map ) <> S or Range( map ) <> S ) then + +#T add implication that a FLMLOR of mappings is associative! + +#T for ideals construction, inherit the info? +#T SetNiceFreeLeftModuleInfo( I, NiceFreeLeftModuleInfo( A ) ); + + +############################################################################# +## +## 5. methods for full hom spaces +## + + +############################################################################# +## +#M IsFullHomModule( V ) . . . . . . . . . . . for space of linear mappings +## +InstallMethod( IsFullHomModule, + "for space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection ], + V -> Dimension( V ) = Dimension( UnderlyingLeftModule( NiceFreeLeftModuleInfo( V ).basissource ) ) + * Dimension( UnderlyingLeftModule( NiceFreeLeftModuleInfo( V ).basisrange ) ) ); + + +############################################################################# +## +#M Dimension( ) . . . . . . . . . for full hom space of linear mappings +## +InstallMethod( Dimension, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], + V -> Dimension( UnderlyingLeftModule( NiceFreeLeftModuleInfo( V ).basissource ) ) + * Dimension( UnderlyingLeftModule( NiceFreeLeftModuleInfo( V ).basisrange ) ) ); + + +############################################################################# +## +#M Random( ) . . . . . . . . . . . for full hom space of linear mappings +## +InstallMethodWithRandomSource( Random, + "for a random source and full hom space of linear mappings", + [ IsRandomSource, IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], + function( rs, M ) + local BS, BR; + + BR:= NiceFreeLeftModuleInfo( M ); + BS:= BR.basissource; + BR:= BR.basisrange; + + return LeftModuleHomomorphismByMatrix( BS, + RandomMat( rs, + Dimension( UnderlyingLeftModule( BS ) ), + Dimension( UnderlyingLeftModule( BR ) ), + LeftActingDomain( M ) ), + BR ); + end ); + + +############################################################################# +## +#M Representative( ) . . . . . . . for full hom space of linear mappings +## +## This method is necessary for example for computing the `Zero' value of +## . Note that does in general *not* store any generators! +## +InstallMethod( Representative, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], + function( M ) + local BS, BR; + + BR:= NiceFreeLeftModuleInfo( M ); + BS:= BR.basissource; + BR:= BR.basisrange; + + return LeftModuleHomomorphismByMatrix( BS, + NullMat( Dimension( UnderlyingLeftModule( BS ) ), + Dimension( UnderlyingLeftModule( BR ) ), + LeftActingDomain( M ) ), + BR ); + end ); + + +############################################################################# +## +#M GeneratorsOfLeftModule( ) . . . for full hom space of linear mappings +## +BindGlobal( "StandardGeneratorsOfFullHomModule", function( M ) + local BS, BR, R, one, m, n, zeromat, gens, i, j, gen; + + BR:= NiceFreeLeftModuleInfo( M ); + BS:= BR.basissource; + BR:= BR.basisrange; + R:= LeftActingDomain( M ); + one:= One( R ); + m:= Dimension( UnderlyingLeftModule( BS ) ); + n:= Dimension( UnderlyingLeftModule( BR ) ); + zeromat:= NullMat( m, n, R ); + gens:= []; + for i in [ 1 .. m ] do + for j in [ 1 .. n ] do + gen:= List( zeromat, ShallowCopy ); + gen[i][j]:= one; + Add( gens, LeftModuleHomomorphismByMatrix( BS, gen, BR ) ); + od; + od; + + return gens; +end ); + +InstallMethod( GeneratorsOfLeftModule, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], + StandardGeneratorsOfFullHomModule ); + + +############################################################################# +## +#M NiceFreeLeftModule( ) . . . . . for full hom space of linear mappings +## +## We need a special method since we decided not to store vector space +## generators in full hom spaces; +## note that the default methods for `NiceFreeLeftModule' are installed with +## requirement `HasGeneratorsOfLeftModule'. +## +InstallMethod( NiceFreeLeftModule, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], + function( M ) + if HasGeneratorsOfLeftModule( M ) then + TryNextMethod(); + fi; + GeneratorsOfLeftModule( M ); + if not HasGeneratorsOfLeftModule( M ) then + TryNextMethod(); + fi; + return NiceFreeLeftModule( M ); + end ); + + +############################################################################# +## +#M ViewObj( ) . . . . . . . . . . for full hom space of linear mappings +#M PrintObj( ) . . . . . . . . . . for full hom space of linear mappings +## +BindGlobal( "ViewFullHomModule", function( M ) + local info; + + info:= NiceFreeLeftModuleInfo( M ); + if IsIdenticalObj( info.basissource, info.basisrange ) then + Print( "End( " ); + View( LeftActingDomain( M ) ); + Print( ", " ); + View( UnderlyingLeftModule( info.basissource ) ); + Print( " )" ); + else + Print( "Hom( " ); + View( LeftActingDomain( M ) ); + Print( ", " ); + View( UnderlyingLeftModule( info.basissource ) ); + Print( ", " ); + View( UnderlyingLeftModule( info.basisrange ) ); + Print( " )" ); + fi; +end ); + +InstallMethod( ViewObj, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], SUM_FLAGS, + ViewFullHomModule ); + +InstallMethod( PrintObj, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], SUM_FLAGS, + ViewFullHomModule ); + + +############################################################################# +## +#M \in( , ) . . . . . . . . . . for full hom space of linear mappings +## +InstallMethod( \in, + "for full hom space of linear mappings", + IsElmsColls, + [ IsGeneralMapping, + IsFreeLeftModule and IsGeneralMappingCollection + and IsFullHomModule ], + function( map, M ) + local info; + info:= NiceFreeLeftModuleInfo( M ); + return Source( map ) = UnderlyingLeftModule( info.basissource ) + and Range( map ) = UnderlyingLeftModule( info.basisrange ) + and IsLeftModuleHomomorphism( map ); + end ); + + +############################################################################# +## +#M IsPseudoCanonicalBasisFullHomModule( ) . . . . for a full hom module +## +InstallMethod( IsPseudoCanonicalBasisFullHomModule, + "for a basis of a full hom module", + [ IsBasis ], + function( B ) + local V; + + V:= UnderlyingLeftModule( B ); + if IsGeneralMappingCollection( V ) then + if not IsFullHomModule( V ) then + return false; + fi; + return BasisVectors( B ) = StandardGeneratorsOfFullHomModule( V ); + else + Error( "do not know what a pseudo canon. basis for is" ); + fi; + end ); + + +############################################################################# +## +#M BasisVectors( ) . . . for pseudo canonical basis of a full hom module +## +InstallMethod( BasisVectors, + "for pseudo canonical basis of a full hom module", + [ IsBasis and IsPseudoCanonicalBasisFullHomModule ], + B -> StandardGeneratorsOfFullHomModule( UnderlyingLeftModule( B ) ) ); + + +############################################################################# +## +#M Coefficients( , ) for a pseudo canon. basis of a full hom module +## +InstallOtherMethod( Coefficients, + "for pseudo canon. basis of a full hom module, and lin. mapping", + IsCollsElms, + [ IsBasis and IsPseudoCanonicalBasisFullHomModule, IsGeneralMapping ], + function( B, map ) + local V, info; + V:= UnderlyingLeftModule( B ); + if not IsGeneralMappingCollection( V ) then + TryNextMethod(); + fi; + info:= NiceFreeLeftModuleInfo( V ); + if Source( map ) = UnderlyingLeftModule( info.basissource ) + and Range( map ) = UnderlyingLeftModule( info.basisrange ) + and IsLeftModuleHomomorphism( map ) then + return Concatenation( + List( BasisVectors( info.basissource ), + v -> Coefficients( info.basisrange, + ImagesRepresentative( map, v ) ) ) ); + else + return fail; + fi; + end ); + +InstallMethod( Coefficients, + "for pseudo can. basis of full hom module, and lin. m.b.m.", + IsCollsElms, + [ IsBasis and IsPseudoCanonicalBasisFullHomModule, + IsMapping and IsLinearMappingByMatrixDefaultRep ], + function( B, map ) + local V, info; + V:= UnderlyingLeftModule( B ); + if not IsGeneralMappingCollection( V ) then + TryNextMethod(); + fi; + info:= NiceFreeLeftModuleInfo( V ); + if map!.basissource = info.basissource + and map!.basisrange = info.basisrange then + return Concatenation( map!.matrix ); + elif Source( map ) = UnderlyingLeftModule( info.basissource ) + and Range( map ) = UnderlyingLeftModule( info.basisrange ) then + return Concatenation( + List( BasisVectors( info.basissource ), + v -> Coefficients( info.basisrange, + ImagesRepresentative( map, v ) ) ) ); + else + return fail; + fi; + end ); + + +############################################################################# +## +#M Basis( ) . . . . . . . . . . . . . . . . . . . . for full hom module +## +InstallMethod( Basis, + "for full hom space of linear mappings", + [ IsFreeLeftModule and IsFullHomModule ], 100, + function( V ) + local B; + B:= Objectify( NewType( FamilyObj( V ), + IsFiniteBasisDefault + and IsPseudoCanonicalBasisFullHomModule + and IsAttributeStoringRep ), + rec() ); + SetUnderlyingLeftModule( B, V ); + if IsFiniteDimensional( V ) then + SetIsFinite( B, true ); + #T Check whether its is a) correct and even if so + #T b) sometimes to expensive + SetBasisVectors( B, GeneratorsOfLeftModule(V) ); + fi; + return B; + end ); + + +############################################################################# +## +#M Hom( , , ) +## +InstallMethod( Hom, + "for division ring and two free left modules", + [ IsDivisionRing, IsFreeLeftModule, IsFreeLeftModule ], + function( F, V, W ) + local M; # the free module record, result + + if V = W then + return End( F, V ); + fi; + if LeftActingDomain( V ) <> F then + V:= AsLeftModule( F, V ); + fi; + if LeftActingDomain( W ) <> F then + W:= AsLeftModule( F, W ); + fi; + + M:= Objectify( NewType( CollectionsFamily( GeneralMappingsFamily( + ElementsFamily( FamilyObj( V ) ), + ElementsFamily( FamilyObj( W ) ) ) ), + IsFreeLeftModule + and IsFullHomModule + and IsLinearMappingsModule + and IsGeneralMappingCollection + and IsAttributeStoringRep ), + rec() ); + + SetLeftActingDomain( M, F ); + SetNiceFreeLeftModuleInfo( M, rec( + basissource := Basis( V ), + basisrange := Basis( W ) ) ); + + return M; + end ); + + +############################################################################# +## +#M End( , ) . . . . . . . . . for division ring and free left module +## +## We use the generators that are also taken for full matrix FLMLORs. +## +InstallMethod( End, + "for division ring and space of linear mappings", + [ IsDivisionRing, IsFreeLeftModule ], + function( F, V ) + local n, # dimension of `V' + i, # loop over the rows + gens, # list of generators + one, # the identity of the field + B, # basis of `V' + A; # algebra, result + + if LeftActingDomain( V ) <> F then + V:= AsLeftModule( F, V ); + fi; + + n:= Dimension( V ); + gens:= NullMat( n, n, F ); + gens:= [ gens, List( gens, ShallowCopy ) ]; + one:= One( F ); + + # Construct the generators. + gens[1][1][1]:= one; + gens[2][1][n]:= one; + for i in [ 2 .. n ] do + gens[2][i][i-1]:= one; + od; + B:= Basis( V ); + gens:= List( gens, mat -> LeftModuleHomomorphismByMatrix( B, mat, B ) ); + + # Construct the FLMLOR. + A:= AlgebraWithOneByGenerators( F, gens ); + SetIsFullHomModule( A, true ); + SetNiceFreeLeftModuleInfo( A, rec( + basissource := B, + basisrange := B ) ); + + # Return the FLMLOR. + return A; + end ); + + +#T InstallMethod( Field, true, [ IsGeneralMappingCollection ], 0, ... ); +#T InstallMethod( DefaultField, true, [ IsGeneralMappingCollection ], 0, ... );