60 lines
1.4 KiB
Julia
60 lines
1.4 KiB
Julia
import OrderedCollections: OrderedSet
|
|
|
|
mutable struct FPGroupIter{S,T,GEl}
|
|
seen::S
|
|
seen_iter_state::T
|
|
current::GEl
|
|
gen_idx::Int
|
|
u_tmp::GEl
|
|
v_tmp::GEl
|
|
end
|
|
|
|
function Base.iterate(G::AbstractFPGroup)
|
|
seen = OrderedSet([one(G)])
|
|
current, seen_state = iterate(seen)
|
|
gr_iter = FPGroupIter(seen, seen_state, current, 1, one(G), one(G))
|
|
return one(G), gr_iter
|
|
end
|
|
|
|
function _next_elt!(itr::FPGroupIter)
|
|
res = iterate(itr.seen, itr.seen_iter_state)
|
|
res === nothing && return true
|
|
|
|
itr.current = first(res)
|
|
itr.seen_iter_state = last(res)
|
|
itr.gen_idx = 1
|
|
|
|
return false
|
|
end
|
|
|
|
function Base.iterate(G::AbstractFPGroup, state)
|
|
if state.gen_idx > length(alphabet(G))
|
|
finished = _next_elt!(state)
|
|
finished && return nothing
|
|
end
|
|
|
|
elt = let u = state.u_tmp, v = state.v_tmp, current = state.current
|
|
copyto!(v, current)
|
|
push!(word(v), state.gen_idx)
|
|
_setnormalform!(v, false)
|
|
_setvalidhash!(v, false)
|
|
@assert !isnormalform(v)
|
|
|
|
resize!(word(u), 0)
|
|
normalform!(u, v)
|
|
end
|
|
|
|
state.gen_idx += 1
|
|
|
|
if elt in state.seen
|
|
return iterate(G, state)
|
|
else
|
|
@assert isnormalform(elt)
|
|
push!(state.seen, deepcopy(elt))
|
|
return elt, state
|
|
end
|
|
end
|
|
|
|
# Groups.Core default:
|
|
# Base.IteratorSize(::Type{<:AbstractFPGroup}) = Base.SizeUnknown()
|