Groups.jl/src/aut_groups/gersten_relations.jl

120 lines
3.5 KiB
Julia
Raw Normal View History

2023-03-15 18:37:10 +01:00
function gersten_alphabet(n::Integer; commutative::Bool = true)
2021-05-16 22:47:20 +02:00
indexing = [(i, j) for i in 1:n for j in 1:n if i j]
S = [ϱ(i, j) for (i, j) in indexing]
2021-05-16 22:47:20 +02:00
if !commutative
append!(S, [λ(i, j) for (i, j) in indexing])
end
2022-10-14 01:14:38 +02:00
return Alphabet(mapreduce(x -> [x, inv(x)], union, S))
end
function _commutation_rule(
::Type{W},
A::Alphabet,
x::S,
y::S,
) where {S,T,W<:AbstractWord{T}}
return W(T[A[x], A[y]]) => W(T[A[y], A[x]])
end
function _pentagonal_rule(
::Type{W},
A::Alphabet,
x::S,
y::S,
z::S,
) where {S,T,W<:AbstractWord{T}}
# x·y·x⁻¹·y⁻¹ => z, i.e. z·y·x => x·y
return W(T[A[z], A[y], A[x]]) => W(T[A[x], A[y]])
end
function _hexagonal_rule(
::Type{W},
A::Alphabet,
x::S,
y::S,
z::S,
w::S,
) where {S,T,W<:AbstractWord{T}}
# x·y⁻¹·z => z·w⁻¹·x
return W(T[A[x], A[inv(y)], A[z]]) => W(T[A[z], A[w^-1], A[x]])
end
2023-03-15 18:37:10 +01:00
function gersten_relations(n::Integer; commutative)
return gersten_relations(Word{UInt8}, n; commutative = commutative)
end
2023-03-15 18:37:10 +01:00
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"
2023-03-15 18:37:10 +01:00
A = gersten_alphabet(n; commutative = commutative)
2022-10-14 01:14:38 +02:00
@assert length(A) <= typemax(eltype(W)) "Type $W can not represent words over alphabet with $(length(A)) letters."
rels = Pair{W,W}[]
for (i, j, k, l) in Iterators.product(1:n, 1:n, 1:n, 1:n)
if i j && k l && k i && k j && l i
push!(rels, _commutation_rule(W, A, ϱ(i, j), ϱ(k, l)))
commutative && continue
push!(rels, _commutation_rule(W, A, λ(i, j), λ(k, l)))
end
end
if !commutative
for (i, j, k, l) in Iterators.product(1:n, 1:n, 1:n, 1:n)
if (i j && k l && k j && l i)
push!(rels, _commutation_rule(W, A, ϱ(i, j), λ(k, l)))
push!(rels, _commutation_rule(W, A, λ(i, j), ϱ(k, l)))
end
end
end
# pentagonal rule:
# x*y*inv(x)*inv(y)=>z
for (i, j, k) in Iterators.product(1:n, 1:n, 1:n)
if (i j && k i && k j)
2023-03-15 18:37:10 +01:00
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
push!(rels, _pentagonal_rule(W, A, ϱ(i, j), λ(j, k), ϱ(i, k)^-1))
push!(rels, _pentagonal_rule(W, A, ϱ(i, j), λ(j, k)^-1, ϱ(i, k)))
# the same as above, but with ϱ ↔ λ:
2023-03-15 18:37:10 +01:00
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))
push!(rels, _pentagonal_rule(W, A, λ(i, j), ϱ(j, k)^-1, λ(i, k)))
end
end
if !commutative
for (i, j) in Iterators.product(1:n, 1:n)
if i j
2023-03-15 18:37:10 +01:00
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
end
end
return A, rels
end