From 9425c78578e9b2d0cfffcf1cc05c2650a125b6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 21 Jan 2025 16:59:09 +0100 Subject: [PATCH 1/9] Allow `@perm G [list of perms]` --- src/Groups/perm.jl | 6 +++++- test/Groups/Permutations.jl | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 6a23bdeaacc6..46b89c875a7c 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -818,11 +818,15 @@ end # @doc raw""" @perm n gens + @perm G gens Input a list of permutations in cycle notation, created as elements of the symmetric group of degree `n`, i.e., `symmetric_group(n)`, by invoking [`cperm`](@ref) suitably. +Instead of the degree `n`, one can also provide the parent permutation group `G`. +This macro will raise an error if the permutations are not elements of `G`. + # Examples ```jldoctest julia> gens = @perm 14 [ @@ -860,7 +864,7 @@ macro perm(n,gens) end return quote - let g = symmetric_group($n) + let n = $(esc(n)), g = n isa Int ? symmetric_group(n) : n [ cperm(g, pi...) for pi in [$(ores...)] ] end end diff --git a/test/Groups/Permutations.jl b/test/Groups/Permutations.jl index 4ceec10803b0..9a94e9d3dfe4 100644 --- a/test/Groups/Permutations.jl +++ b/test/Groups/Permutations.jl @@ -42,6 +42,15 @@ G = sub(G,gens)[1] @test order(G) == 645120 + + n = 4 + p, = @perm n+1 [(1,2,3,4)] + @test degree(parent(p)) == n+1 + + A = alternating_group(4) + p, = @perm A [(1,2,3)] + @test parent(p) == A + @test_throws ArgumentError @perm A [(1,2,3,4)] end @testset "permutation_group" begin From ac3d10266f23e7ba741802b15d3d8b26c1498d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 21 Jan 2025 17:30:54 +0100 Subject: [PATCH 2/9] Add explicit error for intertwined `@perm` macros --- src/Groups/perm.jl | 7 +++++++ test/Groups/Permutations.jl | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 46b89c875a7c..88fda29db293 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -750,6 +750,13 @@ function _perm_helper(ex::Expr) ex == :( () ) && return [] ex isa Expr || error("Input is not a permutation expression") + if ex.head == :tuple && any(x -> x isa Expr && x.head == :macrocall && x.args[1] == Symbol("@perm"), ex.args) + error("""Encountered @perm macro inside of permutation expression. + Either set explicit parentheses for each @perm call (e.g. `@perm((1,2)), @perm((3,4))`), + or use the @perm variant that takes a list of permutations (e.g. `@perm n [(1,2), (3,4)]`). + Please refer to the docstring of @perm for more information.""") + end + res = [] while ex isa Expr && ex.head == :call push!(res, Expr(:vect, ex.args[2:end]...)) diff --git a/test/Groups/Permutations.jl b/test/Groups/Permutations.jl index 9a94e9d3dfe4..127ceb9a5bf4 100644 --- a/test/Groups/Permutations.jl +++ b/test/Groups/Permutations.jl @@ -11,8 +11,6 @@ @test p == cperm() @test_throws ArgumentError @perm (-1, 1) - @test_throws LoadError @eval @perm "bla" - @test_throws LoadError @eval @perm 1 + 1 gens = @perm 14 [ (1,10) @@ -51,6 +49,16 @@ p, = @perm A [(1,2,3)] @test parent(p) == A @test_throws ArgumentError @perm A [(1,2,3,4)] + + @static if VERSION >= v"1.7" + # the following tests need the improved `@macroexpand` from Julia 1.7 + @test_throws MethodError @macroexpand @perm "bla" + @test_throws ErrorException @macroexpand @perm 1 + 1 + @test_throws ErrorException @macroexpand [@perm (1,2), @perm (3,4), @perm (5,6)] + @test_throws ErrorException @macroexpand [@perm (1,2)(3,4), @perm (5,6)(7,8)] + @test_throws ErrorException @macroexpand p1, p2, p3 = @perm (1,2), @perm (3,4), @perm (5,6) + @test_throws ErrorException @macroexpand p1, p2 = @perm (1,2)(3,4), @perm (5,6)(7,8) + end end @testset "permutation_group" begin From 6046e0b4ddc694640329cc90155412c7f7a50eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 22 Jan 2025 18:22:12 +0100 Subject: [PATCH 3/9] Update docs and tests with wishlist for `@perm` macro features Functionality is not changed yet --- src/Groups/perm.jl | 74 +++++------ test/Groups/Permutations.jl | 243 ++++++++++++++++++++++++++++++++++-- 2 files changed, 267 insertions(+), 50 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 88fda29db293..928304ec3c7c 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -779,64 +779,64 @@ end ################################################################################ # -# perm +# @perm # +macro perm(ex) + res = _perm_helper(ex) + return esc(:(Oscar.cperm($(res...)))) +end + + @doc raw""" - @perm ex - -Input a permutation in cycle notation. Supports arbitrary expressions for -generating the integer entries of the cycles. The parent group is inferred -to be the symmetric group with a degree of the highest integer referenced -in the permutation. + @perm expr + @perm n expr + @perm G expr + +Input a permutation or a non-empty list of permutations in cycle notation. + +Supports arbitrary expressions for generating the integer entries of the cycles. + +`expr` may either be a single permutation, a non-empty list of permutations, +or a non-empty tuple of permutations. **Note:** `@perm ()` denotes the identity +permutation, NOT the empty tuple of permutations. + +If a group `G` is provided, the permutations are created as elements of `G`. This will +raise an error if the permutations are not elements of `G`. + +If an integer `n` is provided, the permutations are created as elements of the +symmetric group of degree `n`, i.e., `symmetric_group(n)`. + +Input a list of permutations in cycle notation, created as elements of the +symmetric group of degree `n`, i.e., `symmetric_group(n)`, by invoking +[`cperm`](@ref) suitably. + +In the remaining case, the parent group is inferred to be the symmetric group +with a degree of the highest integer referenced in `expr`. The actual work is done by [`cperm`](@ref). Thus, for the time being, cycles which are *not* disjoint actually are supported. # Examples ```jldoctest +```jldoctest julia> x = @perm (1,2,3)(4,5)(factorial(3),7,8) (1,2,3)(4,5)(6,7,8) julia> parent(x) Sym(8) -julia> y = cperm([1,2,3],[4,5],[6,7,8]) -(1,2,3)(4,5)(6,7,8) - -julia> x == y +julia> x == @perm 8 (1,2,3)(4,5)(factorial(3),7,8) true -julia> z = perm(symmetric_group(8),[2,3,1,5,4,7,8,6]) -(1,2,3)(4,5)(6,7,8) +julia> x == cperm([1,2,3],[4,5],[6,7,8]) +true -julia> x == z +julia> x == perm(symmetric_group(8),[2,3,1,5,4,7,8,6]) true ``` -""" -macro perm(ex) - res = _perm_helper(ex) - return esc(:(Oscar.cperm($(res...)))) -end - -################################################################################ -# -# perm(n,gens) -# -@doc raw""" - @perm n gens - @perm G gens - -Input a list of permutations in cycle notation, created as elements of the -symmetric group of degree `n`, i.e., `symmetric_group(n)`, by invoking -[`cperm`](@ref) suitably. - -Instead of the degree `n`, one can also provide the parent permutation group `G`. -This macro will raise an error if the permutations are not elements of `G`. - -# Examples ```jldoctest -julia> gens = @perm 14 [ +julia> gens = @perm [ (1,10) (2,11) (3,12) diff --git a/test/Groups/Permutations.jl b/test/Groups/Permutations.jl index 127ceb9a5bf4..3851e417a629 100644 --- a/test/Groups/Permutations.jl +++ b/test/Groups/Permutations.jl @@ -9,9 +9,7 @@ @test p == cperm([1,5,2],[3,4]) p = @perm () @test p == cperm() - - @test_throws ArgumentError @perm (-1, 1) - + gens = @perm 14 [ (1,10) (2,11) @@ -35,20 +33,239 @@ p[8] = cperm(G,[1,2,3,4,5,6,7],[8,9,10,11,12,13,14]) p[9] = cperm(G,[1,2],[10,11]) @test gens == p - - @test_throws ArgumentError @perm 10 [(1,11)] - + G = sub(G,gens)[1] @test order(G) == 645120 +end + +@testset "@perm" begin + @testset "@perm <...> cycles" begin + @testset "@perm cycles" begin + p = @perm (1,2,6)(4,5) + @test p isa PermGroupElem + G = parent(p) + @test degree(G) == 6 + @test is_natural_symmetric_group(G) + @test order(p) == 6 + + p = @perm () + @test p isa PermGroupElem + G = parent(p) + @test degree(G) == 1 + @test is_natural_symmetric_group(G) + @test order(p) == 1 + + @test_throws ArgumentError @perm (-1,1) + end + + @testset "@perm n cycles" begin + n = 7 + + p = @perm n (1,2,6)(4,5) + @test p isa PermGroupElem + G = parent(p) + @test degree(G) == n + @test is_natural_symmetric_group(G) + @test order(p) == 6 + + p = @perm n () + @test p isa PermGroupElem + G = parent(p) + @test degree(G) == n + @test is_natural_symmetric_group(G) + @test order(p) == 1 + + @test_throws ArgumentError @perm 10 (1,11) + @test_throws ArgumentError @perm 5 (-1,1) + end + + @testset "@perm G cycles" begin + S = symmetric_group(7) + p = @perm S (1,2,6)(4,5) + @test p isa PermGroupElem + @test parent(p) == S + @test order(p) == 6 + p = @perm S () + @test p isa PermGroupElem + @test parent(p) == S + @test order(p) == 1 + + @test_throws ArgumentError @perm S (-1,1) + @test_throws ArgumentError @perm S (2,5,8) + + A = alternating_group(7) + p = @perm A (1,6)(4,5) + @test p isa PermGroupElem + @test parent(p) == A + @test order(p) == 2 + p = @perm A () + @test p isa PermGroupElem + @test parent(p) == A + @test order(p) == 1 + + # perms with negative sign + @test_throws ArgumentError @perm A (3,5) + @test_throws ArgumentError @perm A (1,2,3,4) + @test_throws ArgumentError @perm A (2,5)(4,1,3) + end + end + + @testset "@perm <...> vector" begin + let n = 7 + S = symmetric_group(n) + @static if VERSION >= v"1.7" + # the following tests need the improved `@macroexpand` from Julia 1.7 + @test_throws ArgumentError @macroexpand @perm [] + @test_throws ArgumentError @macroexpand @perm n [] + @test_throws ArgumentError @macroexpand @perm S [] + end + end + + @testset "@perm vector" begin + ps = @perm [(1,4)(2,3)(6,5)] + @test ps isa Vector{PermGroupElem} + G = parent(ps[1]) + @test degree(G) == 6 + @test is_natural_symmetric_group(G) + @test ps == [@perm(G, (1,4)(2,3)(6,5))] + + ps = @perm [(1,2,3)(4,5), (6,2,3,1), (), (2,)(1,4)] + @test ps isa Vector{PermGroupElem} + @test allequal(parent, ps) + G = parent(ps[1]) + @test degree(G) == 6 + @test is_natural_symmetric_group(G) + @test ps == [@perm(G, (1,2,3)(4,5)), @perm(G, (6,2,3,1)), @perm(G, ()), @perm(G, (2,)(1,4))] + + @test_throws ArgumentError @perm [(1,-2)] + end + + @testset "@perm n vector" begin + n = 7 + ps = @perm n [(1,4)(2,3)(6,5)] + @test ps isa Vector{PermGroupElem} + G = parent(ps[1]) + @test degree(G) == n + @test is_natural_symmetric_group(G) + @test ps == [@perm(n, (1,4)(2,3)(6,5))] + + ps = @perm n [(1,2,3)(4,5), (6,2,3,1), (), (2,)(1,4)] + @test ps isa Vector{PermGroupElem} + @test allequal(parent, ps) + G = parent(ps[1]) + @test degree(G) == n + @test is_natural_symmetric_group(G) + @test ps == [@perm(n, (1,2,3)(4,5)), @perm(n, (6,2,3,1)), @perm(n, ()), @perm(n, (2,)(1,4))] + + @test_throws ArgumentError @perm 10 [(1,11)] + @test_throws ArgumentError @perm 5 [(1,-2)] + end + + @testset "@perm G vector" begin + S = symmetric_group(7) + A = alternating_group(7) + + ps = @perm S [(1,4)(2,3)(6,5)] + @test ps isa Vector{PermGroupElem} + @test parent(ps[1]) == S + @test ps == [@perm(S, (1,4)(2,3)(6,5))] + + ps = @perm S [(1,2,3)(4,5), (6,2,3,1), (), (2,)(1,4)] + @test ps isa Vector{PermGroupElem} + @test all(p -> parent(p) == S, ps) + @test ps == [@perm(S, (1,2,3)(4,5)), @perm(S, (6,2,3,1)), @perm(S, ()), @perm(S, (2,)(1,4))] + + @test_throws ArgumentError @perm S [(1,11)] + @test_throws ArgumentError @perm S [(1,-2)] + + ps = @perm A [(1,4)(6,5)] + @test ps isa Vector{PermGroupElem} + @test parent(ps[1]) == A + @test ps == [@perm(A, (1,4)(6,5))] + + ps = @perm A [(1,2,3)(4,5,7), (6,2,3,1,5), (), (2,)(1,4,5)] + @test ps isa Vector{PermGroupElem} + @test all(p -> parent(p) == A, ps) + @test ps == [@perm(A, (1,2,3)(4,5,7)), @perm(A, (6,2,3,1,5)), @perm(A, ()), @perm(A, (2,)(1,4,5))] + + @test_throws ArgumentError @perm A [(1,4)(2,3)(6,5)] + end + end + + @testset "@perm <...> tuple" begin + # the empty tuple does not throw an error as it denotes the identity permutation + @testset "@perm tuple" begin + ps = @perm ((1,4)(2,3)(6,5),) + @test ps isa NTuple{1, PermGroupElem} + G = parent(ps[1]) + @test degree(G) == 6 + @test is_natural_symmetric_group(G) + @test ps == (@perm(G, (1,4)(2,3)(6,5)),) + + ps = @perm ((1,2,3)(4,5), (6,2,3,1), (), (2,)(1,4)) + @test ps isa NTuple{4, PermGroupElem} + @test allequal(parent, ps) + G = parent(ps[1]) + @test degree(G) == 6 + @test is_natural_symmetric_group(G) + @test ps == (@perm(G, (1,2,3)(4,5)), @perm(G, (6,2,3,1)), @perm(G, ()), @perm(G, (2,)(1,4))) - n = 4 - p, = @perm n+1 [(1,2,3,4)] - @test degree(parent(p)) == n+1 + @test_throws ArgumentError @perm ((1,-2),) + end + + @testset "@perm n tuple" begin + n = 7 + + ps = @perm n ((1,4)(2,3)(6,5),) + @test ps isa NTuple{1, PermGroupElem} + G = parent(ps[1]) + @test degree(G) == n + @test is_natural_symmetric_group(G) + @test ps == (@perm(n, (1,4)(2,3)(6,5)),) + + ps = @perm n ((1,2,3)(4,5), (6,2,3,1), (), (2,)(1,4)) + @test ps isa NTuple{4, PermGroupElem} + @test allequal(parent, ps) + G = parent(ps[1]) + @test degree(G) == n + @test is_natural_symmetric_group(G) + @test ps == (@perm(n, (1,2,3)(4,5)), @perm(n, (6,2,3,1)), @perm(n, ()), @perm(n, (2,)(1,4))) + + @test_throws ArgumentError @perm 10 ((1,11),) + @test_throws ArgumentError @perm 5 ((1,-2),) + end + + @testset "@perm G tuple" begin + S = symmetric_group(7) + A = alternating_group(7) + + ps = @perm S ((1,4)(2,3)(6,5),) + @test ps isa NTuple{1, PermGroupElem} + @test parent(ps[1]) == S + @test ps == (@perm(S, (1,4)(2,3)(6,5)),) + + ps = @perm S ((1,2,3)(4,5), (6,2,3,1), (), (2,)(1,4)) + @test ps isa NTuple{4, PermGroupElem} + @test all(p -> parent(p) == S, ps) + @test ps == (@perm(S, (1,2,3)(4,5)), @perm(S, (6,2,3,1)), @perm(S, ()), @perm(S, (2,)(1,4))) + + @test_throws ArgumentError @perm S ((1,11),) + @test_throws ArgumentError @perm S ((1,-2),) + + ps = @perm A ((1,4)(6,5),) + @test ps isa NTuple{1, PermGroupElem} + @test parent(ps[1]) == A + @test ps == (@perm(A, (1,4)(6,5)),) + + ps = @perm A ((1,2,3)(4,5,7), (6,2,3,5,1), (), (2,)(1,4,5)) + @test ps isa NTuple{4, PermGroupElem} + @test all(p -> parent(p) == A, ps) + @test ps == (@perm(A, (1,2,3)(4,5,7)), @perm(A, (6,2,3,5,1)), @perm(A, ()), @perm(A, (2,)(1,4,5))) + + @test_throws ArgumentError @perm A ((1,4)(2,3)(6,5),) + end + end - A = alternating_group(4) - p, = @perm A [(1,2,3)] - @test parent(p) == A - @test_throws ArgumentError @perm A [(1,2,3,4)] @static if VERSION >= v"1.7" # the following tests need the improved `@macroexpand` from Julia 1.7 From 7bde5b7f35ae121cda97f7eebd6d5c6073e0c82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 22 Jan 2025 23:20:52 +0100 Subject: [PATCH 4/9] Works now --- src/Groups/perm.jl | 91 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 928304ec3c7c..5fad6c94066e 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -781,11 +781,6 @@ end # # @perm # -macro perm(ex) - res = _perm_helper(ex) - return esc(:(Oscar.cperm($(res...)))) -end - @doc raw""" @perm expr @@ -811,7 +806,9 @@ symmetric group of degree `n`, i.e., `symmetric_group(n)`, by invoking [`cperm`](@ref) suitably. In the remaining case, the parent group is inferred to be the symmetric group -with a degree of the highest integer referenced in `expr`. +with a degree of the highest integer referenced in `expr`. This may result in +evalutating the expressions in the cycle entries multiple times, so it is +recommended to provide the parent group explicitly in cases of complex expressions. The actual work is done by [`cperm`](@ref). Thus, for the time being, cycles which are *not* disjoint actually are supported. @@ -862,6 +859,83 @@ julia> parent(gens[1]) Sym(14) ``` """ +macro perm(expr) + type, res = _perm_parse(expr) + n = _perm_max_entry(type, res) + return _perm_format(type, n, res) +end + +macro perm(n_or_G, expr) + type, res = _perm_parse(expr) + return _perm_format(type, esc(n_or_G), res) +end + +function _perm_parse(expr::Expr) + # case: expr is a non-empty vector + if expr.head == :vect + @req length(expr.args) > 0 "empty vector not allowed" + return Val(:vector), [esc(:([$(_perm_helper(arg)...)])) for arg in expr.args] + end + + # case: expr is a non-empty tuple of permutations + # to distinguish this from a single cycle (of arbitrary expressions), we walk through + # the expression tree, and look for a place where a tuple is called. + # This never happens inside a single cycle, so this is a safe way to distinguish. + if expr.head == :tuple && length(expr.args) > 0 && expr.args[1] isa Expr + ex = expr.args[1] + while true + if ex.head == :tuple + return Val(:tuple), [esc(:([$(_perm_helper(arg)...)])) for arg in expr.args] + end + if ex.head == :call && ex.args[1] isa Expr + ex = ex.args[1] + else + break + end + end + end + + # otherwise, we have a single permutation + return Val(:single), esc.(_perm_helper(expr)) +end + +function _perm_max_entry(::Val{:single}, res) + return :(mapreduce(maximum, max, [$(res...)]; init=1)) +end + +function _perm_max_entry(::Val{:vector}, res) + return :(mapreduce(x -> mapreduce(maximum, max, x; init=1), max, [$(res...)]; init=1)) +end + +function _perm_max_entry(::Val{:tuple}, res) + return :(mapreduce(x -> mapreduce(maximum, max, x; init=1), max, [$(res...)]; init=1)) +end + +function _perm_format(::Val{:single}, n_or_G, res) + return quote + let n = $(n_or_G), G = n isa Int ? symmetric_group(n) : n + cperm(G, $(res...)) + end + end +end + +function _perm_format(::Val{:vector}, n_or_G, res) + return quote + let n = $(n_or_G), G = n isa Int ? symmetric_group(n) : n + [cperm(G, p...) for p in [$(res...)]] + end + end +end + +function _perm_format(::Val{:tuple}, n_or_G, res) + return quote + let n = $(n_or_G), G = n isa Int ? symmetric_group(n) : n + ((cperm(G, p...) for p in [$(res...)])...,) + end + end +end + +#= macro perm(n,gens) ores = Expr[] @@ -877,6 +951,11 @@ macro perm(n,gens) end end +macro perm(ex) + res = _perm_helper(ex) + return esc(:(Oscar.cperm($(res...)))) +end +=# @doc raw""" permutation_group(n::IntegerUnion, perms::Vector{PermGroupElem}) From 0c1fa59e44d160d26840580f2bee0b451775696d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 22 Jan 2025 23:36:52 +0100 Subject: [PATCH 5/9] Some optimizations --- src/Groups/perm.jl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 5fad6c94066e..fe53d006d413 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -740,7 +740,7 @@ end # # The following code implements a new way to input permutations in Julia. For example # it is possible to create a permutation as follow -# pi = Oscar.Permutations.@perm (1,2,3)(4,5)(6,7,8) +# pi = @perm (1,2,3)(4,5)(6,7,8) # > (1,2,3)(4,5)(6,7,8) # For this we use macros to modify the syntax tree of (1,2,3)(4,5)(6,7,8) such that # Julia can deal with the expression. @@ -757,7 +757,7 @@ function _perm_helper(ex::Expr) Please refer to the docstring of @perm for more information.""") end - res = [] + res = Expr[] while ex isa Expr && ex.head == :call push!(res, Expr(:vect, ex.args[2:end]...)) ex = ex.args[1] @@ -767,7 +767,7 @@ function _perm_helper(ex::Expr) error("Input is not a permutation.") end - push!(res, Expr(:vect,ex.args...)) + push!(res, Expr(:vect, ex.args...)) # reverse `res` to match the original order; this ensures # the evaluation order is as the user expects @@ -903,11 +903,7 @@ function _perm_max_entry(::Val{:single}, res) return :(mapreduce(maximum, max, [$(res...)]; init=1)) end -function _perm_max_entry(::Val{:vector}, res) - return :(mapreduce(x -> mapreduce(maximum, max, x; init=1), max, [$(res...)]; init=1)) -end - -function _perm_max_entry(::Val{:tuple}, res) +function _perm_max_entry(::Union{Val{:vector}, Val{:tuple}}, res) return :(mapreduce(x -> mapreduce(maximum, max, x; init=1), max, [$(res...)]; init=1)) end From 82541c8dbfb070c28f963d74fbfa2bd2f4a786ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 22 Jan 2025 23:46:19 +0100 Subject: [PATCH 6/9] Make doctests work again --- src/Groups/perm.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index fe53d006d413..5c458f15782d 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -815,7 +815,6 @@ cycles which are *not* disjoint actually are supported. # Examples ```jldoctest -```jldoctest julia> x = @perm (1,2,3)(4,5)(factorial(3),7,8) (1,2,3)(4,5)(6,7,8) @@ -872,7 +871,7 @@ end function _perm_parse(expr::Expr) # case: expr is a non-empty vector - if expr.head == :vect + if expr.head == :vect || expr.head == :vcat @req length(expr.args) > 0 "empty vector not allowed" return Val(:vector), [esc(:([$(_perm_helper(arg)...)])) for arg in expr.args] end From 6250f8f5a2c749864180716ffd90641298e468cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 23 Jan 2025 10:38:52 +0100 Subject: [PATCH 7/9] Fix docstring --- src/Groups/perm.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 5c458f15782d..11ad76b291e4 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -801,18 +801,16 @@ raise an error if the permutations are not elements of `G`. If an integer `n` is provided, the permutations are created as elements of the symmetric group of degree `n`, i.e., `symmetric_group(n)`. -Input a list of permutations in cycle notation, created as elements of the -symmetric group of degree `n`, i.e., `symmetric_group(n)`, by invoking -[`cperm`](@ref) suitably. - In the remaining case, the parent group is inferred to be the symmetric group with a degree of the highest integer referenced in `expr`. This may result in -evalutating the expressions in the cycle entries multiple times, so it is +evaluating the expressions in the cycle entries multiple times, so it is recommended to provide the parent group explicitly in cases of complex expressions. The actual work is done by [`cperm`](@ref). Thus, for the time being, cycles which are *not* disjoint actually are supported. +See also [`cperm`](@ref) and [`perm`](@ref) for other ways to create permutations. + # Examples ```jldoctest julia> x = @perm (1,2,3)(4,5)(factorial(3),7,8) From dd9c60f148c924be69c775d9d5b383928c25ff1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 23 Jan 2025 10:47:47 +0100 Subject: [PATCH 8/9] Add `allequal` from `Compat.jl` --- test/Groups/Permutations.jl | 4 ++++ test/Project.toml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/test/Groups/Permutations.jl b/test/Groups/Permutations.jl index 3851e417a629..6e83b6961ab1 100644 --- a/test/Groups/Permutations.jl +++ b/test/Groups/Permutations.jl @@ -1,3 +1,7 @@ +if VERSION < v"1.11.0-DEV.1562" + import Compat: allequal +end + @testset "Examples.Permutations" begin p = @perm (1,2)(3,4)(5,6) @test p == cperm([1,2],[3,4],[5,6]) diff --git a/test/Project.toml b/test/Project.toml index 0de15f378034..c80cadd7072c 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,5 +1,6 @@ [deps] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" DeepDiffs = "ab62b9b5-e342-54a8-a765-a90f495de1a6" Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" @@ -12,6 +13,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] Aqua = "0.8.2" +Compat = "4.13.0" DeepDiffs = "1.2.0" Distributed = "1.6" Documenter = "0.27, 1.0" From 48a6ddfd0baaea5c5c671ed26fb994eb330348b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 23 Jan 2025 13:37:18 +0100 Subject: [PATCH 9/9] Remove old code --- src/Groups/perm.jl | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/Groups/perm.jl b/src/Groups/perm.jl index 11ad76b291e4..b87db02f5e67 100644 --- a/src/Groups/perm.jl +++ b/src/Groups/perm.jl @@ -928,27 +928,6 @@ function _perm_format(::Val{:tuple}, n_or_G, res) end end -#= -macro perm(n,gens) - - ores = Expr[] - for ex in gens.args - res = _perm_helper(ex) - push!(ores, esc(:( [$(res...)] ))) - end - - return quote - let n = $(esc(n)), g = n isa Int ? symmetric_group(n) : n - [ cperm(g, pi...) for pi in [$(ores...)] ] - end - end -end - -macro perm(ex) - res = _perm_helper(ex) - return esc(:(Oscar.cperm($(res...)))) -end -=# @doc raw""" permutation_group(n::IntegerUnion, perms::Vector{PermGroupElem})