From 299aa4e0cb9170aee8f501ea603a7c61c3d62954 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 12 Aug 2026 18:38:40 +0200 Subject: [PATCH] Count a selection without listing it For example, `NumberSmallGroups(1536, IsSupersolvableGroup)` constructs 408641062 pairs just to count and and discard them. Almost none of that work is needed if we use the indices properly. A layer can hook into `COUNT_SMALL_GROUPS_FUNCS` for this. Those layers selecting generically can us `SMALL_GROUPS_COUNT_GENERIC` there. Layers which don't use the hook falls back to the previous approach of listing group (ids) and counting them. To make this easier, we split two helpers out of `SelectSmallGroups`: `SMALL_GROUPS_PARSE_QUERY` reads the arguments, and `SMALL_GROUPS_LIBRARY_NUMBER` renumbers for 3^7, 5^7, 7^7 and 11^7 Co-Authored-By: Claude Opus 5 --- CHANGES.md | 11 +- gap/small.gi | 273 +++++++++++++++++++++++++++++++--------------- small10/smlgp10.g | 4 +- small11/smlgp11.g | 3 +- small3/smlgp3.g | 3 +- small4/smlgp4.g | 3 +- small6/smlgp6.g | 3 +- small7/smlgp7.g | 3 +- small8/smlgp8.g | 3 +- small9/smlgp9.g | 5 +- tst/count.tst | 45 ++++++++ tst/small.tst | 2 +- 12 files changed, 257 insertions(+), 101 deletions(-) create mode 100644 tst/count.tst diff --git a/CHANGES.md b/CHANGES.md index 3be323d..2322e5e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,12 +1,17 @@ This file describes changes in the smallgrp package. +# Unreleased + + - Optimized `NumberSmallGroups` to be much faster in certain cases, for + example `NumberSmallGroups(1536, IsSolvableGroup, true)` is now instant + instead of running for 90 seconds. + # 1.6.0 (2026-08-09) - Require GAP 4.12 - `NumberSmallGroups` now accepts a list of orders and the selection - criteria of `AllSmallGroups`, as in `NumberSmallGroups(96, IsAbelian)`. - It counts by listing the ids, so it costs what `IdsOfAllSmallGroups` - costs (issue #68) + criteria of `AllSmallGroups`, as in `NumberSmallGroups(96, IsAbelian)` + (issue #68) - Selection by `IsAbelian`, `IsNilpotentGroup`, `IsSupersolvableGroup`, `IsSolvableGroup`, `RankPGroup` and `PClassPGroup` now avoids constructing the groups for most orders which had no precomputed data, diff --git a/gap/small.gi b/gap/small.gi index ccdae55..9230498 100644 --- a/gap/small.gi +++ b/gap/small.gi @@ -83,6 +83,15 @@ NUMBER_SMALL_GROUPS_FUNCS := [ ]; ## SELECT_SMALL_GROUPS_FUNCS := [ ]; +############################################################################# +## +#F COUNT_SMALL_GROUPS_FUNCS +## +## A layer may install a function here to count a selection rather than +## list it, taking , , , and . Without +## one the groups are listed and the list measured. +COUNT_SMALL_GROUPS_FUNCS := [ ]; + ############################################################################# ## #F SMALL_IDS_EXPAND( ) @@ -345,6 +354,77 @@ SMALL_GROUPS_SIMPLIFY_QUERY := function( funcs, vals ) return rec( funcs := newfuncs, vals := newvals ); end; +############################################################################# +## +#F SMALL_GROUPS_PARSE_QUERY( argl ) +## +## turns the arguments of 'AllSmallGroups' and its kin into a record with +## the components 'sizes', 'idList', 'funcs' and 'vals', the latter two as +## 'SMALL_GROUPS_SIMPLIFY_QUERY' leaves them. +SMALL_GROUPS_PARSE_QUERY := function( argl ) + local sizes, i, funcs, vals, hasSizes, pos, idList, query; + + sizes := [ ]; + hasSizes := false; + idList := fail; + + for i in [ 1 .. Length( argl ) ] do + if i = 1 and argl[ i ] = Size then + ; + elif ( not hasSizes ) and IsList( argl[ i ] ) + and Length( sizes ) = 1 then + idList := argl[ i ]; + elif ( not hasSizes ) and IsList( argl[ i ] ) then + Append( sizes, argl[ i ] ); + elif ( not hasSizes ) and IsPosInt( argl[ i ] ) then + Add( sizes, argl[ i ] ); + elif ( not hasSizes ) and sizes <> [] and IsFunction( argl[i] ) then + hasSizes := true; + funcs := [ argl[ i ] ]; + vals := [ [ ] ]; + pos := 1; + elif not hasSizes then + Error( "usage: AllSmallGroups / OneSmallGroup(\n", + " Size, [ sizes ],\n", + " function1, [ values1 ],\n", + " function2, [ values2 ], ... )" ); + elif vals[ pos ] <> [ ] and IsFunction( argl[ i ] ) then + pos := pos + 1; + funcs[ pos ] := argl[ i ]; + vals[ pos ] := [ ]; + elif IsFunction( argl[ i ] ) then + vals[ pos ] := [ true ]; + pos := pos + 1; + funcs[ pos ] := argl[ i ]; + vals[ pos ] := [ ]; + elif IsList( argl[ i ] ) and vals[ pos ] = [ ] then + vals[ pos ] := argl[ i ]; + elif IsList( argl[ i ] ) and IsInt( argl[ i ][ 1 ] ) and + IsList( vals[ pos ][ 1 ] ) and IsInt( vals[ pos ][1][ 1 ] ) then + Add( vals[ pos ], argl[ i ] ); + elif IsList( argl[ i ] ) and IsInt( argl[ i ][ 1 ] ) and + IsInt( vals[ pos ][ 1 ] ) then + vals[ pos ] := [ vals[ pos ], argl[ i ] ]; + else + Add( vals[ pos ], argl[ i ] ); + fi; + od; + + if sizes <> [ ] and ( not IsBound( vals ) ) then + funcs := [ ]; + vals := [ ]; + elif vals[ pos ] = [ ] then + vals[ pos ] := [ true ]; + fi; + + query := SMALL_GROUPS_SIMPLIFY_QUERY( funcs, vals ); + funcs := query.funcs; + vals := query.vals; + + return rec( sizes := sizes, idList := idList, + funcs := query.funcs, vals := query.vals ); +end; + ############################################################################# ## #F SMALL_GROUPS_PROPERTIES_FUNCS @@ -499,6 +579,28 @@ SMALL_GROUPS_PROPERTY_IDS := function( size, inforec, funcs, vals ) return rec( ids := ids, funcs := evalfuncs, vals := evalvals ); end; +############################################################################# +## +#F SMALL_GROUPS_LIBRARY_NUMBER( size, i ) +## +## the number the library stores 'SmallGroup( size, i )' under. The two +## differ for the orders 3^7, 5^7, 7^7 and 11^7; see +## 'SMALL_GROUPS_OLD_ORDER'. +SMALL_GROUPS_LIBRARY_NUMBER := function( size, i ) + if SMALL_GROUPS_OLD_ORDER then + return i; + elif size = 3^7 then + return SMALLGP_PERM3( i ); + elif size = 5^7 then + return SMALLGP_PERM5( i ); + elif size = 7^7 then + return SMALLGP_PERM7( i ); + elif size = 11^7 then + return SMALLGP_PERM11( i ); + fi; + return i; +end; + ############################################################################# ## #F SMALL_GROUPS_SELECT_GENERIC( size, funcs, vals, inforec, all, id, idList ) @@ -508,7 +610,7 @@ end; ## them. SMALL_GROUPS_SELECT_GENERIC := function( size, funcs, vals, inforec, all, id, idList ) - local result, i, g, ok, j, sel, range, nid; + local result, i, g, ok, j, sel, range; if not IsBound( inforec.number ) then inforec := NUMBER_SMALL_GROUPS_FUNCS[ inforec.func ]( size, inforec); @@ -538,20 +640,8 @@ SMALL_GROUPS_SELECT_GENERIC := function( size, funcs, vals, inforec, result := [ ]; for i in range do - nid:=i; - if not SMALL_GROUPS_OLD_ORDER then - if size = 3^7 then - nid := SMALLGP_PERM3(i); - elif size = 5^7 then - nid := SMALLGP_PERM5(i); - elif size = 7^7 then - nid := SMALLGP_PERM7(i); - elif size = 11^7 then - nid := SMALLGP_PERM11(i); - fi; - fi; - - g := SMALL_GROUP_FUNCS[ inforec.func ]( size, nid, inforec ); + g := SMALL_GROUP_FUNCS[ inforec.func ]( + size, SMALL_GROUPS_LIBRARY_NUMBER( size, i ), inforec ); SetIdGroup( g, [ size, i ] ); ok := true; for j in [ 1 .. Length( funcs ) ] do @@ -573,6 +663,74 @@ SMALL_GROUPS_SELECT_GENERIC := function( size, funcs, vals, inforec, fi; end; +############################################################################# +## +#F SMALL_GROUPS_COUNT_GENERIC( size, funcs, vals, inforec, idList ) +## +## how many groups 'SMALL_GROUPS_SELECT_GENERIC' would return, without +## building the list. +SMALL_GROUPS_COUNT_GENERIC := function( size, funcs, vals, inforec, idList ) + local sel, range, n, i, g; + + if not IsBound( inforec.number ) then + inforec := NUMBER_SMALL_GROUPS_FUNCS[ inforec.func ]( size, inforec ); + fi; + sel := SMALL_GROUPS_PROPERTY_IDS( size, inforec, funcs, vals ); + + if idList = fail then + if sel.funcs = [ ] then + return Sum( sel.ids, run -> SMALL_IDS_LAST( run ) + - SMALL_IDS_FIRST( run ) + 1 ); + fi; + range := SMALL_IDS_EXPAND( sel.ids ); + else + range := Filtered( idList, x -> SMALL_IDS_MEMBER( sel.ids, x ) ); + if sel.funcs = [ ] then + return Length( range ); + fi; + fi; + + n := 0; + for i in range do + g := SMALL_GROUP_FUNCS[ inforec.func ]( + size, SMALL_GROUPS_LIBRARY_NUMBER( size, i ), inforec ); + SetIdGroup( g, [ size, i ] ); + if ForAll( [ 1 .. Length( sel.funcs ) ], + j -> sel.funcs[ j ]( g ) in sel.vals[ j ] ) then + n := n + 1; + fi; + od; + return n; +end; + +############################################################################# +## +#F SMALL_GROUPS_COUNT( argl ) +## +## the number of groups the selection describes. +SMALL_GROUPS_COUNT := function( argl ) + local query, n, size, inforec; + + query := SMALL_GROUPS_PARSE_QUERY( argl ); + n := 0; + for size in query.sizes do + inforec := SMALL_AVAILABLE( size ); + if inforec = fail then + Error( "NumberSmallGroups: groups of order ", size, + " not available" ); + fi; + if IsBound( COUNT_SMALL_GROUPS_FUNCS[ inforec.func ] ) then + n := n + COUNT_SMALL_GROUPS_FUNCS[ inforec.func ] + ( size, query.funcs, query.vals, inforec, query.idList ); + else + n := n + Length( SELECT_SMALL_GROUPS_FUNCS[ inforec.func ] + ( size, query.funcs, query.vals, inforec, + true, true, query.idList ) ); + fi; + od; + return n; +end; + ############################################################################# ## #V SMALL_GROUP_LIB @@ -597,7 +755,7 @@ PROPERTIES_SMALL_GROUPS := [ ]; ## an PcGroup, if the group is soluble and a permutation group otherwise. ## If the groups of this size are not installed, it will return an error. InstallGlobalFunction( SmallGroup, function( arg ) - local inforec, g, size, i, nid; + local inforec, g, size, i; if Length( arg ) = 1 then if not IsList( arg[1] ) or Length( arg[1] ) <> 2 then @@ -618,19 +776,8 @@ InstallGlobalFunction( SmallGroup, function( arg ) if inforec = fail then Error( "the library of groups of size ", size, " is not available" ); fi; - nid := i; - if not SMALL_GROUPS_OLD_ORDER then - if size = 3^7 then - nid := SMALLGP_PERM3(i); - elif size = 5^7 then - nid := SMALLGP_PERM5(i); - elif size = 7^7 then - nid := SMALLGP_PERM7(i); - elif size = 11^7 then - nid := SMALLGP_PERM11(i); - fi; - fi; - g := SMALL_GROUP_FUNCS[ inforec.func ]( size, nid, inforec ); + g := SMALL_GROUP_FUNCS[ inforec.func ]( + size, SMALL_GROUPS_LIBRARY_NUMBER( size, i ), inforec ); SetIdGroup( g, [ size, i ] ); IsPGroup( g ); return g; @@ -695,74 +842,22 @@ InstallGlobalFunction( NumberSmallGroups, function( arg ) Error( "usage: NumberSmallGroups( order )" ); fi; - # so far counting the groups is not cheaper than listing their ids - return Length( SelectSmallGroups( arg, true, true ) ); + return SMALL_GROUPS_COUNT( arg ); end ); ############################################################################# ## #F SelectSmallGroups( argl, all, id ) ## -InstallGlobalFunction( SelectSmallGroups, function( argl, all, id ) - local sizes, size, i, funcs, vals, gs, inforec, result, hasSizes, pos, - idList, query; - - sizes := [ ]; - hasSizes := false; - idList := fail; - for i in [ 1 .. Length( argl ) ] do - if i = 1 and argl[ i ] = Size then - ; - elif ( not hasSizes ) and IsList( argl[ i ] ) - and Length( sizes ) = 1 then - idList := argl[ i ]; - elif ( not hasSizes ) and IsList( argl[ i ] ) then - Append( sizes, argl[ i ] ); - elif ( not hasSizes ) and IsPosInt( argl[ i ] ) then - Add( sizes, argl[ i ] ); - elif ( not hasSizes ) and sizes <> [] and IsFunction( argl[i] ) then - hasSizes := true; - funcs := [ argl[ i ] ]; - vals := [ [ ] ]; - pos := 1; - elif not hasSizes then - Error( "usage: AllSmallGroups / OneSmallGroup(\n", - " Size, [ sizes ],\n", - " function1, [ values1 ],\n", - " function2, [ values2 ], ... )" ); - elif vals[ pos ] <> [ ] and IsFunction( argl[ i ] ) then - pos := pos + 1; - funcs[ pos ] := argl[ i ]; - vals[ pos ] := [ ]; - elif IsFunction( argl[ i ] ) then - vals[ pos ] := [ true ]; - pos := pos + 1; - funcs[ pos ] := argl[ i ]; - vals[ pos ] := [ ]; - elif IsList( argl[ i ] ) and vals[ pos ] = [ ] then - vals[ pos ] := argl[ i ]; - elif IsList( argl[ i ] ) and IsInt( argl[ i ][ 1 ] ) and - IsList( vals[ pos ][ 1 ] ) and IsInt( vals[ pos ][1][ 1 ] ) then - Add( vals[ pos ], argl[ i ] ); - elif IsList( argl[ i ] ) and IsInt( argl[ i ][ 1 ] ) and - IsInt( vals[ pos ][ 1 ] ) then - vals[ pos ] := [ vals[ pos ], argl[ i ] ]; - else - Add( vals[ pos ], argl[ i ] ); - fi; - od; - - if sizes <> [ ] and ( not IsBound( vals ) ) then - funcs := [ ]; - vals := [ ]; - elif vals[ pos ] = [ ] then - vals[ pos ] := [ true ]; - fi; +InstallGlobalFunction( SelectSmallGroups, function( argl, all, id ) + local query, sizes, funcs, vals, idList, size, gs, inforec, result; - query := SMALL_GROUPS_SIMPLIFY_QUERY( funcs, vals ); - funcs := query.funcs; - vals := query.vals; + query := SMALL_GROUPS_PARSE_QUERY( argl ); + sizes := query.sizes; + funcs := query.funcs; + vals := query.vals; + idList := query.idList; result := [ ]; for size in sizes do diff --git a/small10/smlgp10.g b/small10/smlgp10.g index 59defac..dccd06f 100644 --- a/small10/smlgp10.g +++ b/small10/smlgp10.g @@ -189,10 +189,12 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 24 .. 25 ]( funcs, vals, inforec, all, id ) +#F SELECT_SMALL_GROUPS_FUNCS[ 24 .. 25 ], COUNT_SMALL_GROUPS_FUNCS[ 24 .. 25 ] ## SELECT_SMALL_GROUPS_FUNCS[ 24 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 24 ] := SMALL_GROUPS_COUNT_GENERIC; SELECT_SMALL_GROUPS_FUNCS[ 25 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 25 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small11/smlgp11.g b/small11/smlgp11.g index e71cad9..02f1f67 100644 --- a/small11/smlgp11.g +++ b/small11/smlgp11.g @@ -225,9 +225,10 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 26 ]( funcs, vals, inforec, all, id ) +#F SELECT_SMALL_GROUPS_FUNCS[ 26 ], COUNT_SMALL_GROUPS_FUNCS[ 26 ] ## SELECT_SMALL_GROUPS_FUNCS[ 26 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 26 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small3/smlgp3.g b/small3/smlgp3.g index ff2ab53..ecdba61 100644 --- a/small3/smlgp3.g +++ b/small3/smlgp3.g @@ -347,9 +347,10 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 11 ] +#F SELECT_SMALL_GROUPS_FUNCS[ 11 ], COUNT_SMALL_GROUPS_FUNCS[ 11 ] ## SELECT_SMALL_GROUPS_FUNCS[ 11 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 11 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small4/smlgp4.g b/small4/smlgp4.g index 6897f7a..984fa18 100644 --- a/small4/smlgp4.g +++ b/small4/smlgp4.g @@ -219,9 +219,10 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 17 ] +#F SELECT_SMALL_GROUPS_FUNCS[ 17 ], COUNT_SMALL_GROUPS_FUNCS[ 17 ] ## SELECT_SMALL_GROUPS_FUNCS[ 17 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 17 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small6/smlgp6.g b/small6/smlgp6.g index 22af60c..276102b 100644 --- a/small6/smlgp6.g +++ b/small6/smlgp6.g @@ -182,9 +182,10 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 12 ]( funcs, vals, inforec, all, id ) +#F SELECT_SMALL_GROUPS_FUNCS[ 12 ], COUNT_SMALL_GROUPS_FUNCS[ 12 ] ## SELECT_SMALL_GROUPS_FUNCS[ 12 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 12 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small7/smlgp7.g b/small7/smlgp7.g index 781bbff..6fa2689 100644 --- a/small7/smlgp7.g +++ b/small7/smlgp7.g @@ -155,9 +155,10 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 18 ]( funcs, vals, inforec, all, id ) +#F SELECT_SMALL_GROUPS_FUNCS[ 18 ], COUNT_SMALL_GROUPS_FUNCS[ 18 ] ## SELECT_SMALL_GROUPS_FUNCS[ 18 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 18 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small8/smlgp8.g b/small8/smlgp8.g index c1beaec..3ddbd98 100644 --- a/small8/smlgp8.g +++ b/small8/smlgp8.g @@ -308,9 +308,10 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 14 ]( funcs, vals, inforec, all, id, idList ) +#F SELECT_SMALL_GROUPS_FUNCS[ 14 ], COUNT_SMALL_GROUPS_FUNCS[ 14 ] ## SELECT_SMALL_GROUPS_FUNCS[ 14 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 14 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/small9/smlgp9.g b/small9/smlgp9.g index 8947a93..d3fb3e3 100644 --- a/small9/smlgp9.g +++ b/small9/smlgp9.g @@ -1074,11 +1074,14 @@ end; ############################################################################# ## -#F SELECT_SMALL_GROUPS_FUNCS[ 19, 20, 21 ]( funcs, vals, inforec, all, id ) +#F SELECT_SMALL_GROUPS_FUNCS[ 19, 20, 21 ], COUNT_SMALL_GROUPS_FUNCS[ 19, 20, 21 ] ## SELECT_SMALL_GROUPS_FUNCS[ 19 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 19 ] := SMALL_GROUPS_COUNT_GENERIC; SELECT_SMALL_GROUPS_FUNCS[ 20 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 20 ] := SMALL_GROUPS_COUNT_GENERIC; SELECT_SMALL_GROUPS_FUNCS[ 21 ] := SMALL_GROUPS_SELECT_GENERIC; +COUNT_SMALL_GROUPS_FUNCS[ 21 ] := SMALL_GROUPS_COUNT_GENERIC; ############################################################################# ## diff --git a/tst/count.tst b/tst/count.tst new file mode 100644 index 0000000..c03fbaa --- /dev/null +++ b/tst/count.tst @@ -0,0 +1,45 @@ +# +# Counting a selection without listing it +# +gap> START_TEST("count.tst"); + +# the orders where listing is out of the question +gap> NumberSmallGroups(1536, IsSolvableGroup, true); +408641062 +gap> NumberSmallGroups(1536, IsNilpotentGroup, true); +10494213 +gap> NumberSmallGroups(512, RankPGroup, 2); +2043 +gap> NumberSmallGroups(1920, IsSolvableGroup, false); +588 + +# counting agrees with listing wherever listing is affordable +gap> orders := [ 12, 30, 64, 96, 128, 720, 1016, 1029, 1088, 1215, 2002, +> 2004, 3420 ];; +gap> props := [ IsAbelian, IsNilpotentGroup, IsSupersolvableGroup, +> IsSolvableGroup ];; +gap> ForAll(orders, n -> ForAll(props, f -> ForAll([true, false], v -> +> NumberSmallGroups(n, f, v) = Length(IdsOfAllSmallGroups(n, f, v))))); +true + +# with a list of group numbers, and with a criterion no layer indexes +gap> ForAll(orders, n -> NumberSmallGroups(n, +> Filtered([1 .. NrSmallGroups(n)], IsOddInt), IsAbelian, true) +> = Length(IdsOfAllSmallGroups(n, +> Filtered([1 .. NrSmallGroups(n)], IsOddInt), IsAbelian, true))); +true +gap> ForAll(orders, n -> +> NumberSmallGroups(n, IsSolvableGroup, true, IsCyclic, false) +> = Length(IdsOfAllSmallGroups(n, IsSolvableGroup, true, IsCyclic, +> false))); +true + +# several orders at once, with and without criteria +gap> NumberSmallGroups([1 .. 100]) = Sum([1 .. 100], NrSmallGroups); +true +gap> NumberSmallGroups(Size, [96, 720], IsAbelian, true) +> = Length(IdsOfAllSmallGroups(Size, [96, 720], IsAbelian, true)); +true + +# +gap> STOP_TEST("count.tst"); diff --git a/tst/small.tst b/tst/small.tst index 7ceb05d..ef53352 100644 --- a/tst/small.tst +++ b/tst/small.tst @@ -171,7 +171,7 @@ gap> NumberSmallGroups(60, [ 1 .. 10 ], IsNilpotentGroup); # selection criteria need the library, even where the number does not gap> NumberSmallGroups(1024, IsAbelian); -Error, AllSmallGroups / OneSmallGroup: groups of order 1024 not available +Error, NumberSmallGroups: groups of order 1024 not available ################################################################################ # SelectSmallGroups GlobalFunction (called by AllSmallGroups or OneSmallGroup)