mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-12-26 10:25:30 +01:00
new iteration based on OrderedSet
This commit is contained in:
parent
cdd36f680a
commit
4c8eccf72b
@ -5,6 +5,7 @@ version = "0.5.2"
|
|||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
|
AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
|
||||||
|
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
||||||
GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"
|
GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"
|
||||||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
ThreadsX = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d"
|
ThreadsX = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d"
|
||||||
|
@ -22,6 +22,8 @@ include("arithmetic.jl")
|
|||||||
include("findreplace.jl")
|
include("findreplace.jl")
|
||||||
|
|
||||||
module New
|
module New
|
||||||
|
using DataStructures
|
||||||
|
|
||||||
include("new_types.jl")
|
include("new_types.jl")
|
||||||
include("new_hashing.jl")
|
include("new_hashing.jl")
|
||||||
include("normalform.jl")
|
include("normalform.jl")
|
||||||
|
55
src/iteration.jl
Normal file
55
src/iteration.jl
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
mutable struct FPIterState{GEl, T}
|
||||||
|
elts::OrderedSet{GEl}
|
||||||
|
u::GEl
|
||||||
|
v::GEl
|
||||||
|
elts_iter_state::T
|
||||||
|
end
|
||||||
|
|
||||||
|
Base.in(x, itr::FPIterState) = x in itr.elts
|
||||||
|
Base.push!(itr::FPIterState, x) = push!(itr.elts, x)
|
||||||
|
function FPIterState(G::AbstractFPGroup)
|
||||||
|
S = OrderedSet([one(G)])
|
||||||
|
elt, state = iterate(S)
|
||||||
|
return elt, FPIterState(S, one(G), one(G), state)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.iterate(G::AbstractFPGroup)
|
||||||
|
elt, state = FPIterState(G)
|
||||||
|
return one(G), (state, elt, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.iterate(G::AbstractFPGroup, state)
|
||||||
|
iter, elt, gen_idx = state
|
||||||
|
|
||||||
|
if gen_idx > length(alphabet(G))
|
||||||
|
res = iterate(iter.elts, iter.elts_iter_state)
|
||||||
|
res === nothing && return nothing
|
||||||
|
gen_idx = 1
|
||||||
|
elt = first(res)
|
||||||
|
iter.elts_iter_state = last(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
res = let (u, v) = (iter.u, iter.v), elt = elt
|
||||||
|
copyto!(v, elt) # this invalidates normalform of v
|
||||||
|
push!(word(v), gen_idx)
|
||||||
|
resize!(word(u), 0)
|
||||||
|
|
||||||
|
_setnormalform!(v, false)
|
||||||
|
_setvalidhash!(v, false)
|
||||||
|
|
||||||
|
@assert !isnormalform(v)
|
||||||
|
normalform!(u, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
if res in iter
|
||||||
|
return iterate(G, (iter, elt, gen_idx+1))
|
||||||
|
else
|
||||||
|
w = deepcopy(res)
|
||||||
|
@assert isnormalform(w)
|
||||||
|
push!(iter, w)
|
||||||
|
return w, (iter, elt, gen_idx+1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Groups.Core default:
|
||||||
|
# Base.IteratorSize(::Type{<:AbstractFPGroup}) = Base.SizeUnknown()
|
@ -43,50 +43,7 @@ Base.one(G::AbstractFPGroup) = FPGroupElement(one(word_type(G)), G)
|
|||||||
Base.eltype(::Type{FPG}) where {FPG<:AbstractFPGroup} =
|
Base.eltype(::Type{FPG}) where {FPG<:AbstractFPGroup} =
|
||||||
FPGroupElement{FPG, word_type(FPG)}
|
FPGroupElement{FPG, word_type(FPG)}
|
||||||
|
|
||||||
struct FPGroupIter{GEl}
|
include("iteration.jl")
|
||||||
elts::Vector{GEl}
|
|
||||||
seen::Set{GEl}
|
|
||||||
u::GEl
|
|
||||||
v::GEl
|
|
||||||
end
|
|
||||||
|
|
||||||
FPGroupIter(G::AbstractFPGroup) =
|
|
||||||
FPGroupIter([one(G)], Set([one(G)]), one(G), one(G))
|
|
||||||
|
|
||||||
Base.iterate(G::AbstractFPGroup) = one(G), (FPGroupIter(G), 1, 1)
|
|
||||||
@inline function Base.iterate(G::AbstractFPGroup, state)
|
|
||||||
iter, elt_idx, gen_idx = state
|
|
||||||
|
|
||||||
if gen_idx > length(alphabet(G))
|
|
||||||
elt_idx == length(iter.elts) && return nothing
|
|
||||||
gen_idx = 1
|
|
||||||
elt_idx += 1
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
res = let (u, v) = (iter.u, iter.v), elt = iter.elts[elt_idx]
|
|
||||||
copyto!(v, elt) # this invalidates normalform of v
|
|
||||||
@assert !isnormalform(v)
|
|
||||||
push!(word(v), gen_idx)
|
|
||||||
resize!(word(u), 0)
|
|
||||||
|
|
||||||
normalform!(u, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
if res in iter.seen
|
|
||||||
return iterate(G, (iter, elt_idx, gen_idx+1))
|
|
||||||
else
|
|
||||||
w = deepcopy(res)
|
|
||||||
@assert isnormalform(w)
|
|
||||||
push!(iter.elts, w)
|
|
||||||
push!(iter.seen, w)
|
|
||||||
state = (iter, elt_idx, gen_idx+1)
|
|
||||||
return w, state
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# the default:
|
|
||||||
# Base.IteratorSize(::Type{<:AbstractFPGroup}) = Base.SizeUnknown()
|
|
||||||
|
|
||||||
GroupsCore.ngens(G::AbstractFPGroup) = length(G.gens)
|
GroupsCore.ngens(G::AbstractFPGroup) = length(G.gens)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user