format aut_groups

This commit is contained in:
Marek Kaluba 2023-03-15 18:37:10 +01:00
parent 29af9659d9
commit 3cdef72977
No known key found for this signature in database
GPG Key ID: 8BF1A3855328FC15
5 changed files with 109 additions and 43 deletions

View File

@ -1,4 +1,4 @@
function gersten_alphabet(n::Integer; commutative::Bool=true)
function gersten_alphabet(n::Integer; commutative::Bool = true)
indexing = [(i, j) for i in 1:n for j in 1:n if i j]
S = [ϱ(i, j) for (i, j) in indexing]
@ -40,12 +40,17 @@ function _hexagonal_rule(
return W(T[A[x], A[inv(y)], A[z]]) => W(T[A[z], A[w^-1], A[x]])
end
gersten_relations(n::Integer; commutative) =
gersten_relations(Word{UInt8}, n, commutative=commutative)
function gersten_relations(n::Integer; commutative)
return gersten_relations(Word{UInt8}, n; commutative = commutative)
end
function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:AbstractWord}
function gersten_relations(
::Type{W},
n::Integer;
commutative,
) where {W<:AbstractWord}
@assert n > 1 "Gersten relations are defined only for n>1, got n=$n"
A = gersten_alphabet(n, commutative=commutative)
A = gersten_alphabet(n; commutative = commutative)
@assert length(A) <= typemax(eltype(W)) "Type $W can not represent words over alphabet with $(length(A)) letters."
rels = Pair{W,W}[]
@ -74,7 +79,10 @@ function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:Abstrac
for (i, j, k) in Iterators.product(1:n, 1:n, 1:n)
if (i j && k i && k j)
push!(rels, _pentagonal_rule(W, A, ϱ(i, j)^-1, ϱ(j, k)^-1, ϱ(i, k)^-1))
push!(
rels,
_pentagonal_rule(W, A, ϱ(i, j)^-1, ϱ(j, k)^-1, ϱ(i, k)^-1),
)
push!(rels, _pentagonal_rule(W, A, ϱ(i, j)^-1, ϱ(j, k), ϱ(i, k)))
commutative && continue
@ -83,7 +91,10 @@ function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:Abstrac
push!(rels, _pentagonal_rule(W, A, ϱ(i, j), λ(j, k)^-1, ϱ(i, k)))
# the same as above, but with ϱ ↔ λ:
push!(rels, _pentagonal_rule(W, A, λ(i, j)^-1, λ(j, k)^-1, λ(i, k)^-1))
push!(
rels,
_pentagonal_rule(W, A, λ(i, j)^-1, λ(j, k)^-1, λ(i, k)^-1),
)
push!(rels, _pentagonal_rule(W, A, λ(i, j)^-1, λ(j, k), λ(i, k)))
push!(rels, _pentagonal_rule(W, A, λ(i, j), ϱ(j, k), λ(i, k)^-1))
@ -94,7 +105,10 @@ function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:Abstrac
if !commutative
for (i, j) in Iterators.product(1:n, 1:n)
if i j
push!(rels, _hexagonal_rule(W, A, ϱ(i, j), ϱ(j, i), λ(i, j), λ(j, i)))
push!(
rels,
_hexagonal_rule(W, A, ϱ(i, j), ϱ(j, i), λ(i, j), λ(j, i)),
)
w = W([A[ϱ(i, j)], A[ϱ(j, i)^-1], A[λ(i, j)]])
push!(rels, w^2 => inv(w, A)^2)
end

View File

@ -17,7 +17,7 @@ function Base.show(io::IO, S::SurfaceGroup)
end
end
function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
function SurfaceGroup(genus::Integer, boundaries::Integer, W = Word{Int16})
@assert genus > 1
# The (confluent) rewriting systems comes from
@ -31,7 +31,15 @@ function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
ltrs = String[]
for i in 1:genus
subscript = join('₀' + d for d in reverse(digits(i)))
append!(ltrs, ["A" * subscript, "a" * subscript, "B" * subscript, "b" * subscript])
append!(
ltrs,
[
"A" * subscript,
"a" * subscript,
"B" * subscript,
"b" * subscript,
],
)
end
Al = Alphabet(reverse!(ltrs))
@ -51,9 +59,13 @@ function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
comms = W(word)
word_rels = [comms => one(comms)]
rws = let R = KnuthBendix.RewritingSystem(word_rels, KnuthBendix.Recursive(Al))
KnuthBendix.IndexAutomaton(KnuthBendix.knuthbendix(R))
end
rws =
let R = KnuthBendix.RewritingSystem(
word_rels,
KnuthBendix.Recursive(Al),
)
KnuthBendix.IndexAutomaton(KnuthBendix.knuthbendix(R))
end
elseif boundaries == 1
word_rels = Pair{W,W}[]
rws = let R = RewritingSystem(word_rels, KnuthBendix.LenLex(Al))
@ -66,7 +78,13 @@ function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
F = FreeGroup(Al)
rels = [F(lhs) => F(rhs) for (lhs, rhs) in word_rels]
return SurfaceGroup(genus, boundaries, [Al[i] for i in 2:2:length(Al)], rels, rws)
return SurfaceGroup(
genus,
boundaries,
[Al[i] for i in 2:2:length(Al)],
rels,
rws,
)
end
rewriting(S::SurfaceGroup) = S.rw
@ -75,17 +93,26 @@ relations(S::SurfaceGroup) = S.relations
function symplectic_twists(π₁Σ::SurfaceGroup)
g = genus(π₁Σ)
saut = SpecialAutomorphismGroup(FreeGroup(2g), max_rules=1000)
saut = SpecialAutomorphismGroup(FreeGroup(2g); max_rules = 1000)
Aij = [SymplecticMappingClass(saut, :A, i, j) for i in 1:g for j in 1:g if i j]
Aij = [
SymplecticMappingClass(saut, :A, i, j) for i in 1:g for
j in 1:g if i j
]
Bij = [SymplecticMappingClass(saut, :B, i, j) for i in 1:g for j in 1:g if i j]
Bij = [
SymplecticMappingClass(saut, :B, i, j) for i in 1:g for
j in 1:g if i j
]
mBij = [SymplecticMappingClass(saut, :B, i, j, minus=true) for i in 1:g for j in 1:g if i j]
mBij = [
SymplecticMappingClass(saut, :B, i, j; minus = true) for i in 1:g
for j in 1:g if i j
]
Bii = [SymplecticMappingClass(saut, :B, i, i) for i in 1:g]
mBii = [SymplecticMappingClass(saut, :B, i, i, minus=true) for i in 1:g]
mBii = [SymplecticMappingClass(saut, :B, i, i; minus = true) for i in 1:g]
return [Aij; Bij; mBij; Bii; mBii]
end

View File

@ -1,10 +1,13 @@
include("transvections.jl")
include("gersten_relations.jl")
function SpecialAutomorphismGroup(F::FreeGroup; ordering=KnuthBendix.LenLex, kwargs...)
function SpecialAutomorphismGroup(
F::FreeGroup;
ordering = KnuthBendix.LenLex,
kwargs...,
)
n = length(alphabet(F)) ÷ 2
A, rels = gersten_relations(n, commutative=false)
A, rels = gersten_relations(n; commutative = false)
S = [A[i] for i in 1:2:length(A)]
max_rules = 1000 * n
@ -12,7 +15,10 @@ function SpecialAutomorphismGroup(F::FreeGroup; ordering=KnuthBendix.LenLex, kwa
rws = Logging.with_logger(Logging.NullLogger()) do
rws = KnuthBendix.RewritingSystem(rels, ordering(A))
# the rws is not confluent, let's suppress warning about it
KnuthBendix.knuthbendix(rws, KnuthBendix.Settings(; max_rules=max_rules, kwargs...))
return KnuthBendix.knuthbendix(
rws,
KnuthBendix.Settings(; max_rules = max_rules, kwargs...),
)
end
idxA = KnuthBendix.IndexAutomaton(rws)
@ -21,5 +27,5 @@ end
function relations(G::AutomorphismGroup{<:FreeGroup})
n = length(alphabet(object(G))) ÷ 2
return last(gersten_relations(n, commutative=false))
return last(gersten_relations(n; commutative = false))
end

View File

@ -47,7 +47,15 @@ function Te_diagonal(λ::Groups.ΡΛ, ϱ::Groups.ΡΛ, i::Integer)
return g
end
function Te_lantern(A::Alphabet, b₀::T, a₁::T, a₂::T, a₃::T, a₄::T, a₅::T) where {T}
function Te_lantern(
A::Alphabet,
b₀::T,
a₁::T,
a₂::T,
a₃::T,
a₄::T,
a₅::T,
) where {T}
a₀ = (a₁ * a₂ * a₃)^4 * inv(b₀, A)
X = a₄ * a₅ * a₃ * a₄ # from Primer
b₁ = inv(X, A) * a₀ * X # from Primer
@ -85,7 +93,8 @@ function Te(λ::ΡΛ, ϱ::ΡΛ, i, j)
if mod(j - (i + 1), genus) == 0
return Te_diagonal(λ, ϱ, i)
else
return inv(Te_lantern(
return inv(
Te_lantern(
A,
# Our notation: # Primer notation:
inv(Ta(λ, i + 1), A), # b₀
@ -94,7 +103,9 @@ function Te(λ::ΡΛ, ϱ::ΡΛ, i, j)
inv(Te_diagonal(λ, ϱ, i), A), # a₃
inv(Tα(λ, i + 1), A), # a₄
inv(Te(λ, ϱ, i + 1, j), A), # a₅
), A)
),
A,
)
end
end
@ -105,7 +116,6 @@ Return the element of `G` which corresponds to shifting generators of the free g
In the corresponding mapping class group this element acts by rotation of the surface anti-clockwise.
"""
function rotation_element(G::AutomorphismGroup{<:FreeGroup})
A = alphabet(G)
@assert iseven(ngens(object(G)))
genus = ngens(object(G)) ÷ 2
@ -140,7 +150,10 @@ function rotation_element(λ::ΡΛ, ϱ::ΡΛ)
Ta(λ, i) *
inv(Te_diagonal(λ, ϱ, i), A)
Ta(λ, i) * inv(Ta(λ, j) * Tα(λ, j), A)^6 * (Ta(λ, j) * Tα(λ, j) * z)^4 * c
return Ta(λ, i) *
inv(Ta(λ, j) * Tα(λ, j), A)^6 *
(Ta(λ, j) * Tα(λ, j) * z)^4 *
c
end
τ = (Ta(λ, 1) * Tα(λ, 1))^6 * prod(halftwists)
@ -148,7 +161,6 @@ function rotation_element(λ::ΡΛ, ϱ::ΡΛ)
end
function mcg_twists(G::AutomorphismGroup{<:FreeGroup})
@assert iseven(ngens(object(G)))
genus = ngens(object(G)) ÷ 2
@ -178,7 +190,9 @@ struct SymplecticMappingClass{T,F} <: GSymbol
f::F
end
Base.:(==)(a::SymplecticMappingClass, b::SymplecticMappingClass) = a.autFn_word == b.autFn_word
function Base.:(==)(a::SymplecticMappingClass, b::SymplecticMappingClass)
return a.autFn_word == b.autFn_word
end
Base.hash(a::SymplecticMappingClass, h::UInt) = hash(a.autFn_word, h)
@ -187,8 +201,8 @@ function SymplecticMappingClass(
id::Symbol,
i::Integer,
j::Integer;
minus=false,
inverse=false
minus = false,
inverse = false,
)
@assert i > 0 && j > 0
id === :A && @assert i j
@ -246,7 +260,7 @@ function Base.show(io::IO, smc::SymplecticMappingClass)
else
print(io, smc.id, subscriptify(smc.i), ".", subscriptify(smc.j))
end
smc.inv && print(io, "^-1")
return smc.inv && print(io, "^-1")
end
function Base.inv(m::SymplecticMappingClass)
@ -259,7 +273,7 @@ end
function evaluate!(
t::NTuple{N,T},
smc::SymplecticMappingClass,
tmp=nothing,
tmp = nothing,
) where {N,T}
t = smc.f(t)
for i in 1:N

View File

@ -4,7 +4,7 @@ struct Transvection <: GSymbol
j::UInt16
inv::Bool
function Transvection(id::Symbol, i::Integer, j::Integer, inv=false)
function Transvection(id::Symbol, i::Integer, j::Integer, inv = false)
@assert id in (:ϱ, )
return new(id, i, j, inv)
end
@ -20,20 +20,23 @@ function Base.show(io::IO, t::Transvection)
'λ'
end
print(io, id, subscriptify(t.i), '.', subscriptify(t.j))
t.inv && print(io, "^-1")
return t.inv && print(io, "^-1")
end
Base.inv(t::Transvection) = Transvection(t.id, t.i, t.j, !t.inv)
Base.:(==)(t::Transvection, s::Transvection) =
t.id === s.id && t.i == s.i && t.j == s.j && t.inv == s.inv
function Base.:(==)(t::Transvection, s::Transvection)
return t.id === s.id && t.i == s.i && t.j == s.j && t.inv == s.inv
end
Base.hash(t::Transvection, h::UInt) = hash(hash(t.id, hash(t.i)), hash(t.j, hash(t.inv, h)))
function Base.hash(t::Transvection, h::UInt)
return hash(hash(t.id, hash(t.i)), hash(t.j, hash(t.inv, h)))
end
Base.@propagate_inbounds @inline function evaluate!(
v::NTuple{T,N},
t::Transvection,
tmp=one(first(v)),
tmp = one(first(v)),
) where {T,N}
i, j = t.i, t.j
@assert 1 i length(v) && 1 j length(v)
@ -84,7 +87,7 @@ end
function Base.show(io::IO, p::PermRightAut)
print(io, 'σ')
join(io, (subscriptify(Int(i)) for i in p.perm))
return join(io, (subscriptify(Int(i)) for i in p.perm))
end
Base.inv(p::PermRightAut) = PermRightAut(invperm(p.perm))
@ -92,4 +95,6 @@ Base.inv(p::PermRightAut) = PermRightAut(invperm(p.perm))
Base.:(==)(p::PermRightAut, q::PermRightAut) = p.perm == q.perm
Base.hash(p::PermRightAut, h::UInt) = hash(p.perm, hash(PermRightAut, h))
evaluate!(v::NTuple{T,N}, p::PermRightAut, tmp=nothing) where {T,N} = v[p.perm]
function evaluate!(v::NTuple{T,N}, p::PermRightAut, tmp = nothing) where {T,N}
return v[p.perm]
end