diff --git a/Project.toml b/Project.toml index cd77d3f..7e007b9 100644 --- a/Project.toml +++ b/Project.toml @@ -15,13 +15,15 @@ AbstractAlgebra = "0.15, 0.16" GroupsCore = "^0.3" KnuthBendix = "^0.2.1" OrderedCollections = "1" +PermutationGroups = "^0.3" ThreadsX = "^0.1.0" julia = "1.3, 1.4, 1.5, 1.6" [extras] AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +PermutationGroups = "8bc5a954-2dfc-11e9-10e6-cd969bffa420" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test", "BenchmarkTools", "AbstractAlgebra"] +test = ["Test", "BenchmarkTools", "AbstractAlgebra", "PermutationGroups"] diff --git a/test/AutSigma_41.jl b/test/AutSigma_41.jl index 11c3e6a..f4f92d2 100644 --- a/test/AutSigma_41.jl +++ b/test/AutSigma_41.jl @@ -1,12 +1,21 @@ using PermutationGroups +using Groups.KnuthBendix @testset "Wajnryb presentation for Σ₄₁" begin genus = 4 - G = New.SpecialAutomorphismGroup(New.FreeGroup(2genus)) + G = SpecialAutomorphismGroup(FreeGroup(2genus)) - T = let G = G; (Tas, Tαs, Tes) = New.mcg_twists(genus) + # symplectic pairing goes like this: + # in the free Group: + # f1 ↔ f5 + # f2 ↔ f6 + # f3 ↔ f7 + # f4 ↔ f8 + + T = let G = G + (Tas, Tαs, Tes) = Groups.mcg_twists(G) Ta = G.(Tas) Tα = G.(Tαs) Tes = G.(Tes) @@ -24,24 +33,58 @@ using PermutationGroups a8 = T[8]^-1 # Tα₄ b0 = T[2]^-1 # Ta₂ - a0 = (a1*a2*a3)^4*b0^-1 # from the 3-chain relation - X = a4*a5*a3*a4 # auxillary, not present in the Primer - b1 = X^-1*a0*X + a0 = (a1 * a2 * a3)^4 * b0^-1 # from the 3-chain relation + X = a4 * a5 * a3 * a4 # auxillary, not present in the Primer + b1 = X^-1 * a0 * X b2 = T[10]^-1 # Te₁₃ - As = T[[1,5,9,6,12,7,14,8]] # the inverses of the elements a + As = T[[1, 5, 9, 6, 12, 7, 14, 8]] # the inverses of the elements a + + + @testset "preserving relator" begin + F = Groups.object(G) + + R = prod(commutator(gens(F, i), gens(F, i+genus)) for i in 1:genus) + + ## TODO: how to evaluate automorphisms properly??!!! + + for g in T + w = one(word(g)) + + dg = Groups.domain(g) + gens_idcs = first.(word.(dg)) + img = evaluate(g) + A = alphabet(first(dg)) + + ltrs_map = Vector{eltype(dg)}(undef, length(KnuthBendix.letters(A))) + + for i in 1:length(KnuthBendix.letters(A)) + if i in gens_idcs + ltrs_map[i] = img[findfirst(==(i), gens_idcs)] + else + ltrs_map[i] = inv(img[findfirst(==(inv(A, i)), gens_idcs)]) + end + end + + for l in word(R) + append!(w, word(ltrs_map[l])) + end + + @test F(w) == R + end + end @testset "commutation relations" begin for (i, ai) in enumerate(As) #the element ai here is actually the inverse of ai before. It does not matter for commutativity. Also, a0 is as defined before. for (j, aj) in enumerate(As) - if abs(i-j) > 1 - @test ai*aj == aj*ai + if abs(i - j) > 1 + @test ai * aj == aj * ai elseif i ≠ j - @test ai*aj != aj*ai + @test ai * aj != aj * ai end end if i != 4 - @test a0*ai == ai*a0 + @test a0 * ai == ai * a0 end end end @@ -49,145 +92,186 @@ using PermutationGroups @testset "braid relations" begin for (i, ai) in enumerate(As) #the element ai here is actually the inverse of ai before. It does not matter for braid relations. for (j, aj) in enumerate(As) - if abs(i-j) == 1 - @test ai*aj*ai == aj*ai*aj + if abs(i - j) == 1 + @test ai * aj * ai == aj * ai * aj end end end - @test a0*a4*a0 == a4*a0*a4 # here, a0 and a4 are as before + @test a0 * a4 * a0 == a4 * a0 * a4 # here, a0 and a4 are as before end @testset "Lantern relation" begin @testset "b2 definition" begin - @test b2 == (a2*a3*a1*a2)^-1*b1*(a2*a3*a1*a2) + @test b2 == (a2 * a3 * a1 * a2)^-1 * b1 * (a2 * a3 * a1 * a2) # some additional tests, checking what explicitly happens to the generators of the π₁ under b2 - d = New.domain(b2) - im = New.evaluate(b2) - z = im[7]*d[7]^-1 + d = Groups.domain(b2) + im = evaluate(b2) + z = im[7] * d[7]^-1 @test im[1] == d[1] - @test im[2] == z*d[2]*z^-1 - @test im[3] == z*d[3]*z^-1 + @test im[2] == z * d[2] * z^-1 + @test im[3] == z * d[3] * z^-1 @test im[4] == d[4] - @test im[5] == d[5]*z^-1 - @test im[6] == z*d[6]*z^-1 - @test im[7] == z*d[7] + @test im[5] == d[5] * z^-1 + @test im[6] == z * d[6] * z^-1 + @test im[7] == z * d[7] @test im[8] == d[8] end @testset "b2: commutation relations" begin - @test b2*a1 == a1*b2 - @test b2*a2 != a2*b2 - @test b2*a3 == a3*b2 - @test b2*a4 == a4*b2 - @test b2*a5 == a5*b2 - @test b2*a6 != a6*b2 + @test b2 * a1 == a1 * b2 + @test b2 * a2 != a2 * b2 + @test b2 * a3 == a3 * b2 + @test b2 * a4 == a4 * b2 + @test b2 * a5 == a5 * b2 + @test b2 * a6 != a6 * b2 end @testset "b2: braid relations" begin - @test a2*b2*a2 == b2*a2*b2 - @test a6*b2*a6 == b2*a6*b2 + @test a2 * b2 * a2 == b2 * a2 * b2 + @test a6 * b2 * a6 == b2 * a6 * b2 end @testset "lantern" begin - u = (a6*a5)^-1*b1*(a6*a5) - x = (a6*a5*a4*a3*a2*u*a1^-1*a2^-1*a3^-1*a4^-1) # yet another auxillary + u = (a6 * a5)^-1 * b1 * (a6 * a5) + x = (a6 * a5 * a4 * a3 * a2 * u * a1^-1 * a2^-1 * a3^-1 * a4^-1) # yet another auxillary # x = (a4^-1*a3^-1*a2^-1*a1^-1*u*a2*a3*a4*a5*a6) - @time New.evaluate(x) - b3 = x*a0*x^-1 - @time New.evaluate(b3) - @test a0*b2*b1 == a1*a3*a5*b3 + @time evaluate(x) + b3 = x * a0 * x^-1 + @time evaluate(b3) + @test a0 * b2 * b1 == a1 * a3 * a5 * b3 end end @testset "Te₁₂ definition" begin G = parent(first(T)) - F₈ = New.object(G) - (a, b, c, d, α, β, γ, δ) = gens(F₈) + F₈ = Groups.object(G) + (a, b, c, d, α, β, γ, δ) = Groups.gens(F₈) - A = KnuthBendix.alphabet(G) + A = alphabet(G) - λ = [i == j ? one(G) : G([A[New.λ(i,j)]]) for i in 1:8, j in 1:8] - ϱ = [i == j ? one(G) : G([A[New.ϱ(i,j)]]) for i in 1:8, j in 1:8] + λ = [i == j ? one(G) : G([A[Groups.λ(i, j)]]) for i in 1:8, j in 1:8] + ϱ = [i == j ? one(G) : G([A[Groups.ϱ(i, j)]]) for i in 1:8, j in 1:8] g = one(G) - # @show g - # @show g(Groups.domain(G)) # β ↦ α*β - g *= λ[6,5] - @test New.evaluate(g)[6] == α*β + g *= λ[6, 5] + @test evaluate(g)[6] == α * β # α ↦ a*α*b^-1 - g *= λ[5,1]*inv(ϱ[5,2]) - @test New.evaluate(g)[5] == a*α*b^-1 + g *= λ[5, 1] * inv(ϱ[5, 2]) + @test evaluate(g)[5] == a * α * b^-1 # β ↦ b*α^-1*a^-1*α*β - g *= inv(λ[6,5]) - @test New.evaluate(g)[6] == b*α^-1*a^-1*α*β + g *= inv(λ[6, 5]) + @test evaluate(g)[6] == b * α^-1 * a^-1 * α * β # b ↦ α - g *= λ[2,5]*inv(λ[2,1]); - @test New.evaluate(g)[2] == α + g *= λ[2, 5] * inv(λ[2, 1]) + @test evaluate(g)[2] == α # b ↦ b*α^-1*a^-1*α - g *= inv(λ[2,5]); - @test New.evaluate(g)[2] == b*α^-1*a^-1*α + g *= inv(λ[2, 5]) + @test evaluate(g)[2] == b * α^-1 * a^-1 * α # b ↦ b*α^-1*a^-1*α*b*α^-1 - g *= inv(ϱ[2,5])*ϱ[2,1]; - @test New.evaluate(g)[2] == b*α^-1*a^-1*α*b*α^-1 + g *= inv(ϱ[2, 5]) * ϱ[2, 1] + @test evaluate(g)[2] == b * α^-1 * a^-1 * α * b * α^-1 # b ↦ b*α^-1*a^-1*α*b*α^-1*a*α*b^-1 - g *= ϱ[2,5]; - @test New.evaluate(g)[2] == b*α^-1*a^-1*α*b*α^-1*a*α*b^-1 + g *= ϱ[2, 5] + @test evaluate(g)[2] == b * α^-1 * a^-1 * α * b * α^-1 * a * α * b^-1 - x = b*α^-1*a^-1*α - @test New.evaluate(g) == # (a, b, c, d, α, β, γ, δ) - (a, x*b*x^-1, c, d, α*x^-1, x*β, γ, δ) + x = b * α^-1 * a^-1 * α + @test evaluate(g) == + (a, x * b * x^-1, c, d, α * x^-1, x * β, γ, δ) + # (a, b, c, d, α, β, γ, δ) @test g == T[9] end - Base.conj(t::New.Transvection, p::Perm) = - New.Transvection(t.id, t.i^p, t.j^p, t.inv) + Base.conj(t::Groups.Transvection, p::Perm) = + Groups.Transvection(t.id, t.i^p, t.j^p, t.inv) - function Base.conj(elt::New.FPGroupElement, p::Perm) + function Base.conj(elt::FPGroupElement, p::Perm) G = parent(elt) - A = New.alphabet(elt) - return G([A[conj(A[idx], p)] for idx in New.word(elt)]) + A = alphabet(elt) + return G([A[conj(A[idx], p)] for idx in word(elt)]) end @testset "Te₂₃ definition" begin Te₁₂, Te₂₃ = T[9], T[12] G = parent(Te₁₂) - F₈ = New.object(G) - (a, b, c, d, α, β, γ, δ) = gens(F₈) + F₈ = Groups.object(G) + (a, b, c, d, α, β, γ, δ) = Groups.gens(F₈) - img_Te₂₃ = New.evaluate(Te₂₃) - y = c*β^-1*b^-1*β - @test img_Te₂₃ == (a, b, y*c*y^-1, d, α, β*y^-1, y*γ, δ) + img_Te₂₃ = evaluate(Te₂₃) + y = c * β^-1 * b^-1 * β + @test img_Te₂₃ == (a, b, y * c * y^-1, d, α, β * y^-1, y * γ, δ) σ = perm"(1,2,3)(5,6,7)(8)" Te₂₃_σ = conj(Te₁₂, σ) - # @test New.word(Te₂₃_σ) == New.word(Te₂₃) + # @test word(Te₂₃_σ) == word(Te₂₃) - @test New.evaluate(Te₂₃_σ) == New.evaluate(Te₂₃) + @test evaluate(Te₂₃_σ) == evaluate(Te₂₃) @test Te₂₃ == Te₂₃_σ end @testset "Te₃₄ definition" begin Te₁₂, Te₃₄ = T[9], T[14] G = parent(Te₁₂) - F₈ = New.object(G) + F₈ = Groups.object(G) (a, b, c, d, α, β, γ, δ) = Groups.gens(F₈) σ = perm"(1,3)(2,4)(5,7)(6,8)" Te₃₄_σ = conj(Te₁₂, σ) @test Te₃₄ == Te₃₄_σ end + + @testset "hyperelliptic τ is central" begin + + A = alphabet(G) + λ = Groups.ΡΛ(:λ, A, 2genus) + ϱ = Groups.ΡΛ(:ϱ, A, 2genus) + + import Groups: Ta, Tα, Te + + halftwists = map(1:genus-1) do i + j = i + 1 + x = Ta(λ, j) * inv(A, Ta(λ, i)) * Tα(λ, j) * Te(λ, ϱ, i, j) + δ = x * Tα(λ, i) * inv(A, x) + c = + inv(A, Ta(λ, j)) * + Te(λ, ϱ, i, j) * + Tα(λ, i)^2 * + inv(A, δ) * + inv(A, Ta(λ, j)) * + Ta(λ, i) * + δ + z = + Te(λ, ϱ, j, i) * + inv(A, Ta(λ, i)) * + Tα(λ, i) * + Ta(λ, i) * + inv(A, Te(λ, ϱ, j, i)) + + G(Ta(λ, i) * inv(A, Ta(λ, j) * Tα(λ, j))^6 * (Ta(λ, j) * Tα(λ, j) * z)^4 * c) + end + + τ = (G(Ta(λ, 1) * Tα(λ, 1))^6) * prod(halftwists, init = one(G)) + + # τ^genus is trivial but only in autπ₁Σ₄ + # here we check its centrality + + + + + τᵍ = τ^genus + @test_broken all(a * τᵍ == τᵍ * a for a in Groups.gens(G)) + end end diff --git a/test/runtests.jl b/test/runtests.jl index e69bce8..2e41ab8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -26,6 +26,7 @@ include(joinpath(pathof(GroupsCore), "..", "..", "test", "conformance_test.jl")) include("fp_groups.jl") include("AutFn.jl") + include("AutSigma_41.jl") # if !haskey(ENV, "CI") # include("benchmarks.jl")