Merge pull request #21 from kalmarek/fix/FPGroup_order

Allow passing Ordering directly to FPGroup constructor
This commit is contained in:
Marek Kaluba 2021-12-18 23:39:11 +01:00 committed by GitHub
commit 2070d0efad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 21 deletions

View File

@ -1,7 +1,7 @@
name = "Groups"
uuid = "5d8bd718-bd84-11e8-3b40-ad14f4a32557"
authors = ["Marek Kaluba <kalmar@amu.edu.pl>"]
version = "0.7.1"
version = "0.7.2"
[deps]
GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"

View File

@ -20,8 +20,18 @@ word_type(G::AbstractFPGroup) = word_type(typeof(G))
# the default:
word_type(::Type{<:AbstractFPGroup}) = Word{UInt8}
# the default (results in free rewriting)
rewriting(G::AbstractFPGroup) = alphabet(G)
"""
rewriting(G::AbstractFPGroup)
Return a "rewriting object" for elements of `G`. The rewriting object must must implement
KnuthBendix.rewrite_from_left!(
u::AbstractWord,
v::AbstractWord,
rewriting(G)
)
For example if `G` is a `FreeGroup` then `alphabet(G)` is returned which results in free rewriting. For `FPGroup` a rewriting system is returned which may (or may not) rewrite word `v` to its normal form.
"""
function rewriting end
Base.@propagate_inbounds function (G::AbstractFPGroup)(
word::AbstractVector{<:Integer},
@ -137,17 +147,20 @@ Base.isone(g::AbstractFPGroupElement) = (normalform!(g); isempty(word(g)))
## Free Groups
struct FreeGroup{T} <: AbstractFPGroup
struct FreeGroup{T,O} <: AbstractFPGroup
gens::Vector{T}
alphabet::KnuthBendix.Alphabet{T}
ordering::O
function FreeGroup(gens, A::KnuthBendix.Alphabet) where {W}
function FreeGroup(gens, ordering::KnuthBendix.WordOrdering)
@assert length(gens) == length(unique(gens))
@assert all(l -> l in KnuthBendix.letters(A), gens)
return new{eltype(gens)}(gens, A)
L = KnuthBendix.letters(alphabet(ordering))
@assert all(l -> l in L, gens)
return new{eltype(gens),typeof(ordering)}(gens, ordering)
end
end
FreeGroup(gens, A::Alphabet) = FreeGroup(gens, KnuthBendix.LenLex(A))
function FreeGroup(A::Alphabet)
@boundscheck @assert all(
KnuthBendix.hasinverse(l, A) for l in KnuthBendix.letters(A)
@ -180,8 +193,10 @@ Base.show(io::IO, F::FreeGroup) =
print(io, "free group on $(ngens(F)) generators")
# mandatory methods:
KnuthBendix.alphabet(F::FreeGroup) = F.alphabet
relations(F::FreeGroup) = Pair{eltype(F)}[]
KnuthBendix.ordering(F::FreeGroup) = F.ordering
KnuthBendix.alphabet(F::FreeGroup) = alphabet(KnuthBendix.ordering(F))
rewriting(F::FreeGroup) = alphabet(F)
# GroupsCore interface:
# these are mathematically correct
@ -198,35 +213,43 @@ struct FPGroup{T,R,S} <: AbstractFPGroup
rws::R
end
KnuthBendix.alphabet(G::FPGroup) = alphabet(rewriting(G))
rewriting(G::FPGroup) = G.rws
relations(G::FPGroup) = G.relations
rewriting(G::FPGroup) = G.rws
KnuthBendix.ordering(G::FPGroup) = KnuthBendix.ordering(rewriting(G))
KnuthBendix.alphabet(G::FPGroup) = alphabet(KnuthBendix.ordering(G))
function FPGroup(
G::AbstractFPGroup,
rels::AbstractVector{<:Pair{GEl,GEl}};
ordering = KnuthBendix.LenLex,
ordering = KnuthBendix.ordering(G),
kwargs...,
) where {GEl<:FPGroupElement}
O = ordering(alphabet(G))
for (lhs, rhs) in rels
@assert parent(lhs) === parent(rhs) === G
end
word_rels = [word(lhs) => word(rhs) for (lhs, rhs) in [relations(G); rels]]
rws = KnuthBendix.RewritingSystem(word_rels, O)
rws = KnuthBendix.RewritingSystem(word_rels, ordering)
KnuthBendix.knuthbendix!(rws; kwargs...)
return FPGroup(G.gens, rels, rws)
end
function Base.show(io::IO, ::MIME"text/plain", G::FPGroup)
print(io, "Finitely presented group generated by:\n\t{")
Base.print_array(io, permutedims(gens(G)))
println(io, " },")
println(io, "subject to relations:")
return Base.print_array(io, relations(G))
end
function Base.show(io::IO, G::FPGroup)
print(io, "")
join(io, gens(G), ", ")
print(io, " | ")
join(io, relations(G), ", ")
return print(io, "")
Base.print_array(io, permutedims(gens(G)))
println(io, " | ")
print(io, "\t ")
Base.print_array(io, permutedims(relations(G)))
return print(io, "")
end
Base.show(io::IO, ::Type{<:FPGroup{T}}) where {T} =

View File

@ -96,7 +96,9 @@
@test evaluate(g*h) == evaluate(h*g)
@test (g*h).savedhash == zero(UInt)
@test sprint(show, typeof(g)) == "Automorphism{FreeGroup{Symbol}, …}"
if VERSION >= v"1.6.0"
@test sprint(show, typeof(g)) == "Automorphism{FreeGroup{Symbol, KnuthBendix.LenLex{Symbol}}, …}"
end
a = g*h
b = h*g

View File

@ -14,7 +14,7 @@
G = FPGroup(F, [a*b=>b*a, a*c=>c*a, b*c=>c*b])
@test G isa FPGroup
@test sprint(show, G) == "a, b, c | a*b => b*a, a*c => c*a, b*c => c*b"
@test sprint(show, G) == " a b c | \n\t a*b => b*a a*c => c*a b*c => c*b "
@test rand(G) isa FPGroupElement
f = a*c*b