mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-11-19 06:30:29 +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
|
end
|
||||||
|
|
||||||
struct PermAut
|
struct PermAut
|
||||||
perm::Generic.Perm{Int8}
|
perm::AbstractAlgebra.Generic.Perm{Int8}
|
||||||
end
|
end
|
||||||
|
|
||||||
struct Identity end
|
struct Identity end
|
||||||
@ -66,7 +66,7 @@ function flip(i::Integer, pow::Integer=1)
|
|||||||
return AutSymbol(id, 1, FlipAut(i))
|
return AutSymbol(id, 1, FlipAut(i))
|
||||||
end
|
end
|
||||||
|
|
||||||
function AutSymbol(p::Generic.Perm, pow::Integer=1)
|
function AutSymbol(p::AbstractAlgebra.Generic.Perm, pow::Integer=1)
|
||||||
if pow != 1
|
if pow != 1
|
||||||
p = p^pow
|
p = p^pow
|
||||||
end
|
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_R(i, j, pow)
|
||||||
λ(i::Integer, j::Integer, pow::Integer=1) = transvection_L(i, j, pow)
|
λ(i::Integer, j::Integer, pow::Integer=1) = transvection_L(i, j, pow)
|
||||||
ε(i::Integer, pow::Integer=1) = flip(i, 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)
|
function change_pow(s::AutSymbol, n::Integer)
|
||||||
iszero(n) && id_autsymbol()
|
iszero(n) && id_autsymbol()
|
||||||
@ -123,8 +123,8 @@ mutable struct Automorphism{N} <: GWord{AutSymbol}
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elem_type(::Type{AutGroup{N}}) where N = Automorphism{N}
|
Base.eltype(::Type{AutGroup{N}}) where N = Automorphism{N}
|
||||||
parent_type(::Type{Automorphism{N}}) where N = AutGroup{N}
|
GroupsCore.parent_type(::Type{Automorphism{N}}) where N = AutGroup{N}
|
||||||
|
|
||||||
function AutGroup(G::FreeGroup; special=false)
|
function AutGroup(G::FreeGroup; special=false)
|
||||||
S = AutSymbol[]
|
S = AutSymbol[]
|
||||||
@ -140,7 +140,7 @@ function AutGroup(G::FreeGroup; special=false)
|
|||||||
|
|
||||||
if !special
|
if !special
|
||||||
flips = [ε(i) for i in 1:n]
|
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])
|
append!(S, [flips; syms])
|
||||||
end
|
end
|
||||||
@ -238,19 +238,19 @@ function compute_images(g::Automorphism)
|
|||||||
return images
|
return images
|
||||||
end
|
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
|
syllables(g) == syllables(h) && return true
|
||||||
img_computed, imh_computed = false, false
|
img_computed, imh_computed = false, false
|
||||||
|
|
||||||
if ismodified(g)
|
if ismodified(g)
|
||||||
img = compute_images(g) # sets modified bit
|
img = compute_images(g) # sets modified bit
|
||||||
hash(g, images=img)
|
hash(g; images=img)
|
||||||
img_computed = true
|
img_computed = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if ismodified(h)
|
if ismodified(h)
|
||||||
imh = compute_images(h) # sets modified bit
|
imh = compute_images(h) # sets modified bit
|
||||||
hash(h, images=imh)
|
hash(h; images=imh)
|
||||||
imh_computed = true
|
imh_computed = true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ end
|
|||||||
# String I/O
|
# 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, "Automorphism Group of $(G.objectGroup)\n")
|
||||||
print(io, "Generated by $(gens(G))")
|
print(io, "Generated by $(gens(G))")
|
||||||
end
|
end
|
||||||
|
@ -29,8 +29,8 @@ export FPGroupElem, FPGroup
|
|||||||
# Type and parent object methods
|
# Type and parent object methods
|
||||||
#
|
#
|
||||||
|
|
||||||
AbstractAlgebra.elem_type(::Type{FPGroup}) = FPGroupElem
|
Base.eltype(::Type{FPGroup}) = FPGroupElem
|
||||||
AbstractAlgebra.parent_type(::Type{FPGroupElem}) = FPGroup
|
GroupsCore.parent_type(::Type{FPGroupElem}) = FPGroup
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -76,7 +76,7 @@ end
|
|||||||
# String I/O
|
# String I/O
|
||||||
#
|
#
|
||||||
|
|
||||||
function show(io::IO, G::FPGroup)
|
function Base.show(io::IO, G::FPGroup)
|
||||||
print(io, "FPgroup on $(length(G.gens)) generators ")
|
print(io, "FPgroup on $(length(G.gens)) generators ")
|
||||||
strrels = join(G.rels, ", ")
|
strrels = join(G.rels, ", ")
|
||||||
if length(strrels) > 200
|
if length(strrels) > 200
|
||||||
|
@ -27,8 +27,8 @@ export FreeGroupElem, FreeGroup
|
|||||||
# Type and parent object methods
|
# Type and parent object methods
|
||||||
#
|
#
|
||||||
|
|
||||||
AbstractAlgebra.elem_type(::Type{FreeGroup}) = FreeGroupElem
|
Base.eltype(::Type{FreeGroup}) = FreeGroupElem
|
||||||
AbstractAlgebra.parent_type(::Type{FreeGroupElem}) = FreeGroup
|
GroupsCore.parent_type(::Type{FreeGroupElem}) = FreeGroup
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -67,7 +67,7 @@ end
|
|||||||
# String I/O
|
# 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: ")
|
print(io, "Free group on $(length(G.gens)) generators: ")
|
||||||
join(io, G.gens, ", ")
|
join(io, G.gens, ", ")
|
||||||
end
|
end
|
||||||
|
@ -1,19 +1,11 @@
|
|||||||
module Groups
|
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 GroupsCore
|
||||||
using LinearAlgebra
|
using LinearAlgebra
|
||||||
using ThreadsX
|
using ThreadsX
|
||||||
|
|
||||||
|
import AbstractAlgebra
|
||||||
|
|
||||||
export gens, FreeGroup, Aut, SAut
|
export gens, FreeGroup, Aut, SAut
|
||||||
|
|
||||||
include("types.jl")
|
include("types.jl")
|
||||||
@ -23,7 +15,6 @@ include("FPGroups.jl")
|
|||||||
include("AutGroup.jl")
|
include("AutGroup.jl")
|
||||||
|
|
||||||
include("symbols.jl")
|
include("symbols.jl")
|
||||||
include("fallbacks.jl")
|
|
||||||
include("words.jl")
|
include("words.jl")
|
||||||
include("hashing.jl")
|
include("hashing.jl")
|
||||||
include("freereduce.jl")
|
include("freereduce.jl")
|
||||||
@ -56,11 +47,7 @@ end
|
|||||||
# Misc
|
# Misc
|
||||||
#
|
#
|
||||||
|
|
||||||
"""
|
GroupsCore.gens(G::AbstractFPGroup) = G.(G.gens)
|
||||||
gens(G::AbstractFPGroups)
|
|
||||||
Return vector of generators of `G`, as its elements.
|
|
||||||
"""
|
|
||||||
AbstractAlgebra.gens(G::AbstractFPGroup) = G.(G.gens)
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wlmetric_ball(S::AbstractVector{<:GroupElem}
|
wlmetric_ball(S::AbstractVector{<:GroupElem}
|
||||||
@ -74,7 +61,7 @@ function wlmetric_ball_serial(
|
|||||||
S::AbstractVector{T};
|
S::AbstractVector{T};
|
||||||
radius = 2,
|
radius = 2,
|
||||||
op = *,
|
op = *,
|
||||||
) where {T<:Union{GroupElem,NCRingElem}}
|
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||||
old = unique!([one(first(S)), S...])
|
old = unique!([one(first(S)), S...])
|
||||||
sizes = [1, length(old)]
|
sizes = [1, length(old)]
|
||||||
for i = 2:radius
|
for i = 2:radius
|
||||||
@ -91,7 +78,7 @@ function wlmetric_ball_thr(
|
|||||||
S::AbstractVector{T};
|
S::AbstractVector{T};
|
||||||
radius = 2,
|
radius = 2,
|
||||||
op = *,
|
op = *,
|
||||||
) where {T<:Union{GroupElem,NCRingElem}}
|
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||||
old = unique!([one(first(S)), S...])
|
old = unique!([one(first(S)), S...])
|
||||||
sizes = [1, length(old)]
|
sizes = [1, length(old)]
|
||||||
for r = 2:radius
|
for r = 2:radius
|
||||||
@ -114,7 +101,7 @@ function wlmetric_ball_serial(
|
|||||||
center::T;
|
center::T;
|
||||||
radius = 2,
|
radius = 2,
|
||||||
op = *,
|
op = *,
|
||||||
) where {T<:Union{GroupElem,NCRingElem}}
|
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||||
E, sizes = wlmetric_ball_serial(S, radius = radius, op = op)
|
E, sizes = wlmetric_ball_serial(S, radius = radius, op = op)
|
||||||
isone(center) && return E, sizes
|
isone(center) && return E, sizes
|
||||||
return c .* E, sizes
|
return c .* E, sizes
|
||||||
@ -125,7 +112,7 @@ function wlmetric_ball_thr(
|
|||||||
center::T;
|
center::T;
|
||||||
radius = 2,
|
radius = 2,
|
||||||
op = *,
|
op = *,
|
||||||
) where {T<:Union{GroupElem,NCRingElem}}
|
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||||
E, sizes = wlmetric_ball_thr(S, radius = radius, op = op)
|
E, sizes = wlmetric_ball_thr(S, radius = radius, op = op)
|
||||||
isone(center) && return E, sizes
|
isone(center) && return E, sizes
|
||||||
return c .* E, sizes
|
return c .* E, sizes
|
||||||
@ -137,7 +124,7 @@ function wlmetric_ball(
|
|||||||
radius = 2,
|
radius = 2,
|
||||||
op = *,
|
op = *,
|
||||||
threading = true,
|
threading = true,
|
||||||
) where {T<:Union{GroupElem,NCRingElem}}
|
) where {T<:Union{GroupElement,AbstractAlgebra.NCRingElem}}
|
||||||
threading && return wlmetric_ball_thr(S, center, radius = radius, op = op)
|
threading && return wlmetric_ball_thr(S, center, radius = radius, op = op)
|
||||||
return return wlmetric_ball_serial(S, center, radius = radius, op = op)
|
return return wlmetric_ball_serial(S, center, radius = radius, op = op)
|
||||||
end
|
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)
|
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)
|
Base.:(*)(W::GW, Z::GW) where GW <: GWord = rmul!(deepcopy(W), W, Z)
|
||||||
(*)(W::GWord, s::GSymbol) = freereduce!(push!(deepcopy(W), s))
|
Base.:(*)(W::GWord, s::GSymbol) = freereduce!(push!(deepcopy(W), s))
|
||||||
(*)(s::GSymbol, W::GWord) = freereduce!(pushfirst!(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
|
if p < 0
|
||||||
return power_by_squaring(inv(W), -p)
|
return Base.power_by_squaring(inv(W), -p)
|
||||||
elseif p == 0
|
elseif p == 0
|
||||||
return one(W)
|
return one(W)
|
||||||
elseif p == 1
|
elseif p == 1
|
||||||
@ -90,4 +90,4 @@ function power_by_squaring(W::GWord, p::Integer)
|
|||||||
return freereduce!(Z)
|
return freereduce!(Z)
|
||||||
end
|
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
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
"""doc
|
"""
|
||||||
|
|
||||||
Find the first syllable index k>=i such that Z < syllables(W)[k:k+syllablelength(Z)-1]
|
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))
|
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||||
isempty(subword) && return start
|
isempty(subword) && return start
|
||||||
stop = syllablelength(word) - syllablelength(subword) +1
|
stop = syllablelength(word) - syllablelength(subword) +1
|
||||||
@ -42,7 +43,7 @@ function findnext(subword::GWord, word::GWord, start::Integer)
|
|||||||
return nothing
|
return nothing
|
||||||
end
|
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))
|
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||||
isone(s) && return start
|
isone(s) && return start
|
||||||
stop = syllablelength(word)
|
stop = syllablelength(word)
|
||||||
@ -53,7 +54,7 @@ function findnext(s::FreeSymbol, word::GWord, start::Integer)
|
|||||||
return nothing
|
return nothing
|
||||||
end
|
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))
|
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||||
isempty(subword) && return start
|
isempty(subword) && return start
|
||||||
stop = 1
|
stop = 1
|
||||||
@ -64,7 +65,7 @@ function findprev(subword::GWord, word::GWord, start::Integer)
|
|||||||
return nothing
|
return nothing
|
||||||
end
|
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))
|
@boundscheck 1 ≤ start ≤ syllablelength(word) || throw(BoundsError(word, start))
|
||||||
isone(s) && return start
|
isone(s) && return start
|
||||||
stop = 1
|
stop = 1
|
||||||
@ -75,11 +76,11 @@ function findprev(s::FreeSymbol, word::GWord, start::Integer)
|
|||||||
return nothing
|
return nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
findfirst(subword::GWord, word::GWord) = findnext(subword, word, 1)
|
Base.findfirst(subword::GWord, word::GWord) = findnext(subword, word, 1)
|
||||||
findlast(subword::GWord, word::GWord) =
|
Base.findlast(subword::GWord, word::GWord) =
|
||||||
findprev(subword, word, syllablelength(word)-syllablelength(subword)+1)
|
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}
|
{GS<:GSymbol, T<:GWord, GW<:GWord}
|
||||||
(count == 0 || isempty(W)) && return W
|
(count == 0 || isempty(W)) && return W
|
||||||
count < 0 && throw(DomainError(count, "`count` must be non-negative."))
|
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)
|
return freereduce!(out)
|
||||||
end
|
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}
|
{GW<:GWord, T <: GWord}
|
||||||
(count == 0 || isempty(W)) && return W
|
(count == 0 || isempty(W)) && return W
|
||||||
count < 0 && throw(DomainError(count, "`count` must be non-negative."))
|
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)
|
return freereduce!(out)
|
||||||
end
|
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}
|
{GW<:GWord, T <: GWord}
|
||||||
return replace!(one(W), W, lhs_rhs; count=count)
|
return replace!(one(W), W, lhs_rhs; count=count)
|
||||||
end
|
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
|
out = W
|
||||||
for toreplace in reverse!(sort!(collect(keys(subst_dict)), by=length))
|
for toreplace in reverse!(sort!(collect(keys(subst_dict)), by=length))
|
||||||
replacement = subst_dict[toreplace]
|
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.
|
The default reduction is the reduction in the free group reduction.
|
||||||
More specific procedures should be dispatched on `GWord`s type parameter.
|
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))
|
return hash(syllables(W), hash(typeof(W), h))
|
||||||
end
|
end
|
||||||
|
|
||||||
function hash(W::GWord, h::UInt=UInt(0); kwargs...)
|
function Base.hash(W::GWord, h::UInt=UInt(0); kwargs...)
|
||||||
if ismodified(W)
|
if ismodified(W)
|
||||||
savehash!(W, hash_internal(W; kwargs...))
|
savehash!(W, hash_internal(W; kwargs...))
|
||||||
unsetmodified!(W)
|
unsetmodified!(W)
|
||||||
@ -25,7 +25,7 @@ function Base.deepcopy_internal(W::T, dict::IdDict) where T<:GWord
|
|||||||
return g
|
return g
|
||||||
end
|
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
|
hash(W) != hash(Z) && return false # distinguishes parent and parentless words
|
||||||
if hasparent(W) && hasparent(Z)
|
if hasparent(W) && hasparent(Z)
|
||||||
parent(W) != parent(Z) && return false
|
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.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)))
|
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
|
isone(s) && isone(t) && return true
|
||||||
s.pow == t.pow && s.id == t.id && return true
|
s.pow == t.pow && s.id == t.id && return true
|
||||||
return false
|
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
|
Represents a syllable. Abstract type which all group symbols of
|
||||||
`AbstractFPGroups` should subtype. Each concrete subtype should implement fields:
|
`AbstractFPGroups` should subtype. Each concrete subtype should implement fields:
|
||||||
* `id` which is the `Symbol` representation/identification of a symbol
|
* `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 GSymbol end
|
||||||
|
|
||||||
abstract type GWord{T<:GSymbol} <: GroupElem end
|
abstract type GWord{T<:GSymbol} <: GroupsCore.GroupElement end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
W::GroupWord{T} <: GWord{T<:GSymbol} <:GroupElem
|
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)
|
unsetmodified!(w::GWord) = (w.modified = false; w)
|
||||||
savehash!(w::GWord, h::UInt) = (w.savedhash = h; w)
|
savehash!(w::GWord, h::UInt) = (w.savedhash = h; w)
|
||||||
savedhash(w::GWord) = w.savedhash
|
savedhash(w::GWord) = w.savedhash
|
||||||
parent(w::GWord) = w.parent
|
Base.parent(w::GWord) = w.parent
|
||||||
hasparent(w::GWord) = isdefined(w, :parent)
|
hasparent(w::GWord) = isdefined(w, :parent)
|
||||||
setparent!(w::GWord, G::AbstractFPGroup) = (w.parent = G; w)
|
setparent!(w::GWord, G::AbstractFPGroup) = (w.parent = G; w)
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import AbstractAlgebra.@perm_str
|
||||||
|
|
||||||
@testset "Automorphisms" begin
|
@testset "Automorphisms" begin
|
||||||
|
|
||||||
G = SymmetricGroup(Int8(4))
|
G = AbstractAlgebra.SymmetricGroup(Int8(4))
|
||||||
|
|
||||||
@testset "AutSymbol" begin
|
@testset "AutSymbol" begin
|
||||||
@test_throws MethodError Groups.AutSymbol(:a)
|
@test_throws MethodError Groups.AutSymbol(:a)
|
||||||
@ -91,7 +93,7 @@
|
|||||||
f = Groups.AutSymbol(:a, 1, Groups.FlipAut(1))
|
f = Groups.AutSymbol(:a, 1, Groups.FlipAut(1))
|
||||||
@test isa(Automorphism{3}(f), Groups.GWord)
|
@test isa(Automorphism{3}(f), Groups.GWord)
|
||||||
@test isa(Automorphism{3}(f), Automorphism)
|
@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)
|
@test isa(AutGroup(FreeGroup(1)), Groups.AbstractFPGroup)
|
||||||
|
|
||||||
A = AutGroup(FreeGroup(1))
|
A = AutGroup(FreeGroup(1))
|
||||||
|
@ -42,7 +42,7 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
@testset "FreeGroup" begin
|
@testset "FreeGroup" begin
|
||||||
@test isa(FreeGroup(["s", "t"]), AbstractAlgebra.Group)
|
@test isa(FreeGroup(["s", "t"]), GroupsCore.Group)
|
||||||
G = FreeGroup(["s", "t"])
|
G = FreeGroup(["s", "t"])
|
||||||
s, t = gens(G)
|
s, t = gens(G)
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ end
|
|||||||
w = deepcopy(t)
|
w = deepcopy(t)
|
||||||
@test length(Groups.rmul!(w, t)) == 2
|
@test length(Groups.rmul!(w, t)) == 2
|
||||||
@test length(Groups.lmul!(w, inv(t))) == 1
|
@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(w) == 2
|
||||||
@test length(Groups.lmul!(w, inv(s))) == 3
|
@test length(Groups.lmul!(w, inv(s))) == 3
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
using Test
|
using Test
|
||||||
using AbstractAlgebra
|
import AbstractAlgebra
|
||||||
using Groups
|
using Groups
|
||||||
|
|
||||||
|
include("symmetric.jl")
|
||||||
using LinearAlgebra
|
using LinearAlgebra
|
||||||
|
|
||||||
@testset "Groups" begin
|
@testset "Groups" begin
|
||||||
|
|
||||||
@testset "wlmetric_ball" begin
|
@testset "wlmetric_ball" begin
|
||||||
M = MatrixAlgebra(zz, 3)
|
M = AbstractAlgebra.MatrixAlgebra(AbstractAlgebra.zz, 3)
|
||||||
w = one(M); w[1,2] = 1;
|
w = one(M); w[1,2] = 1;
|
||||||
r = one(M); r[2,3] = -3;
|
r = one(M); r[2,3] = -3;
|
||||||
s = one(M); s[1,3] = 2; s[3,2] = -1;
|
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