1
0
mirror of https://github.com/kalmarek/PropertyT.jl.git synced 2024-11-19 15:25:29 +01:00

(==) and reduce! functions as suggested by ScottPJones

This commit is contained in:
kalmar 2017-01-21 17:15:33 +01:00
parent 1189c38504
commit 58c90d244d

View File

@ -17,18 +17,15 @@ function show(io::IO, s::GSymbol)
end end
end end
(==)(s::GSymbol, t::GSymbol) = s.gen == t.gen && s.pow == t.pow
length(s::GSymbol) = (s.pow == 0 ? 0 : 1) length(s::GSymbol) = (s.pow == 0 ? 0 : 1)
one{T<:GSymbol}(::Type{T}) = IDSymbol(T) one{T<:GSymbol}(::Type{T}) = IDSymbol(T)
one(s::GSymbol) = one(typeof(s)) one(s::GSymbol) = one(typeof(s))
reduce(s::GSymbol) = (s.pow == 0 ? one(s) : s)
(^)(s::GSymbol, n::Integer) = change_pow(s, s.pow*n)
(*){T<:GSymbol}(s::T, t::T) = return GWord{T}([s])*t (*){T<:GSymbol}(s::T, t::T) = return GWord{T}([s])*t
change_pow(s::GSymbol, n::Int) = throw(ArgumentError("Define change_pow function for $(typeof(s))!"))
abstract Word abstract Word
@ -51,19 +48,16 @@ If so, I'd recommend
5) for ==, I don't think you need to do all that checking for length or length == 0, that will already be handled by comparing the symbols vectors (possibly faster) 5) for ==, I don't think you need to do all that checking for length or length == 0, that will already be handled by comparing the symbols vectors (possibly faster)
function (==){T}(W::GWord{T}, Z::GWord{T})
W.modified && reduce!(W) # reduce could actually clear the flag and recalculate the hash
Z.modified && reduce!(Z)
W.hash == Z.hash && W.symbols == Z.symbols
end
hash{T}(W::GWord{T}) = (W.modified && reduce!(W); W.hash)
(and last lines of reduce! would have W.modified = false ; W.hash = hash(W.symbols))
=# =#
immutable GWord{T<:GSymbol} <: Word type GWord{T<:GSymbol} <: Word
symbols::Vector{T} symbols::Vector{T}
savedhash::UInt
modified::Bool
function GWord(symbols::Vector{T})
return new(symbols, hash(symbols), false)
end
end end
GWord{T<:GSymbol}(s::T) = GWord{T}([s]) GWord{T<:GSymbol}(s::T) = GWord{T}([s])
@ -103,29 +97,28 @@ end
function reduce!{T}(W::GWord{T}, reduce_func::Function=free_group_reduction!) function reduce!{T}(W::GWord{T}, reduce_func::Function=free_group_reduction!)
if length(W) < 2 if length(W) < 2
deleteat!(W.symbols, find(x -> x.pow == 0, W.symbols)) deleteat!(W.symbols, find(x -> x.pow == 0, W.symbols))
return W else
end
reduced = false reduced = false
while !reduced while !reduced
reduced = reduce_func(W) reduced = reduce_func(W)
deleteat!(W.symbols, find(x -> x.pow == 0, W.symbols)) deleteat!(W.symbols, find(x -> x.pow == 0, W.symbols))
end end
end
W.modified = false
W.savedhash = hash(W.symbols,hash(typeof(W)))
return W return W
end end
reduce(W::GWord) = reduce!(deepcopy(W)) reduce(W::GWord) = reduce!(deepcopy(W))
hash{T}(W::GWord{T}) = (W.modified && reduce!(W); W.savedhash)
function (==){T}(W::GWord{T}, Z::GWord{T}) function (==){T}(W::GWord{T}, Z::GWord{T})
reduce!(W) W.modified && reduce!(W) # reduce could actually clear the flag and recalculate the hash
reduce!(Z) Z.modified && reduce!(Z)
if length(W) != length(Z) return W.savedhash == Z.savedhash && W.symbols == Z.symbols
return false
elseif length(W) == 0
return true
else
return W.symbols == Z.symbols
end
end end
function show(io::IO, W::GWord) function show(io::IO, W::GWord)