From f883b5172e2b0e522dcea783313b3465e0c2bc61 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 11 Dec 2021 13:53:17 +0100 Subject: [PATCH 1/5] use equality_data for checking == (defaults to word) --- src/types.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 4dcec05..a7464ee 100644 --- a/src/types.jl +++ b/src/types.jl @@ -90,7 +90,7 @@ function Base.:(==)(g::AbstractFPGroupElement, h::AbstractFPGroupElement) normalform!(g) normalform!(h) hash(g) != hash(h) && return false - return word(g) == word(h) + return equality_data(g) == equality_data(h) end function Base.deepcopy_internal(g::FPGroupElement, stackdict::IdDict) From 70bd59e9b98a69ec78cd69dcd45948e4aef4fe9c Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 11 Dec 2021 13:55:31 +0100 Subject: [PATCH 2/5] shorten printing of types --- src/types.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/types.jl b/src/types.jl index a7464ee..7a23eee 100644 --- a/src/types.jl +++ b/src/types.jl @@ -71,6 +71,9 @@ mutable struct FPGroupElement{Gr<:AbstractFPGroup,W<:AbstractWord} <: AbstractFP new{Gr, W}(word, UInt(0), G) end +Base.show(io::IO, ::Type{<:FPGroupElement{Gr}}) where {Gr} = + print(io, FPGroupElement, "{$Gr, …}") + word(f::AbstractFPGroupElement) = f.word #convenience @@ -203,6 +206,9 @@ function Base.show(io::IO, G::FPGroup) print(io, "⟩") end +Base.show(io::IO, ::Type{<:FPGroup{T}}) where {T} = + print(io, FPGroup, "{$T, …}") + ## GSymbol aka letter of alphabet abstract type GSymbol end From 7ac7b3aa5ba72be3e9016a2055ce1d22411f2a04 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 11 Dec 2021 13:55:47 +0100 Subject: [PATCH 3/5] formatting --- src/types.jl | 65 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/src/types.jl b/src/types.jl index 7a23eee..dfb637c 100644 --- a/src/types.jl +++ b/src/types.jl @@ -23,8 +23,13 @@ word_type(::Type{<:AbstractFPGroup}) = Word{UInt8} # the default (results in free rewriting) rewriting(G::AbstractFPGroup) = alphabet(G) -Base.@propagate_inbounds function (G::AbstractFPGroup)(word::AbstractVector{<:Integer}) - @boundscheck @assert all(l -> 1 <= l <= length(KnuthBendix.alphabet(G)), word) +Base.@propagate_inbounds function (G::AbstractFPGroup)( + word::AbstractVector{<:Integer}, +) + @boundscheck @assert all( + l -> 1 <= l <= length(KnuthBendix.alphabet(G)), + word, + ) return FPGroupElement(word_type(G)(word), G) end @@ -32,7 +37,8 @@ end Base.one(G::AbstractFPGroup) = FPGroupElement(one(word_type(G)), G) -Base.eltype(::Type{FPG}) where {FPG<:AbstractFPGroup} = FPGroupElement{FPG,word_type(FPG)} +Base.eltype(::Type{FPG}) where {FPG<:AbstractFPGroup} = + FPGroupElement{FPG,word_type(FPG)} include("iteration.jl") @@ -43,32 +49,42 @@ function GroupsCore.gens(G::AbstractFPGroup, i::Integer) l = alphabet(G)[G.gens[i]] return FPGroupElement(word_type(G)([l]), G) end -GroupsCore.gens(G::AbstractFPGroup) = [gens(G, i) for i in 1:GroupsCore.ngens(G)] +GroupsCore.gens(G::AbstractFPGroup) = + [gens(G, i) for i in 1:GroupsCore.ngens(G)] # TODO: ProductReplacementAlgorithm -function Base.rand(rng::Random.AbstractRNG, rs::Random.SamplerTrivial{<:AbstractFPGroup}) +function Base.rand( + rng::Random.AbstractRNG, + rs::Random.SamplerTrivial{<:AbstractFPGroup}, +) l = rand(10:100) G = rs[] nletters = length(alphabet(G)) return FPGroupElement(word_type(G)(rand(1:nletters, l)), G) end -Base.isfinite(::AbstractFPGroup) = (@warn "using generic isfinite(::AbstractFPGroup): the returned `false` might be wrong"; false) +Base.isfinite(::AbstractFPGroup) = ( + @warn "using generic isfinite(::AbstractFPGroup): the returned `false` might be wrong"; false +) ## FPGroupElement abstract type AbstractFPGroupElement{Gr} <: GroupElement end -mutable struct FPGroupElement{Gr<:AbstractFPGroup,W<:AbstractWord} <: AbstractFPGroupElement{Gr} +mutable struct FPGroupElement{Gr<:AbstractFPGroup,W<:AbstractWord} <: + AbstractFPGroupElement{Gr} word::W savedhash::UInt parent::Gr - FPGroupElement(word::W, G::AbstractFPGroup, hash::UInt=UInt(0)) where {W<:AbstractWord} = - new{typeof(G),W}(word, hash, G) + FPGroupElement( + word::W, + G::AbstractFPGroup, + hash::UInt = UInt(0), + ) where {W<:AbstractWord} = new{typeof(G),W}(word, hash, G) - FPGroupElement{Gr, W}(word::AbstractWord, G::Gr) where {Gr, W} = - new{Gr, W}(word, UInt(0), G) + FPGroupElement{Gr,W}(word::AbstractWord, G::Gr) where {Gr,W} = + new{Gr,W}(word, UInt(0), G) end Base.show(io::IO, ::Type{<:FPGroupElement{Gr}}) where {Gr} = @@ -81,7 +97,7 @@ KnuthBendix.alphabet(g::AbstractFPGroupElement) = alphabet(parent(g)) function Base.show(io::IO, f::AbstractFPGroupElement) f = normalform!(f) - KnuthBendix.print_repr(io, word(f), alphabet(f)) + return KnuthBendix.print_repr(io, word(f), alphabet(f)) end ## GroupElement Interface for FPGroupElement @@ -100,17 +116,21 @@ function Base.deepcopy_internal(g::FPGroupElement, stackdict::IdDict) return FPGroupElement(copy(word(g)), parent(g), g.savedhash) end -function Base.inv(g::GEl) where GEl <: AbstractFPGroupElement +function Base.inv(g::GEl) where {GEl<:AbstractFPGroupElement} G = parent(g) return GEl(inv(alphabet(G), word(g)), G) end -function Base.:(*)(g::GEl, h::GEl) where GEl<:AbstractFPGroupElement +function Base.:(*)(g::GEl, h::GEl) where {GEl<:AbstractFPGroupElement} @boundscheck @assert parent(g) === parent(h) return GEl(word(g) * word(h), parent(g)) end -GroupsCore.isfiniteorder(g::AbstractFPGroupElement) = isone(g) ? true : (@warn "using generic isfiniteorder(::AbstractFPGroupElement): the returned `false` might be wrong"; false) +GroupsCore.isfiniteorder(g::AbstractFPGroupElement) = + isone(g) ? true : + ( + @warn "using generic isfiniteorder(::AbstractFPGroupElement): the returned `false` might be wrong"; false + ) # additional methods: Base.isone(g::AbstractFPGroupElement) = (normalform!(g); isempty(word(g))) @@ -129,7 +149,9 @@ struct FreeGroup{T} <: AbstractFPGroup end function FreeGroup(A::Alphabet) - @boundscheck @assert all(KnuthBendix.hasinverse(l, A) for l in KnuthBendix.letters(A)) + @boundscheck @assert all( + KnuthBendix.hasinverse(l, A) for l in KnuthBendix.letters(A) + ) ltrs = KnuthBendix.letters(A) gens = Vector{eltype(ltrs)}() invs = Vector{eltype(ltrs)}() @@ -149,12 +171,13 @@ function FreeGroup(n::Integer) sizehint!(inverses, 2n) for i in 1:n push!(symbols, Symbol(:f, i), Symbol(:F, i)) - push!(inverses, 2i, 2i-1) + push!(inverses, 2i, 2i - 1) end return FreeGroup(symbols[1:2:2n], Alphabet(symbols, inverses)) end -Base.show(io::IO, F::FreeGroup) = print(io, "free group on $(ngens(F)) generators") +Base.show(io::IO, F::FreeGroup) = + print(io, "free group on $(ngens(F)) generators") # mandatory methods: KnuthBendix.alphabet(F::FreeGroup) = F.alphabet @@ -164,7 +187,8 @@ relations(F::FreeGroup) = Pair{eltype(F)}[] # these are mathematically correct Base.isfinite(::FreeGroup) = false -GroupsCore.isfiniteorder(g::AbstractFPGroupElement{<:FreeGroup}) = isone(g) ? true : false +GroupsCore.isfiniteorder(g::AbstractFPGroupElement{<:FreeGroup}) = + isone(g) ? true : false ## FP Groups @@ -185,7 +209,6 @@ function FPGroup( ordering = KnuthBendix.LenLex, kwargs..., ) where {GEl<:FPGroupElement} - O = ordering(alphabet(G)) for (lhs, rhs) in rels @assert parent(lhs) === parent(rhs) === G @@ -203,7 +226,7 @@ function Base.show(io::IO, G::FPGroup) join(io, gens(G), ", ") print(io, " | ") join(io, relations(G), ", ") - print(io, "⟩") + return print(io, "⟩") end Base.show(io::IO, ::Type{<:FPGroup{T}}) where {T} = From d82f109e45c97dfc8f82a29e5cfd43c2577fc452 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 11 Dec 2021 13:56:04 +0100 Subject: [PATCH 4/5] bump to 0.7.1 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e180329..1085a30 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Groups" uuid = "5d8bd718-bd84-11e8-3b40-ad14f4a32557" authors = ["Marek Kaluba "] -version = "0.7.0" +version = "0.7.1" [deps] GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120" From e770990d35e4803c88c3b114eb65d2e21a9a65b3 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Mon, 13 Dec 2021 09:54:32 +0100 Subject: [PATCH 5/5] fix: specialize printing for Type{<:Automorphism} --- src/autgroups.jl | 4 ++-- test/AutFn.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/autgroups.jl b/src/autgroups.jl index 6ac0165..696270a 100644 --- a/src/autgroups.jl +++ b/src/autgroups.jl @@ -79,8 +79,8 @@ end # eye-candy -Base.show(io::IO, ::Type{<:AbstractFPGroupElement{<:AutomorphismGroup{T}}}) where {T} = - print(io, "Automorphism{$T,…}") +Base.show(io::IO, ::Type{<:FPGroupElement{<:AutomorphismGroup{T}}}) where {T} = + print(io, "Automorphism{$T, …}") Base.show(io::IO, A::AutomorphismGroup) = print(io, "automorphism group of ", object(A)) diff --git a/test/AutFn.jl b/test/AutFn.jl index b8a3f1d..c9b47c5 100644 --- a/test/AutFn.jl +++ b/test/AutFn.jl @@ -96,7 +96,7 @@ @test evaluate(g*h) == evaluate(h*g) @test (g*h).savedhash == zero(UInt) - @test sprint(show, typeof(g)) == "Automorphism{FreeGroup{Symbol},…}" + @test sprint(show, typeof(g)) == "Automorphism{FreeGroup{Symbol}, …}" a = g*h b = h*g