Skip to content

Commit

Permalink
Merge branch 'master' into doc
Browse files Browse the repository at this point in the history
  • Loading branch information
kalmarek authored Feb 9, 2021
2 parents 853e561 + 51cfdcc commit e635097
Show file tree
Hide file tree
Showing 28 changed files with 916 additions and 622 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
name: TagBot
on:
schedule:
- cron: 0 0 * * *
issue_comment:
types:
- created
workflow_dispatch:
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
ssh: ${{ secrets.DOCUMENTER_KEY }}
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ jobs:
matrix:
version:
- '1.0'
- '1.4'
- '1.5'
- '1'
- 'nightly'
os:
- ubuntu-latest
Expand Down
9 changes: 5 additions & 4 deletions src/KnuthBendix.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
module KnuthBendix

export Word, Alphabet, RewritingSystem, LenLex
export Word, Alphabet, RewritingSystem, LenLex, knuthbendix

include("abstract_words.jl")
include("words.jl")
include("bufferwords.jl")
include("alphabets.jl")
include("orderings.jl")
include("rewriting.jl")
include("kbs1.jl")
include("kbs2.jl")
include("automata.jl")
include("automata_kbs2.jl")
include("helper_structures.jl")
include("derive_rule.jl")
include("force_confluence.jl")
include("kbs.jl")
end
22 changes: 10 additions & 12 deletions src/abstract_words.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,26 @@ Abstract type representing words over an Alphabet.
`AbstractWord` as such has its meaning only in the contex of an Alphabet.
The subtypes of `AbstractWord{T}` need to implement the following methods which
constitute `AbstractWord` interface:
* `W()`: empty constructor returning the identity (e.g. empty) element
* a constructor from `AbstractVector{T}`
* linear indexing (1-based) consistent with iteration returning pointers to letters of an alphabet (`getindex`, `setindex`, `length`),
* `length`: the length of word as written in the alphabet,
* `Base.push!`/`Base.pushfirst!`: appending a single value at the end/beginning,
* `Base.pop!`/`Base.popfirst!`: popping a single value from the end/beginning,
* `Base.append!`/`Base.prepend!`: appending a another word at the end/beginning,
* `Base.resize!`: dropping/extending a word at the end to the requested length
* `Base.push!`/`Base.pushfirst!`: append a single value at the end/beginning,
* `Base.pop!`/`Base.popfirst!`: pop a single value from the end/beginning,
* `Base.append!`/`Base.prepend!`: append a another word at the end/beginning,
* `Base.resize!`: drop/extend a word at the end to the requested length
* `Base.:*`: word concatenation (monoid binary operation),
* `Base.similar`: an uninitialized word of a similar type/storage.
Note that `length` represents how word is written and not the shortest form of
e.g. free reduced word.
Note that `length` represents free reduced word (how it is written in an alphabet)
and not its the shortest form (e.g. the normal form).
The following are implemented for `AbstractWords` but can be overloaded for
performance reasons:
* `Base.==`: the equality (as words),
* `Base.hash`: simple uniqueness hashing function
* `Base.isone`: predicate checking if argument represents the empty word (i.e. monoid identity element)
* `Base.view`: creating `SubWord` e.g. based on subarray.
"""

abstract type AbstractWord{T<:Integer} <: AbstractVector{T} end

Base.hash(w::AbstractWord, h::UInt) =
Expand All @@ -37,8 +34,9 @@ Base.hash(w::AbstractWord, h::UInt) =

Base.size(w::AbstractWord) = (length(w),)

Base.one(::Type{W}) where W <: AbstractWord = W()
Base.one(::W) where W <: AbstractWord = W()
Base.one(::Type{W}) where {T, W<:AbstractWord{T}} = W(T[])
Base.one(::W) where W <: AbstractWord = one(W)
Base.isone(w::AbstractWord) = iszero(length(w))

Base.getindex(w::W, u::AbstractRange) where W<:AbstractWord =
W([w[i] for i in u])
Expand Down
16 changes: 9 additions & 7 deletions src/alphabets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ Alphabet(x::Vector{T}; safe = true) where T = Alphabet{T}(x; safe = safe)

Base.length(abt::Alphabet) = length(abt.alphabet)
Base.isempty(A::Alphabet) = isempty(A.alphabet)
Base.:(==)(A::Alphabet, B::Alphabet) = A.alphabet == B.alphabet && A.inversions == B.inversions
Base.:(==)(A::Alphabet, B::Alphabet) =
A.alphabet == B.alphabet && A.inversions == B.inversions
Base.hash(A::Alphabet{T}, h::UInt) where T =
hash(A.alphabet, hash(A.inversions, hash(h, hash(Alphabet{T}))))

Base.show(io::IO, A::Alphabet{T}) where T = print(io, Alphabet{T}, A.alphabet)

hasinverse(i::Integer, A::Alphabet) = A.inversions[i] > 0
hasinverse(l::T, A::Alphabet{T}) where T = hasinverse(findfirst(==(l), A.alphabet), A)
hasinverse(l::T, A::Alphabet{T}) where T = hasinverse(A[l], A)

function Base.show(io::IO, ::MIME"text/plain", A::Alphabet{T}) where T
if isempty(A)
Expand Down Expand Up @@ -226,18 +227,19 @@ function Base.getindex(A::Alphabet{T}, p::Integer) where T
end

"""
inv(w::AbstractWord, A::Alphabet)
inv(A::Alphabet, w::AbstractWord)
Return the inverse of a word `w` in the context of alphabet `A`.
"""
function Base.inv(w::AbstractWord, A::Alphabet)
function Base.inv(A::Alphabet, w::AbstractWord)
res = similar(w)
n = length(w)
for i in eachindex(w)
iszero(A.inversions[w[i]]) && throw(DomainError(w, "is not invertible over $A"))
res[n+1-i] = A.inversions[w[i]]
for (i,l) in enumerate(reverse(w))
hasinverse(l, A) || throw(DomainError(w, "is not invertible over $A"))
res[i] = A.inversions[l]
end
return res
end
Base.inv(A::Alphabet{T}, a::T) where {T} = A[-A[a]]

string_repr(w::AbstractWord, A::Alphabet) =
(isone(w) ? "(empty word)" : join((A[i] for i in w), "*"))
Loading

0 comments on commit e635097

Please sign in to comment.