mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-12-25 02:05:30 +01:00
sort out imports + first adjustments to Group Interface
This commit is contained in:
parent
990c8dd1c3
commit
711988b98a
@ -20,7 +20,7 @@ struct FlipAut
|
||||
end
|
||||
|
||||
struct PermAut
|
||||
perm::Generic.Perm{Int8}
|
||||
perm::AbstractAlgebra.Generic.Perm{Int8}
|
||||
end
|
||||
|
||||
struct Identity end
|
||||
@ -66,7 +66,7 @@ function flip(i::Integer, pow::Integer=1)
|
||||
return AutSymbol(id, 1, FlipAut(i))
|
||||
end
|
||||
|
||||
function AutSymbol(p::Generic.Perm, pow::Integer=1)
|
||||
function AutSymbol(p::AbstractAlgebra.Generic.Perm, pow::Integer=1)
|
||||
if pow != 1
|
||||
p = p^pow
|
||||
end
|
||||
@ -81,7 +81,7 @@ end
|
||||
ϱ(i::Integer, j::Integer, pow::Integer=1) = transvection_R(i, j, pow)
|
||||
λ(i::Integer, j::Integer, pow::Integer=1) = transvection_L(i, j, pow)
|
||||
ε(i::Integer, pow::Integer=1) = flip(i, pow)
|
||||
σ(v::Generic.Perm, pow::Integer=1) = AutSymbol(v, pow)
|
||||
σ(v::AbstractAlgebra.Generic.Perm, pow::Integer=1) = AutSymbol(v, pow)
|
||||
|
||||
function change_pow(s::AutSymbol, n::Integer)
|
||||
iszero(n) && id_autsymbol()
|
||||
@ -123,8 +123,8 @@ mutable struct Automorphism{N} <: GWord{AutSymbol}
|
||||
end
|
||||
end
|
||||
|
||||
elem_type(::Type{AutGroup{N}}) where N = Automorphism{N}
|
||||
parent_type(::Type{Automorphism{N}}) where N = AutGroup{N}
|
||||
Base.eltype(::Type{AutGroup{N}}) where N = Automorphism{N}
|
||||
GroupsCore.parent_type(::Type{Automorphism{N}}) where N = AutGroup{N}
|
||||
|
||||
function AutGroup(G::FreeGroup; special=false)
|
||||
S = AutSymbol[]
|
||||
@ -140,7 +140,7 @@ function AutGroup(G::FreeGroup; special=false)
|
||||
|
||||
if !special
|
||||
flips = [ε(i) for i in 1:n]
|
||||
syms = [σ(p) for p in SymmetricGroup(Int8(n))][2:end]
|
||||
syms = [σ(p) for p in AbstractAlgebra.SymmetricGroup(Int8(n))][2:end]
|
||||
|
||||
append!(S, [flips; syms])
|
||||
end
|
||||
@ -238,19 +238,19 @@ function compute_images(g::Automorphism)
|
||||
return images
|
||||
end
|
||||
|
||||
function (==)(g::Automorphism{N}, h::Automorphism{N}) where N
|
||||
function Base.:(==)(g::Automorphism{N}, h::Automorphism{N}) where N
|
||||
syllables(g) == syllables(h) && return true
|
||||
img_computed, imh_computed = false, false
|
||||
|
||||
if ismodified(g)
|
||||
img = compute_images(g) # sets modified bit
|
||||
hash(g, images=img)
|
||||
hash(g; images=img)
|
||||
img_computed = true
|
||||
end
|
||||
|
||||
if ismodified(h)
|
||||
imh = compute_images(h) # sets modified bit
|
||||
hash(h, images=imh)
|
||||
hash(h; images=imh)
|
||||
imh_computed = true
|
||||
end
|
||||
|
||||
@ -282,7 +282,7 @@ end
|
||||
# String I/O
|
||||
#
|
||||
|
||||
function show(io::IO, G::AutGroup)
|
||||
function Base.show(io::IO, G::AutGroup)
|
||||
print(io, "Automorphism Group of $(G.objectGroup)\n")
|
||||
print(io, "Generated by $(gens(G))")
|
||||
end
|
||||
|
@ -29,8 +29,8 @@ export FPGroupElem, FPGroup
|
||||
# Type and parent object methods
|
||||
#
|
||||
|
||||
AbstractAlgebra.elem_type(::Type{FPGroup}) = FPGroupElem
|
||||
AbstractAlgebra.parent_type(::Type{FPGroupElem}) = FPGroup
|
||||
Base.eltype(::Type{FPGroup}) = FPGroupElem
|
||||
GroupsCore.parent_type(::Type{FPGroupElem}) = FPGroup
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -76,7 +76,7 @@ end
|
||||
# String I/O
|
||||
#
|
||||
|
||||
function show(io::IO, G::FPGroup)
|
||||
function Base.show(io::IO, G::FPGroup)
|
||||
print(io, "FPgroup on $(length(G.gens)) generators ")
|
||||
strrels = join(G.rels, ", ")
|
||||
if length(strrels) > 200
|
||||
|
@ -27,8 +27,8 @@ export FreeGroupElem, FreeGroup
|
||||
# Type and parent object methods
|
||||
#
|
||||
|
||||
AbstractAlgebra.elem_type(::Type{FreeGroup}) = FreeGroupElem
|
||||
AbstractAlgebra.parent_type(::Type{FreeGroupElem}) = FreeGroup
|
||||
Base.eltype(::Type{FreeGroup}) = FreeGroupElem
|
||||
GroupsCore.parent_type(::Type{FreeGroupElem}) = FreeGroup
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -67,7 +67,7 @@ end
|
||||
# String I/O
|
||||
#
|
||||
|
||||
function show(io::IO, G::FreeGroup)
|
||||
function Base.show(io::IO, G::FreeGroup)
|
||||
print(io, "Free group on $(length(G.gens)) generators: ")
|
||||
join(io, G.gens, ", ")
|
||||
end
|
||||
|
@ -1,19 +1,11 @@
|
||||
module Groups
|
||||
|
||||
using AbstractAlgebra
|
||||
import AbstractAlgebra: Group, GroupElem, Ring
|
||||
import AbstractAlgebra: parent, parent_type, elem_type
|
||||
import AbstractAlgebra: order, gens, matrix_repr
|
||||
|
||||
import Base: length, ==, hash, show, convert, eltype, iterate
|
||||
import Base: inv, reduce, *, ^, power_by_squaring
|
||||
import Base: findfirst, findnext, findlast, findprev, replace
|
||||
import Base: deepcopy_internal
|
||||
|
||||
using GroupsCore
|
||||
using LinearAlgebra
|
||||
using ThreadsX
|
||||
|
||||
import AbstractAlgebra
|
||||
|
||||
export gens, FreeGroup, Aut, SAut
|
||||
|
||||
include("types.jl")
|
||||
@ -23,7 +15,6 @@ include("FPGroups.jl")
|
||||
include("AutGroup.jl")
|
||||
|
||||
include("symbols.jl")
|
||||
include("fallbacks.jl")
|
||||
include("words.jl")
|
||||
include("hashing.jl")
|
||||
include("freereduce.jl")
|
||||
@ -56,11 +47,7 @@ end
|
||||
# Misc
|
||||
#
|
||||
|
||||
"""
|
||||
gens(G::AbstractFPGroups)
|
||||
Return vector of generators of `G`, as its elements.
|
||||
"""
|
||||
AbstractAlgebra.gens(G::AbstractFPGroup) = G.(G.gens)
|
||||
GroupsCore.gens(G::AbstractFPGroup) = G.(G.gens)
|
||||
|
||||
"""
|
||||
wlmetric_ball(S::AbstractVector{<:GroupElem}
|
||||
@ -74,7 +61,7 @@ function wlmetric_ball_serial(
|
||||
S::AbstractVector{T};
|
||||
radius = 2,
|
||||
op = *,
|
||||
) where {T<:Union{GroupElem,NCRingElem}}
|
||||
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||
old = unique!([one(first(S)), S...])
|
||||
sizes = [1, length(old)]
|
||||
for i = 2:radius
|
||||
@ -91,7 +78,7 @@ function wlmetric_ball_thr(
|
||||
S::AbstractVector{T};
|
||||
radius = 2,
|
||||
op = *,
|
||||
) where {T<:Union{GroupElem,NCRingElem}}
|
||||
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||
old = unique!([one(first(S)), S...])
|
||||
sizes = [1, length(old)]
|
||||
for r = 2:radius
|
||||
@ -114,7 +101,7 @@ function wlmetric_ball_serial(
|
||||
center::T;
|
||||
radius = 2,
|
||||
op = *,
|
||||
) where {T<:Union{GroupElem,NCRingElem}}
|
||||
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||
E, sizes = wlmetric_ball_serial(S, radius = radius, op = op)
|
||||
isone(center) && return E, sizes
|
||||
return c .* E, sizes
|
||||
@ -125,7 +112,7 @@ function wlmetric_ball_thr(
|
||||
center::T;
|
||||
radius = 2,
|
||||
op = *,
|
||||
) where {T<:Union{GroupElem,NCRingElem}}
|
||||
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||
E, sizes = wlmetric_ball_thr(S, radius = radius, op = op)
|
||||
isone(center) && return E, sizes
|
||||
return c .* E, sizes
|
||||
@ -137,7 +124,7 @@ function wlmetric_ball(
|
||||
radius = 2,
|
||||
op = *,
|
||||
threading = true,
|
||||
) where {T<:Union{GroupElem,NCRingElem}}
|
||||
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||
threading && return wlmetric_ball_thr(S, center, radius = radius, op = op)
|
||||
return return wlmetric_ball_serial(S, center, radius = radius, op = op)
|
||||
end
|
||||
|
@ -55,15 +55,15 @@ lmul!(out::T, v::T) where T<:GWord = freereduce!(prepend!(out, v))
|
||||
|
||||
lmul!(out::T, x::T, y::T) where T <: GWord = rmul!(out, y, x)
|
||||
|
||||
AbstractAlgebra.mul!(out::T, x::T, y::T) where T <: GWord = rmul!(out, x, y)
|
||||
GroupsCore.mul!(out::T, x::T, y::T) where T <: GWord = rmul!(out, x, y)
|
||||
|
||||
(*)(W::GW, Z::GW) where GW <: GWord = rmul!(deepcopy(W), W, Z)
|
||||
(*)(W::GWord, s::GSymbol) = freereduce!(push!(deepcopy(W), s))
|
||||
(*)(s::GSymbol, W::GWord) = freereduce!(pushfirst!(deepcopy(W), s))
|
||||
Base.:(*)(W::GW, Z::GW) where GW <: GWord = rmul!(deepcopy(W), W, Z)
|
||||
Base.:(*)(W::GWord, s::GSymbol) = freereduce!(push!(deepcopy(W), s))
|
||||
Base.:(*)(s::GSymbol, W::GWord) = freereduce!(pushfirst!(deepcopy(W), s))
|
||||
|
||||
function power_by_squaring(W::GWord, p::Integer)
|
||||
function Base.power_by_squaring(W::GWord, p::Integer)
|
||||
if p < 0
|
||||
return power_by_squaring(inv(W), -p)
|
||||
return Base.power_by_squaring(inv(W), -p)
|
||||
elseif p == 0
|
||||
return one(W)
|
||||
elseif p == 1
|
||||
@ -90,4 +90,4 @@ function power_by_squaring(W::GWord, p::Integer)
|
||||
return freereduce!(Z)
|
||||
end
|
||||
|
||||
(^)(x::GWord, n::Integer) = power_by_squaring(x,n)
|
||||
Base.:(^)(x::GWord, n::Integer) = Base.power_by_squaring(x,n)
|
||||
|
@ -1,16 +0,0 @@
|
||||
# workarounds
|
||||
Base.one(G::Generic.SymmetricGroup) = Generic.Perm(G.n)
|
||||
|
||||
# fallback definitions
|
||||
# note: the user should implement those on type, when possible
|
||||
Base.eltype(w::GW) where GW<:GWord = eltype(GW)
|
||||
AbstractAlgebra.elem_type(G::Gr) where Gr <:AbstractFPGroup = elem_type(Gr)
|
||||
|
||||
AbstractAlgebra.parent_type(g::Gw) where Gw <:GWord = parent_type(parent(Gr))
|
||||
|
||||
function Base.one(G::Gr) where Gr <: AbstractFPGroup
|
||||
El = elem_type(G)
|
||||
id = El(eltype(El)[])
|
||||
id.parent = G
|
||||
return id
|
||||
end
|
@ -28,10 +28,11 @@ function issubword(z::GWord, w::GWord, sindex::Integer)
|
||||
return true
|
||||
end
|
||||
|
||||
"""doc
|
||||
"""
|
||||
|
||||
Find the first syllable index k>=i such that Z < syllables(W)[k:k+syllablelength(Z)-1]
|
||||
"""
|
||||
function findnext(subword::GWord, word::GWord, start::Integer)
|
||||
function Base.findnext(subword::GWord, word::GWord, start::Integer)
|
||||
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||
isempty(subword) && return start
|
||||
stop = syllablelength(word) - syllablelength(subword) +1
|
||||
@ -42,7 +43,7 @@ function findnext(subword::GWord, word::GWord, start::Integer)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function findnext(s::FreeSymbol, word::GWord, start::Integer)
|
||||
function Base.findnext(s::FreeSymbol, word::GWord, start::Integer)
|
||||
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||
isone(s) && return start
|
||||
stop = syllablelength(word)
|
||||
@ -53,7 +54,7 @@ function findnext(s::FreeSymbol, word::GWord, start::Integer)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function findprev(subword::GWord, word::GWord, start::Integer)
|
||||
function Base.findprev(subword::GWord, word::GWord, start::Integer)
|
||||
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||
isempty(subword) && return start
|
||||
stop = 1
|
||||
@ -64,7 +65,7 @@ function findprev(subword::GWord, word::GWord, start::Integer)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function findprev(s::FreeSymbol, word::GWord, start::Integer)
|
||||
function Base.findprev(s::FreeSymbol, word::GWord, start::Integer)
|
||||
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||
isone(s) && return start
|
||||
stop = 1
|
||||
@ -75,11 +76,11 @@ function findprev(s::FreeSymbol, word::GWord, start::Integer)
|
||||
return nothing
|
||||
end
|
||||
|
||||
findfirst(subword::GWord, word::GWord) = findnext(subword, word, 1)
|
||||
findlast(subword::GWord, word::GWord) =
|
||||
Base.findfirst(subword::GWord, word::GWord) = findnext(subword, word, 1)
|
||||
Base.findlast(subword::GWord, word::GWord) =
|
||||
findprev(subword, word, syllablelength(word)-syllablelength(subword)+1)
|
||||
|
||||
function replace!(out::GW, W::GW, lhs_rhs::Pair{GS, T}; count::Integer=typemax(Int)) where
|
||||
function Base.replace!(out::GW, W::GW, lhs_rhs::Pair{GS, T}; count::Integer=typemax(Int)) where
|
||||
{GS<:GSymbol, T<:GWord, GW<:GWord}
|
||||
(count == 0 || isempty(W)) && return W
|
||||
count < 0 && throw(DomainError(count, "`count` must be non-negative."))
|
||||
@ -117,7 +118,7 @@ function replace!(out::GW, W::GW, lhs_rhs::Pair{GS, T}; count::Integer=typemax(I
|
||||
return freereduce!(out)
|
||||
end
|
||||
|
||||
function replace!(out::GW, W::GW, lhs_rhs::Pair{T, T}; count::Integer=typemax(Int)) where
|
||||
function Base.replace!(out::GW, W::GW, lhs_rhs::Pair{T, T}; count::Integer=typemax(Int)) where
|
||||
{GW<:GWord, T <: GWord}
|
||||
(count == 0 || isempty(W)) && return W
|
||||
count < 0 && throw(DomainError(count, "`count` must be non-negative."))
|
||||
@ -164,12 +165,12 @@ function replace!(out::GW, W::GW, lhs_rhs::Pair{T, T}; count::Integer=typemax(In
|
||||
return freereduce!(out)
|
||||
end
|
||||
|
||||
function replace(W::GW, lhs_rhs::Pair{T, T}; count::Integer=typemax(Int)) where
|
||||
function Base.replace(W::GW, lhs_rhs::Pair{T, T}; count::Integer=typemax(Int)) where
|
||||
{GW<:GWord, T <: GWord}
|
||||
return replace!(one(W), W, lhs_rhs; count=count)
|
||||
end
|
||||
|
||||
function replace(W::GW, subst_dict::Dict{T,T}) where {GW<:GWord, T<:GWord}
|
||||
function Base.replace(W::GW, subst_dict::Dict{T,T}) where {GW<:GWord, T<:GWord}
|
||||
out = W
|
||||
for toreplace in reverse!(sort!(collect(keys(subst_dict)), by=length))
|
||||
replacement = subst_dict[toreplace]
|
||||
|
@ -46,4 +46,4 @@ performs reduction/simplification of a group element (word in generators).
|
||||
The default reduction is the reduction in the free group reduction.
|
||||
More specific procedures should be dispatched on `GWord`s type parameter.
|
||||
"""
|
||||
reduce(w::GWord) = reduce!(deepcopy(w))
|
||||
Base.reduce(w::GWord) = reduce!(deepcopy(w))
|
||||
|
@ -9,7 +9,7 @@ function hash_internal(W::GWord)
|
||||
return hash(syllables(W), hash(typeof(W), h))
|
||||
end
|
||||
|
||||
function hash(W::GWord, h::UInt=UInt(0); kwargs...)
|
||||
function Base.hash(W::GWord, h::UInt=UInt(0); kwargs...)
|
||||
if ismodified(W)
|
||||
savehash!(W, hash_internal(W; kwargs...))
|
||||
unsetmodified!(W)
|
||||
@ -25,7 +25,7 @@ function Base.deepcopy_internal(W::T, dict::IdDict) where T<:GWord
|
||||
return g
|
||||
end
|
||||
|
||||
function (==)(W::T, Z::T) where T <: GWord
|
||||
function Base.:(==)(W::T, Z::T) where T <: GWord
|
||||
hash(W) != hash(Z) && return false # distinguishes parent and parentless words
|
||||
if hasparent(W) && hasparent(Z)
|
||||
parent(W) != parent(Z) && return false
|
||||
|
@ -12,7 +12,7 @@ Base.isone(s::GSymbol) = iszero(s.pow)
|
||||
Base.inv(s::GSymbol) = change_pow(s, -s.pow)
|
||||
Base.hash(s::S, h::UInt) where S<:GSymbol = hash(s.id, hash(s.pow, hash(S, h)))
|
||||
|
||||
function (==)(s::GSymbol, t::GSymbol)
|
||||
function Base.:(==)(s::GSymbol, t::GSymbol)
|
||||
isone(s) && isone(t) && return true
|
||||
s.pow == t.pow && s.id == t.id && return true
|
||||
return false
|
||||
|
13
src/types.jl
13
src/types.jl
@ -1,7 +1,14 @@
|
||||
abstract type AbstractFPGroup <: Group end
|
||||
abstract type AbstractFPGroup <: GroupsCore.Group end
|
||||
|
||||
function Base.one(G::Gr) where Gr <: AbstractFPGroup
|
||||
El = eltype(G)
|
||||
id = El(eltype(El)[])
|
||||
id.parent = G
|
||||
return id
|
||||
end
|
||||
|
||||
"""
|
||||
::GSymbol
|
||||
GSymbol
|
||||
Represents a syllable. Abstract type which all group symbols of
|
||||
`AbstractFPGroups` should subtype. Each concrete subtype should implement fields:
|
||||
* `id` which is the `Symbol` representation/identification of a symbol
|
||||
@ -9,7 +16,7 @@ Represents a syllable. Abstract type which all group symbols of
|
||||
"""
|
||||
abstract type GSymbol end
|
||||
|
||||
abstract type GWord{T<:GSymbol} <: GroupElem end
|
||||
abstract type GWord{T<:GSymbol} <: GroupsCore.GroupElement end
|
||||
|
||||
"""
|
||||
W::GroupWord{T} <: GWord{T<:GSymbol} <:GroupElem
|
||||
|
@ -5,7 +5,7 @@ setmodified!(w::GWord) = (w.modified = true; w)
|
||||
unsetmodified!(w::GWord) = (w.modified = false; w)
|
||||
savehash!(w::GWord, h::UInt) = (w.savedhash = h; w)
|
||||
savedhash(w::GWord) = w.savedhash
|
||||
parent(w::GWord) = w.parent
|
||||
Base.parent(w::GWord) = w.parent
|
||||
hasparent(w::GWord) = isdefined(w, :parent)
|
||||
setparent!(w::GWord, G::AbstractFPGroup) = (w.parent = G; w)
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import AbstractAlgebra.@perm_str
|
||||
|
||||
@testset "Automorphisms" begin
|
||||
|
||||
G = SymmetricGroup(Int8(4))
|
||||
G = AbstractAlgebra.SymmetricGroup(Int8(4))
|
||||
|
||||
@testset "AutSymbol" begin
|
||||
@test_throws MethodError Groups.AutSymbol(:a)
|
||||
@ -91,7 +93,7 @@
|
||||
f = Groups.AutSymbol(:a, 1, Groups.FlipAut(1))
|
||||
@test isa(Automorphism{3}(f), Groups.GWord)
|
||||
@test isa(Automorphism{3}(f), Automorphism)
|
||||
@test isa(AutGroup(FreeGroup(3)), AbstractAlgebra.Group)
|
||||
@test isa(AutGroup(FreeGroup(3)), GroupsCore.Group)
|
||||
@test isa(AutGroup(FreeGroup(1)), Groups.AbstractFPGroup)
|
||||
|
||||
A = AutGroup(FreeGroup(1))
|
||||
|
@ -42,7 +42,7 @@ end
|
||||
end
|
||||
|
||||
@testset "FreeGroup" begin
|
||||
@test isa(FreeGroup(["s", "t"]), AbstractAlgebra.Group)
|
||||
@test isa(FreeGroup(["s", "t"]), GroupsCore.Group)
|
||||
G = FreeGroup(["s", "t"])
|
||||
s, t = gens(G)
|
||||
|
||||
@ -87,7 +87,7 @@ end
|
||||
w = deepcopy(t)
|
||||
@test length(Groups.rmul!(w, t)) == 2
|
||||
@test length(Groups.lmul!(w, inv(t))) == 1
|
||||
w = AbstractAlgebra.mul!(w, w, s)
|
||||
w = GroupsCore.mul!(w, w, s)
|
||||
@test length(w) == 2
|
||||
@test length(Groups.lmul!(w, inv(s))) == 3
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
using Test
|
||||
using AbstractAlgebra
|
||||
import AbstractAlgebra
|
||||
using Groups
|
||||
|
||||
include("symmetric.jl")
|
||||
using LinearAlgebra
|
||||
|
||||
@testset "Groups" begin
|
||||
|
||||
@testset "wlmetric_ball" begin
|
||||
M = MatrixAlgebra(zz, 3)
|
||||
M = AbstractAlgebra.MatrixAlgebra(AbstractAlgebra.zz, 3)
|
||||
w = one(M); w[1,2] = 1;
|
||||
r = one(M); r[2,3] = -3;
|
||||
s = one(M); s[1,3] = 2; s[3,2] = -1;
|
||||
|
31
test/symmetric.jl
Normal file
31
test/symmetric.jl
Normal file
@ -0,0 +1,31 @@
|
||||
import AbstractAlgebra
|
||||
using GroupsCore
|
||||
|
||||
# disambiguation
|
||||
GroupsCore.order(
|
||||
::Type{I},
|
||||
G::AbstractAlgebra.Generic.SymmetricGroup,
|
||||
) where {I<:Integer} = I(factorial(G.n))
|
||||
|
||||
# disambiguation
|
||||
GroupsCore.order(
|
||||
::Type{I},
|
||||
g::AbstractAlgebra.Generic.Perm,
|
||||
) where {I<:Integer} =
|
||||
I(foldl(lcm, length(c) for c in AbstractAlgebra.cycles(g)))
|
||||
|
||||
# correct the AA length:
|
||||
Base.length(G::AbstractAlgebra.Generic.SymmetricGroup) = order(Int, G)
|
||||
|
||||
# genuinely new methods:
|
||||
Base.IteratorSize(::Type{<:AbstractAlgebra.AbstractPermutationGroup}) = Base.HasLength()
|
||||
|
||||
function GroupsCore.gens(G::AbstractAlgebra.Generic.SymmetricGroup{I}) where {I}
|
||||
a, b = one(G), one(G)
|
||||
circshift!(a.d, b.d, -1)
|
||||
b.d[1], b.d[2] = 2, 1
|
||||
return [a, b]
|
||||
end
|
||||
|
||||
Base.deepcopy_internal(g::AbstractAlgebra.Generic.Perm, ::IdDict) =
|
||||
AbstractAlgebra.Generic.Perm(deepcopy(g.d), false)
|
Loading…
Reference in New Issue
Block a user