diff --git a/PackageInfo.g b/PackageInfo.g index b15f5354..433071b5 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -9,7 +9,7 @@ SetPackageInfo( rec( PackageName := "HAP", Subtitle := "Homological Algebra Programming", Version := "1.61", - Date := "12/12/2023", + Date := "02/0q/2024", License := "GPL-2.0-or-later", SourceRepository := rec( diff --git a/date b/date index ac422ea3..b1b02fe2 100644 --- a/date +++ b/date @@ -1 +1 @@ -12 Dec 2023 +02 Jan 2024 diff --git a/doc/Test.xml b/doc/Test.xml index 90d16388..279a3b9a 100644 --- a/doc/Test.xml +++ b/doc/Test.xml @@ -1103,6 +1103,7 @@ HAP_PERMMOVES_DIM_2
HAP_PERMMOVES_DIM_3
HAP_XYXYXYXY
+HAP_type
HAPchildFunctionToggle
HAPchildToggle
HAPchildren
diff --git a/doc/Undocumented.xml b/doc/Undocumented.xml index ed6c0ede..2d2ddff5 100644 --- a/doc/Undocumented.xml +++ b/doc/Undocumented.xml @@ -1,5 +1,5 @@ HAP variables that are not yet documented -
 
2CoreducedChainComplex    Examples:
+
 2CoreducedChainComplex    Examples:

AbelianGOuterGroupToCatOneGroup    Examples:

@@ -1398,6 +1398,9 @@ ../www/SideLinks/About/aboutKnotsQuandles.html10 

+Category_Of_Groups    Examples: ../www/SideLinks/About/aboutAbelianCategories.html1  +
+
ElementsSL2Z    Examples:

HAP_knot_census    Examples:
@@ -5840,9 +5843,6 @@
CATONEGROUP_DATA_SIZE    Examples:

-Category_Of_Groups    Examples: ../www/SideLinks/About/aboutAbelianCategories.html1  -
-
Cedric_PlanarDiagram    Examples:

ChildKill    Examples:
diff --git a/lib/CatGroups/identities.gi b/lib/CatGroups/identities.gi index 98e532a7..ef316c5d 100644 --- a/lib/CatGroups/identities.gi +++ b/lib/CatGroups/identities.gi @@ -9,7 +9,7 @@ local Boundary, Elts, Mult, Inv, Frels, rels, - Fgens,gens, + Fgens,gens,gens2, FirstBoundaryHomomorphism, Boundary2Relator, start, @@ -20,7 +20,7 @@ local COLOURS, tmpDir,tmpInlog,tmpIn2log,tmpIngif, AppendTo, PrintTo, - b, r, x,i,X; + b, r, x,i,X,pos; AppendTo:=HAP_AppendTo; PrintTo:=HAP_PrintTo; @@ -54,8 +54,8 @@ Dimension:=R!.dimension; Boundary:=R!.boundary; Elts:=R!.elts; Frels:=[]; -start:=List([1..Dimension(2)],x->List(Boundary(2,x),y->y[2])); -start:=SortedList(Intersection(start))[1]; +#start:=List([1..Dimension(2)],x->List(Boundary(2,x),y->y[2])); +#start:=SortedList(Intersection(start))[1]; gens:=[]; @@ -72,7 +72,7 @@ end; Inv:=function(g) local pos; pos:= Position(Elts,Elts[g]^-1); -if pos=fail then Add(Elts[g]^-1); pos:=Length(Elts); fi; +if pos=fail then Add(Elts,Elts[g]^-1); pos:=Length(Elts); fi; return pos; end; ##################################################################### @@ -91,8 +91,12 @@ end; Boundary2Relator:=function(b) local c, rel, w; -b:=SortedList(AlgebraicReduction(b)); -rel:=[start]; +rel:=[b[1][2]]; +#b:=SortedList(AlgebraicReduction(b)); +b:=SortedList(b); +#rel:=[start]; + + while Length(b)>0 do for x in b do @@ -116,11 +120,21 @@ Append(Frels,[Boundary2Relator(Boundary(2,r))]); od; for r in Frels do -if (not Inv(r[2]) in gens) then AddSet(gens,r[2]);fi; -if (not Inv(r[Length(r)-1]) in gens) then AddSet(gens,r[Length(r)-1]);fi; +for i in [1..Length(r)-1] do +Add(gens, Mult( Inv(r[i]), r[i+1])); +od; +Add(gens, Mult( Inv(r[Length(r)]), r[1])); +od; + +gens2:=SSortedList(gens); + +gens:=[]; +for i in gens2 do +if not (i in gens or Inv(i) in gens) then Add(gens,i); fi; +pos:=Position(gens,i);if not pos=fail and Inv(i)Edges[2*i]); +Edges:=SSortedList(Edges); +#Print(Collected(Edges)); +#Edges:=List([1..Length(Edges)/2],i->Edges[2*i]); ################ WRITE TO TMPIN.LOG ################################# -AppendTo(tmpInlog," graph G { \n size=\"4,4\" \n subgraph cluster0 {\n node [shape=ellipse, width=.2,height=.2,fixedsize=true,style=filled, color=gray35,label=\"\"] \n edge [style=\"setlinewidth(2)\"] \n"); +AppendTo(tmpInlog," digraph G { \n size=\"4,4\" \n subgraph cluster0 {\n node [shape=ellipse, width=.2,height=.2,fixedsize=true,style=filled, color=gray35,label=\"\"] \n edge [style=\"setlinewidth(2)\"] \n"); for x in Edges do -AppendTo(tmpInlog,x[1]," -- ", x[2], "[color=",Color(x), "] \n"); +if Mult(Inv(x[1]),x[2]) in gens then +AppendTo(tmpInlog,x[1]," -> ", x[2], "[color=",Color(x), "] \n"); +else +AppendTo(tmpInlog,x[2]," -> ", x[1], "[color=",Color(x), "] \n"); +fi; od; #### @@ -179,7 +198,7 @@ AppendTo(tmpInlog," }\n subgraph cluster1 {\n node [shape=box, width=2,height=1 if Maximum(List(X,x->Length(String(x))))<20 then for i in [1..Length(X)] do -AppendTo(tmpInlog,-i," [fontcolor= ",COLOURS[i],",label=\"", X[i],"\" ] \n"); +#AppendTo(tmpInlog,-i," [fontcolor= ",COLOURS[i],",label=\"", X[i],"\" ] \n"); od; fi; diff --git a/lib/CategoryTheory/categories.gdworking b/lib/CategoryTheory/categories.gdold similarity index 96% rename from lib/CategoryTheory/categories.gdworking rename to lib/CategoryTheory/categories.gdold index 52106261..5ac5fafe 100644 --- a/lib/CategoryTheory/categories.gdworking +++ b/lib/CategoryTheory/categories.gdold @@ -174,10 +174,11 @@ DeclareAttribute( "Mapping" , IsCategoryArrow ); ## DeclareProperty("IsAbelianCategory", IsString); DeclareProperty("IsAdditiveCategory", IsString); -DeclareProperty("HasTerminalObject", IsString); -DeclareProperty("HasInitialObject", IsString); -DeclareProperty("HasPullbacks", IsString); -DeclareProperty("HasPushouts", IsString); +DeclareAttribute("TerminalObject", IsString); +#DeclareProperty("HasTerminalObject", IsString); +DeclareAttribute("InitialObject", IsString); #changed from Propertry +DeclareAttribute("Pullbacks", IsString); #changed from Propertry +DeclareAttribute("Pushouts", IsString); #changed from Propertry ############################################################################# ## diff --git a/lib/CategoryTheory/categories.giworking b/lib/CategoryTheory/categories.giold similarity index 97% rename from lib/CategoryTheory/categories.giworking rename to lib/CategoryTheory/categories.giold index c16b69b2..331c080a 100644 --- a/lib/CategoryTheory/categories.giworking +++ b/lib/CategoryTheory/categories.giold @@ -10,11 +10,13 @@ ## The category of groups. As the implementation improves the properties ## of this category will increase! ## -BindGlobal("Category_Of_Groups", Objectify( - NewType(NewFamily("Category_Of_Groups"), +Category_Of_Groups:="Category_Of_Groups"; +HAP_type:= NewType(NewFamily("Category_Of_Groups"), IsString and HasInitialObject - and HasTerminalObject), [])); + and HasTerminalObject); +ObjectifyWithAttributes(Category_Of_Groups,HAP_type); +MakeReadOnlyGlobal("Category_Of_Groups"); ############################################################################# diff --git a/lib/Kelvin/cw-functions.gi b/lib/Kelvin/cw-functions.gi index c38cbd11..8b22cc31 100755 --- a/lib/Kelvin/cw-functions.gi +++ b/lib/Kelvin/cw-functions.gi @@ -926,16 +926,20 @@ InstallGlobalFunction( ViewArc2Presentation, function(l) local - arc, cross, cols, AppendTo, PrintTo, file, filetxt, - bin_arr, coord, res, colours, i, j, x, k, y, z, clr; + arc, cross, cols, AppendTo, PrintTo, file, filetxt, filepng, + bin_arr, coord, res, colours, i, j, x, k, y, z, clr, tmpdir; arc:=List(l[1],x->[SignInt(x[1])*x[1],SignInt(x[2])*x[2]]); cross:=l[2]*1; cols:=l[3]*1; AppendTo:=HAP_AppendTo; PrintTo:=HAP_PrintTo; - file:="/tmp/HAPtmpImage"; - filetxt:="/tmp/HAPtmpImage.txt"; + #file:="/tmp/HAPtmpImage"; + #filetxt:="/tmp/HAPtmpImage.txt"; +tmpdir := DirectoryTemporary();; +file:=Filename( tmpdir , "HAPtmpImage" ); +filetxt:=Filename( tmpdir , "HAPtmpImage.txt" ); +filepng:=Filename( tmpdir , "HAPtmpImage.png" ); # create a binary array from the arc presentation bin_arr:=Sum(PureCubicalKnot(arc)!.binaryArray); @@ -1042,12 +1046,18 @@ InstallGlobalFunction( Concatenation("rm ",filetxt) ); # display the image + #Exec( + # Concatenation(DISPLAY_PATH," ","/tmp/HAPtmpImage.png") + #); Exec( - Concatenation(DISPLAY_PATH," ","/tmp/HAPtmpImage.png") + Concatenation(DISPLAY_PATH," ",filepng) ); # delete the image on window close + #Exec( + # Concatenation("rm ","/tmp/HAPtmpImage.png") + #); Exec( - Concatenation("rm ","/tmp/HAPtmpImage.png") + Concatenation("rm ",filepng) ); end); diff --git a/lib/Kelvin/tutex/kelvin-07.txt b/lib/Kelvin/tutex/kelvin-07.txt index 1ac53cd0..a5d9d7ac 100755 --- a/lib/Kelvin/tutex/kelvin-07.txt +++ b/lib/Kelvin/tutex/kelvin-07.txt @@ -2,6 +2,6 @@ gap> arc:=ArcPresentation(PureCubicalKnot(6,1)); [ [ 5, 8 ], [ 4, 6 ], [ 3, 5 ], [ 2, 4 ], [ 1, 3 ], [ 2, 7 ], [ 6, 8 ], [ 1, 7 ] ] gap> cross:=[0,0,1,-1,-1,0];; gap> cols:=[1,4,3];; -gap> ViewColouredArcDiagram(arc,cross,cols); +gap> ViewArc2Presentation([arc,cross,cols]); convert-im6.q16: pixels are not authentic `/tmp/HAPtmpImage.txt' @ error/cache.c/QueueAuthenticPixelCacheNexus/4381. diff --git a/lib/PolyComplexes/prog b/lib/PolyComplexes/prog index 8bb62263..eb1235ff 100755 --- a/lib/PolyComplexes/prog +++ b/lib/PolyComplexes/prog @@ -2,7 +2,9 @@ # # Program to convert image text files to GAP matrices. -$file = '/tmp/im.txt'; # Name the file +($file) = @ARGV; +#$file = '/tmp/im.txt'; # Name the file + open(INFO, $file); # Open the file my $line = ; @parts = split /(:|,)/, $line; diff --git a/lib/PolyComplexes/pureCubicalComplexes.gi b/lib/PolyComplexes/pureCubicalComplexes.gi index ed3f96ef..2f4a9a87 100644 --- a/lib/PolyComplexes/pureCubicalComplexes.gi +++ b/lib/PolyComplexes/pureCubicalComplexes.gi @@ -306,19 +306,15 @@ if IsString(file) then tmpdir := DirectoryTemporary();; file1:=Filename( tmpdir , "im.txt" ); file2:=Filename( tmpdir , "im.g" ); -file1:="/tmp/im.txt"; #I HAVE NO IDEA WHY I NEED TO DO THIS, BUT IF - #I DON'T THEN THE FUNCTION CRASHES -#i:=Concatenation("convert -colorspace RGB -depth 8 ",file," /tmp/im.txt"); i:=Concatenation("convert -colorspace RGB -depth 8 ",file," ",file1); Exec(i); -#i:=Concatenation("perl ",prog," /tmp/im.txt >/tmp/im.g"); i:=Concatenation("perl ",prog," ",file1," > ",file2); Exec(i); Exec(Concatenation("rm ",file1)); -#Read("/tmp/im.g"); Read(file2); + B:=StructuralCopy(HAPAAA); HAPAAA:=0; diff --git a/lib/Resolutions/presentation.gi b/lib/Resolutions/presentation.gi index 9ce91456..0bd22858 100644 --- a/lib/Resolutions/presentation.gi +++ b/lib/Resolutions/presentation.gi @@ -240,6 +240,7 @@ local Tree,Verts, NTree, NNTree, VertElts, index, cnt, gens, Gens, F, src,trg, + alpha, len, B,i,a, b,bb,x,y,g,lst,bool; if not (IsHapResolution(R) or IsHapEquivariantCWComplex(R)) then @@ -428,7 +429,13 @@ a:=List(a,i->SignInt(i[3])*index[AbsInt(i[3])]); Add(HRels1,a); od; +alpha:=["x","y","z","w","v","u","t","s","r","q","p"]; +len:=Length(HGens)-Length(Tree); +if len<12 then +F:=FreeGroup(alpha{[1..len]}); +else F:=FreeGroup(Length(HGens)-Length(Tree)); +fi; gens:=GeneratorsOfGroup(F); HRels:=[]; diff --git a/lib/Streams/streams.gi b/lib/Streams/streams.gi index 320c42c5..bbad13dd 100644 --- a/lib/Streams/streams.gi +++ b/lib/Streams/streams.gi @@ -5,10 +5,11 @@ HAP_XYXYXYXY:=0; #################################################### InstallGlobalFunction(ChildProcess, function(arg) -local d,f,s,Name,Remote,Computer,ST,AppendTo,PrintTo; +local d,f,s,Name,Remote,Computer,ST,AppendTo,PrintTo,tmpdir; AppendTo:=HAP_AppendTo; PrintTo:=HAP_PrintTo; +tmpdir := DirectoryTemporary();; d:= DirectoryCurrent(); @@ -43,12 +44,15 @@ if not Remote then Name:=Filename(DirectoryTemporary(),"name"); else ST:=String(Random([1..100000])); -Name:=Concatenation("/tmp/",ST); +#Name:=Concatenation("/tmp/",ST); +Name:=Concatenation(tmpdir,ST); while IsExistingFile(Name) do ST:=String(Random([1..100000])); -Name:=Concatenation("/tmp/",ST); +#Name:=Concatenation("/tmp/",ST); +Name:=Concatenation(tmpdir,ST); od; -Name:=Filename(Directory("/tmp"),ST); +#Name:=Filename(Directory("/tmp"),ST); +Name:=Filename(Directory(tmpdir),ST); fi; Add(HAPchildren,Name); @@ -74,12 +78,14 @@ function(s) local i; CloseStream(s.stream); if not s!.remote then -i:=Concatenation("rm -r ",s!.name{[1..Length(s!.name)-4]}); +#i:=Concatenation("rm -r ",s!.name{[1..Length(s!.name)-4]}); +RemoveFile(s!.name{[1..Length(s!.name)-4]}); else -i:=Concatenation(["rm ",s!.name]); +#i:=Concatenation(["rm ",s!.name]); +RemoveFile(s!.name); fi; -Exec(i); +#Exec(i); end); #################################################### @@ -210,10 +216,12 @@ end); ##################################################### InstallGlobalFunction(ChildPut, function(X,Name,s) -local i,fle,flebatch,fleRemote,AppendTo,PrintTo; +local i,fle,flebatch,fleRemote,AppendTo,PrintTo, tmpdir; AppendTo:=HAP_AppendTo; PrintTo:=HAP_PrintTo; +tmpdir := DirectoryTemporary();; + NextAvailableChild([s]); #Don't start if s is busy. @@ -223,9 +231,11 @@ if not s!.remote then fle:=Filename(DirectoryTemporary(),"fle"); else -fle:=Concatenation("/tmp/",String(Random([1..100000]))); +#fle:=Concatenation("/tmp/",String(Random([1..100000]))); +fle:=Concatenation(tmpdir,String(Random([1..100000]))); while IsExistingFile(fle) do -fle:=Concatenation("/tmp/",String(Random([1..100000]))); +#fle:=Concatenation("/tmp/",String(Random([1..100000]))); +fle:=Concatenation(tmpdir,String(Random([1..100000]))); od; fleRemote:=Concatenation(fle,"Remote"); flebatch:=Concatenation(fle,"Batch"); @@ -248,13 +258,16 @@ if s!.remote then i:=Concatenation("Read(\"",fle,"\");"); ChildCommand(i,s,true); if not s!.remote then -i:=Concatenation("Exec(\"rm -r ",fle{[1..Length(fle)-4]},"\");"); +#i:=Concatenation("Exec(\"rm -r ",fle{[1..Length(fle)-4]},"\");"); +i:=Concatenation("RemoveFile(\"",fle{[1..Length(fle)-4]},"\");"); else -i:=Concatenation("Exec(\"rm ",fle,"\");"); +#i:=Concatenation("Exec(\"rm ",fle,"\");"); +i:=Concatenation("RemoveFile(\"",fle{[1..Length(fle)]},"\");"); fi; ChildCommand(i,s,true); if s!.remote then -i:=Concatenation("Exec(\"rm ",flebatch,"\");"); +#i:=Concatenation("Exec(\"rm ",flebatch,"\");"); +i:=Concatenation("RemoveFile(\"",flebatch,"\");"); ChildCommand(i,s,true); fi; @@ -268,11 +281,11 @@ HAP_XYXYXYXY:=0; ##################################################### InstallGlobalFunction(ChildGet, function(X,s) -local i,ST, fle, fleLocal, batchfile, AppendTo, PrintTo; +local i,ST, fle, fleLocal, batchfile, AppendTo, PrintTo, tmpdir; AppendTo:=HAP_AppendTo; PrintTo:=HAP_PrintTo; - +tmpdir:=DirectoryTemporary(); NextAvailableChild([s]); #Don't start if s is busy. PrintTo(s.name,"HAPchildToggle\:=false;"); @@ -283,10 +296,12 @@ fle:=Filename(DirectoryTemporary(),"fle"); else ST:=String(Random([1..100000])); -fle:=Concatenation("/tmp/",ST); +#fle:=Concatenation("/tmp/",ST); +fle:=Concatenation(tmpdir,ST); while IsExistingFile(fle) do ST:=String(Random([1..100000])); -fle:=Concatenation("/tmp/",ST); +#fle:=Concatenation("/tmp/",ST); +fle:=Concatenation(tmpdir,ST); od; #fle:=Filename(Directory("/tmp"),ST); fleLocal:=Concatenation(fle,"Local"); @@ -321,9 +336,11 @@ Read(fle); i:=Concatenation(["PrintTo(\"",String(s.name),"\",\"HAPchildToggle\:=true;\");"]); WriteLine(s.stream,i);; if s!.remote then -Exec(Concatenation(["rm ",fle])); +#Exec(Concatenation(["rm ",fle])); +RemoveFile(fle); else -Exec(Concatenation("rm -r ",fle{[1..Length(fle)-4]})); +#Exec(Concatenation("rm -r ",fle{[1..Length(fle)-4]})); +RemoveFile(fle{[1..Length(fle)-4]}); fi; diff --git a/lib/hap_afterthought.gd b/lib/hap_afterthought.gd index fac13af8..9c9eaa34 100644 --- a/lib/hap_afterthought.gd +++ b/lib/hap_afterthought.gd @@ -16,6 +16,7 @@ fi; #MakeReadOnlyGlobal("HAP_PERMMOVES_DIM_2"); #MakeReadOnlyGlobal("HAP_PERMMOVES_DIM_3"); #MakeReadOnlyGlobal("HAP_XYXYXYXY"); +#MakeReadOnlyGlobal("HAP_type"); #MakeReadOnlyGlobal("HAPchildFunctionToggle"); #MakeReadOnlyGlobal("HAPchildToggle"); #MakeReadOnlyGlobal("HAPchildren"); diff --git a/tst/testall1/1.8.2.tst b/tst/testall1/1.8.2.tst index 4a765805..f94d4ace 100644 --- a/tst/testall1/1.8.2.tst +++ b/tst/testall1/1.8.2.tst @@ -19,9 +19,9 @@ gap> for k in [0..2] do 1 1 gap> F:=FundamentalGroupOfQuotient(Y); - + gap> RelatorsOfFpGroup(F); -[ f1*f2^-1*f3^-1, f1*f3^-1*f2, f1*f3*f2^-1, f1*f2*f3 ] +[ x*y^-1*z^-1, x*z^-1*y, x*z*y^-1, x*y*z ] gap> STOP_TEST( "tst.tst", 1000 ); diff --git a/tst/testall1/1.9.1.tst b/tst/testall1/1.9.1.tst index 9c8496aa..b74198f8 100644 --- a/tst/testall1/1.9.1.tst +++ b/tst/testall1/1.9.1.tst @@ -7,20 +7,19 @@ gap> Y:=EquivariantTwoComplex(G); Equivariant CW-complex of dimension 2 gap> F:=FundamentalGroupOfQuotient(Y); - + gap> RelatorsOfFpGroup(F); -[ f1^2, f2^2, f3^2, f3^-1*f1*f3*f1^-1, f3^-1*f2^-1*f3*f2*f3*f2^-1, - (f2^-1*f1^-1)^2*(f2*f1)^2*f2*f1^-1 ] +[ x^2, y^2, z^2, z^-1*x*z*x^-1, z^-1*y^-1*z*y*z*y^-1, + (y^-1*x^-1)^2*(y*x)^2*y*x^-1 ] gap> H:=Group(x*y,x*z,y*z);; gap> W:=RestrictedEquivariantCWComplex(Y,H); Equivariant CW-complex of dimension 2 gap> FH:=FundamentalGroupOfQuotient(W); - + gap> RelatorsOfFpGroup(FH); -[ f1, f1, f2*f3, f3*f2, f4*f5, f5*f4, f5^-1*f1*f4, f4^-1*f5*f1^-1, - f5^-1*f2^-1*f4*f3*f4*f2^-1, f4^-1*f3^-1*f5*f2*f5*f3^-1, f3^-2*(f2*f1)^2*f2, - (f2^-1*f1^-1)^2*f3^3*f1^-1 ] +[ x, x, y*z, z*y, w*v, v*w, v^-1*x*w, w^-1*v*x^-1, v^-1*y^-1*w*z*w*y^-1, + w^-1*z^-1*v*y*v*z^-1, z^-2*(y*x)^2*y, (y^-1*x^-1)^2*z^3*x^-1 ] gap> xz:=(1,2)(3,4)(5,8)(6,7)(9,10)(11,12);; gap> yz:=(2,4,7,5,3)(6,8,10,11,9);; gap> H:=Group(xz, yz);; @@ -28,9 +27,9 @@ gap> W:=EquivariantTwoComplex(H); Equivariant CW-complex of dimension 2 gap> FH:=FundamentalGroupOfQuotient(W); - + gap> RelatorsOfFpGroup(FH); -[ f2^2, f1^5, f2^-1*(f1*f2)^2*f1 ] +[ y^2, x^5, y^-1*(x*y)^2*x ] gap> STOP_TEST( "tst.tst", 1000 ); diff --git a/tst/testallV11/1.8.1.tst b/tst/testallV11/1.8.1.tst index 8924dcd3..af97286e 100644 --- a/tst/testallV11/1.8.1.tst +++ b/tst/testallV11/1.8.1.tst @@ -20,7 +20,7 @@ gap> FaceStabilizerOrders:=Order(Y!.stabilizer(2,1)); gap> Size(Y!.boundary(2,1)); 6 gap> F:=FundamentalGroupOfQuotient(Y); - + gap> RelatorsOfFpGroup(F); -[ f1^-1*f2*f1^-1*f2^-1 ] +[ x^-1*y*x^-1*y^-1 ] gap> STOP_TEST( "tst.tst", 1000 ); diff --git a/www/home/content.html b/www/home/content.html index a7d99b5f..7df15d52 100644 --- a/www/home/content.html +++ b/www/home/content.html @@ -16,7 +16,7 @@ GAP computer algebra system, and is still under development. The current version hap1.61.tar.gz was released on -12 Dec 2023.

+02 Jan 2024.