diff --git a/docs/src/Groups/grouplib.md b/docs/src/Groups/grouplib.md index 142e2bb0e6ab..7cc62d1b7b28 100644 --- a/docs/src/Groups/grouplib.md +++ b/docs/src/Groups/grouplib.md @@ -76,6 +76,7 @@ not have a faithful permutation representation of small degree. Computations in these groups may be rather time consuming. ```@docs +all_perfect_groups has_number_of_perfect_groups has_perfect_group_identification has_perfect_groups diff --git a/src/Groups/libraries/perfectgroups.jl b/src/Groups/libraries/perfectgroups.jl index 2f4db6185f5a..2ae68f00905c 100644 --- a/src/Groups/libraries/perfectgroups.jl +++ b/src/Groups/libraries/perfectgroups.jl @@ -178,7 +178,75 @@ function number_of_perfect_groups(n::IntegerUnion) return res::Int end -# TODO: add all_perfect_groups() iterator + +""" + all_perfect_groups(L...) + +Return the list of all perfect groups (up to permutation isomorphism) +satisfying the conditions described by the arguments. These conditions +may be of one of the following forms: + +- `func => intval` selects groups for which the function `func` returns `intval` +- `func => list` selects groups for which the function `func` returns any element inside `list` +- `func` selects groups for which the function `func` returns `true` +- `!func` selects groups for which the function `func` returns `false` + +As a special case, the first argument may also be one of the following: +- `intval` selects groups whose order equals `intval`; this is equivalent to `order => intval` +- `intlist` selects groups whose order is in `intlist`; this is equivalent to `order => intlist` + +The following functions are currently supported as values for `func`: +- `is_quasisimple` +- `is_simple` +- `is_sporadic_simple` +- `number_of_conjugacy_classes` +- `order` + +The type of the returned groups is `PermGroup`. + +# Examples +```jldoctest +julia> all_perfect_groups(7200) +2-element Vector{PermGroup}: + Permutation group of degree 29 and order 7200 + Permutation group of degree 288 and order 7200 + +julia> all_perfect_groups(order => 1:200, !is_simple) +2-element Vector{PermGroup}: + Permutation group of degree 1 and order 1 + Permutation group of degree 24 and order 120 +``` +""" +function all_perfect_groups(L...) + @req !isempty(L) "must specify at least one filter" + if L[1] isa IntegerUnion || L[1] isa AbstractVector{<:IntegerUnion} + L = (order => L[1], L[2:end]...) + end + # first get all order restrictions + ordsL = [x for x in L if x isa Pair && x[1] == order] + @req !isempty(ordsL) "must restrict the order" + conds = [x for x in L if !(x isa Pair && x[1] == order)] + orders = intersect([x[2] for x in ordsL]...) + @req has_perfect_groups(maximum(orders)) "only orders up to 2 million are supported" + res = PermGroup[] + for n in orders, i in 1:number_of_perfect_groups(n) + G = perfect_group(n, i) + ok = true + for c in conds + if c isa Pair + val = c[1](G) + ok = (val == c[2] || val in c[2]) + elseif c isa Function + ok = c(G) + else + throw(ArgumentError("expected a function or a pair, got $arg")) + end + ok || break + end + ok && push!(res, G) + end + return res +end function __init_extraperfect() for i in [27, 33] diff --git a/src/exports.jl b/src/exports.jl index 439003b5f2ab..194da4416aea 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -215,6 +215,7 @@ export all_blocks export all_character_table_names export all_cohomologies export all_neighbors +export all_perfect_groups export all_primitive_groups export all_small_groups export all_subsets_matroid diff --git a/test/Groups/libraries.jl b/test/Groups/libraries.jl index 517c22ac0dfe..81bec96db549 100644 --- a/test/Groups/libraries.jl +++ b/test/Groups/libraries.jl @@ -115,6 +115,21 @@ end @test_throws ArgumentError number_of_perfect_groups(0) # invalid argument @test_throws ArgumentError number_of_perfect_groups(ZZRingElem(60)^10) # result not known + Gs = all_perfect_groups(order => 1:200) + @test length(Gs) == sum(number_of_perfect_groups, 1:200) + @test Gs == all_perfect_groups(1:200) + @test length(all_perfect_groups(7200)) == number_of_perfect_groups(7200) + + # all_perfect_groups with additional attributse + @test filter(G -> number_of_conjugacy_classes(G) in 5:8, Gs) == all_perfect_groups(1:200, number_of_conjugacy_classes => 5:8) + @test filter(is_simple, Gs) == all_perfect_groups(1:200, is_simple) + @test filter(is_simple, Gs) == all_perfect_groups(1:200, is_simple => true) + @test filter(!is_simple, Gs) == all_perfect_groups(1:200, !is_simple) + @test filter(!is_simple, Gs) == all_perfect_groups(1:200, is_simple => false) + + # all_perfect_groups with multiple order specifications + @test all_perfect_groups(order => 1:5:200, order => 25:50) == all_perfect_groups(order => intersect(1:5:200, 25:50)) + # lazy artifact loading (needs network access, see https://github.com/oscar-system/Oscar.jl/issues/2480) #@test perfect_group(1376256, 1) isa PermGroup end