separate GWords

This commit is contained in:
kalmarek 2020-03-25 04:19:02 +01:00
parent 263444c2a9
commit 43ad81d4dd
No known key found for this signature in database
GPG Key ID: 8BF1A3855328FC15
3 changed files with 69 additions and 49 deletions

View File

@ -17,53 +17,10 @@ using Markdown
include("types.jl")
include("gsymbols.jl")
include("fallbacks.jl")
include("words.jl")
@doc doc"""
abstract type GWord{T<:GSymbol} <: GroupElem end
# fallback definitions
Base.eltype(w::GW) where GW<:GWord = eltype(GW)
@doc doc"""
W::GroupWord{T} <: GWord{T<:GSymbol} <:GroupElem
> Basic representation of element of a finitely presented group. `W.symbols`
> fieldname contains particular group symbols which multiplied constitute a
> group element, i.e. a word in generators.
> As reduction (inside group) of such word may be time consuming we provide
> `savedhash` and `modified` fields as well:
> hash (used e.g. in the `unique` function) is calculated by reducing the word,
> setting `modified` flag to `false` and computing the hash which is stored in
> `savedhash` field.
> whenever word `W` is changed `W.modified` is set to `false`;
> Future comparisons don't perform reduction (and use `savedhash`) as long as
> `modified` flag remains `false`.
"""
mutable struct GroupWord{T} <: GWord{T}
symbols::Vector{T}
modified::Bool
savedhash::UInt
parent::Group
function GroupWord{T}(symbols::Vector{T}) where {T}
return new{T}(symbols, true, zero(UInt))
end
end
syllablelength(w::GWord) = length(w.symbols)
syllables(w::GWord) = w.symbols
ismodified(w::GWord) = w.modified
setmodified!(w::GWord) = (w.modified = true; w)
unsetmodified!(w::GWord) = (w.modified = false; w)
Base.one(w::GWord) = one(parent(w))
###############################################################################
#
# Includes
#
###############################################################################
include("FreeGroup.jl")
include("FPGroups.jl")
@ -86,11 +43,6 @@ parent(w::GWord{T}) where {T<:GSymbol} = w.parent
#
###############################################################################
GroupWord(s::T) where {T<:GSymbol} = GroupWord{T}(T[s])
GroupWord{T}(s::T) where {T<:GSymbol} = GroupWord{T}(T[s])
GroupWord(w::GroupWord{T}) where {T<:GSymbol} = w
convert(::Type{GroupWord{T}}, s::T) where {T<:GSymbol} = GroupWord{T}(T[s])
###############################################################################
#
# Basic manipulation

View File

@ -9,3 +9,32 @@ abstract type AbstractFPGroup <: Group end
> * `pow` which is the (multiplicative) exponent of a symbol.
"""
abstract type GSymbol end
abstract type GWord{T<:GSymbol} <: GroupElem end
@doc doc"""
W::GroupWord{T} <: GWord{T<:GSymbol} <:GroupElem
> Basic representation of element of a finitely presented group. `W.symbols`
> fieldname contains particular group symbols which multiplied constitute a
> group element, i.e. a word in generators.
> As reduction (inside group) of such word may be time consuming we provide
> `savedhash` and `modified` fields as well:
> hash (used e.g. in the `unique` function) is calculated by reducing the word,
> setting `modified` flag to `false` and computing the hash which is stored in
> `savedhash` field.
> whenever word `W` is changed `W.modified` is set to `false`;
> Future comparisons don't perform reduction (and use `savedhash`) as long as
> `modified` flag remains `false`.
"""
mutable struct GroupWord{T} <: GWord{T}
symbols::Vector{T}
modified::Bool
savedhash::UInt
parent::Group
function GroupWord{T}(symbols::Vector{<:GSymbol}) where T
return new{T}(symbols, true, zero(UInt))
end
end

39
src/words.jl Normal file
View File

@ -0,0 +1,39 @@
syllablelength(w::GWord) = length(w.symbols)
syllables(w::GWord) = w.symbols
ismodified(w::GWord) = w.modified
setmodified!(w::GWord) = (w.modified = true; w)
unsetmodified!(w::GWord) = (w.modified = false; w)
savehash!(w::GWord, h::UInt) = (w.savedhash = h; w)
savedhash(w::GWord) = w.savedhash
parent(w::GWord) = w.parent
hasparent(w::GWord) = isdefined(w, :parent)
setparent!(w::GWord, G::AbstractFPGroup) = (w.parent = G; w)
Base.isempty(w::GWord) = isempty(syllables(w))
Base.isone(w::GWord) = (freereduce!(w); isempty(w))
Base.one(w::GWord) = one(parent(w))
function Base.iterate(w::GWord, state=(syllable=1, pow=1))
state.syllable > syllablelength(w) && return nothing
next = iterate(syllables(w)[state.syllable], state.pow)
next === nothing && return iterate(w, (syllable=state.syllable+1, pow=1))
return first(next), (syllable=state.syllable, pow=last(next))
end
Base.eltype(::Type{<:GWord{T}}) where T = T
Base.length(w::GWord) = isempty(w) ? 0 : sum(length, syllables(w))
Base.size(w::GWord) = (length(w),)
Base.lastindex(w::GWord) = length(w)
Base.@propagate_inbounds function Base.getindex(w::GWord, i::Integer)
csum = 0
idx = 0
@boundscheck 0 < i <= length(w) || throw(BoundsError(w, i))
while csum < i
idx += 1
csum += length(syllables(w)[idx])
end
return first(syllables(w)[idx])
end
# no setindex! for syllable based words