mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-11-19 06:30:29 +01:00
Merge branch 'enh/word_replacement'
This commit is contained in:
commit
26e3d74800
@ -2,6 +2,7 @@ module Groups
|
||||
|
||||
import Base: length, ==, hash, show, convert
|
||||
import Base: one, inv, reduce, *, ^
|
||||
import Base: findfirst, findnext
|
||||
|
||||
export GSymbol, GWord
|
||||
|
||||
@ -177,6 +178,72 @@ end
|
||||
(^)(x::GWord, n::Integer) = power_by_squaring(x,n)
|
||||
(^){T<:GSymbol}(x::T, n::Integer) = GWord(x)^n
|
||||
|
||||
is_subsymbol(s::GSymbol, t::GSymbol) =
|
||||
s.gen == t.gen && (0 ≤ s.pow ≤ t.pow || 0 ≥ s.pow ≥ t.pow)
|
||||
|
||||
function findfirst(W::GWord, Z::GWord)
|
||||
n = length(Z.symbols)
|
||||
|
||||
@assert n > 1
|
||||
for (idx,a) in enumerate(W.symbols)
|
||||
if idx + n - 1 > length(W.symbols)
|
||||
break
|
||||
end
|
||||
first = is_subsymbol(Z.symbols[1],a)
|
||||
if first
|
||||
middle = W.symbols[idx+1:idx+n-2] == Z.symbols[2:end-1]
|
||||
last = is_subsymbol(Z.symbols[end], W.symbols[idx+n-1])
|
||||
if middle && last
|
||||
return idx
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function findnext(W::GWord, Z::GWord, i::Integer)
|
||||
t = findfirst(GWord{eltype(W.symbols)}(W.symbols[i:end]), Z)
|
||||
if t > 0
|
||||
return t+i-1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
function replace!(W::GWord, index, toreplace::GWord, replacement::GWord; asserts=true)
|
||||
n = length(toreplace.symbols)
|
||||
if asserts
|
||||
@assert is_subsymbol(toreplace.symbols[1], W.symbols[index])
|
||||
@assert W.symbols[index+1:index+n-2] == toreplace.symbols[2:end-1]
|
||||
@assert is_subsymbol(toreplace.symbols[end], W.symbols[index+n-1])
|
||||
end
|
||||
|
||||
first = W.symbols[index]*inv(toreplace.symbols[1])
|
||||
last = W.symbols[index+n-1]*inv(toreplace.symbols[end])
|
||||
replacement = first*replacement*last
|
||||
splice!(W.symbols, index:index+n-1, replacement.symbols)
|
||||
Groups.freegroup_reduce!(W)
|
||||
return W
|
||||
end
|
||||
|
||||
function replace(W::GWord, index, toreplace::GWord, replacement::GWord)
|
||||
replace!(deepcopy(W), index, toreplace, replacement)
|
||||
end
|
||||
|
||||
function replace_all!{T}(W::GWord{T}, subst_dict::Dict{GWord{T}, GWord{T}})
|
||||
for toreplace in reverse!(sort!(collect(keys(subst_dict)),by=length))
|
||||
replacement = subst_dict[toreplace]
|
||||
i = findfirst(W, toreplace)
|
||||
while i ≠ 0
|
||||
replace!(W,i,toreplace, replacement)
|
||||
i = findnext(W, toreplace, i)
|
||||
end
|
||||
end
|
||||
return W
|
||||
end
|
||||
|
||||
replace_all(W::GWord, subst_dict::Dict{GWord, GWord}) = replace_all!(deepcopy(W), subst_dict)
|
||||
|
||||
include("free_groups.jl")
|
||||
include("automorphism_groups.jl")
|
||||
|
||||
|
@ -87,7 +87,28 @@ end
|
||||
@test (t*s*t^-1)^10 == t*s^10*t^-1
|
||||
@test (t*s*t^-1)^-10 == t*s^-10*t^-1
|
||||
end
|
||||
|
||||
@testset "replacements" begin
|
||||
@test Groups.is_subsymbol(s, Groups.change_pow(s,2)) == true
|
||||
@test Groups.is_subsymbol(s, Groups.change_pow(s,-2)) == false
|
||||
@test Groups.is_subsymbol(t, Groups.change_pow(s,-2)) == false
|
||||
@test Groups.is_subsymbol(inv(t), Groups.change_pow(t,-2)) == true
|
||||
c = s*t*s^-1*t^-1
|
||||
@test findfirst(c, s^-1*t^-1) == 3
|
||||
@test findnext(c*s^-1, s^-1*t^-1,3) == 3
|
||||
@test findnext(c*s^-1*t^-1, s^-1*t^-1,4) == 5
|
||||
@test findfirst(c*t, c) == 0
|
||||
w = s*t*s^-1
|
||||
subst = Dict{FGWord, FGWord}(w => s^1, s*t^-1 => t^4)
|
||||
@test Groups.replace(c, 1, s*t, one(FGWord)) == s^-1*t^-1
|
||||
|
||||
@test Groups.replace(c, 1, w, subst[w]) == s*t^-1
|
||||
@test Groups.replace(s*c*t^-1, 1, w, subst[w]) == s^2*t^-2
|
||||
@test Groups.replace(t*c*t, 2, w, subst[w]) == t*s
|
||||
@test Groups.replace_all!(s*c*s*c*s, subst) == s*t^4*s*t^4*s
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Automorphisms" begin
|
||||
@testset "AutSymbol" begin
|
||||
@test_throws MethodError AutSymbol("a")
|
||||
|
Loading…
Reference in New Issue
Block a user