Skip to content
Snippets Groups Projects
Verified Commit 9259b774 authored by Lucas Ondel Yang's avatar Lucas Ondel Yang
Browse files

added documentation

parent 3fd5501e
No related branches found
No related tags found
No related merge requests found
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
using Documenter
push!(LOAD_PATH, "../src")
using FiniteStateAutomata
makedocs(
sitename = "FAST",
pages = [
"Home" => "index.md",
"Installation" => "install.md",
"Usage" => [
"Creating WFSTs" => "create.md",
"Operations" => "operations.md"
],
"Library" => "library.md",
"Contributing" => "contrib.md"
]
)
# Contributing
# Creating WFSTs
## Creating a Transducer
The first step is to create a semiring type for the arcs' weight with
the [Semirings.jl](https://gitlab.lisn.upsaclay.fr/fast/semirings.jl)
package. For instance
```
K = LogSemiring{Float64}
```
Then we can create a WFST with the `WFST` function
```julia
WFST(
semiring = K,
initweights = [
(1, K(5))
],
arcs = [
(1, 3, K(2)),
(1, 2, K(3)),
(2, 3, K(4))
],
finalweights = [
(2, K(5)),
(3, K(5))
],
statelabels = [
"a" => "x",
"b" => "y",
"c" => "z"
],
)
```
![](./create_transducer_example.svg)
The main arguments are:
- `semiring`: the arcs' weight semiring
- `initweights`: a list of arcs `(dest, weight)` leaving the initial state `0`
- `arcs`: a list of arcs `(src, dest, weight)`
- `finalweights` a list of final weights `(state, weight)`
- `statelabels` is an array of labels mapping, e.g. "a" => "x", for
each state ; labels can be string or integer
!!! info
In FiniteStateAutomata.jl, we assume by convention that a WFST has
a unique starting state with identifier 0 and with no incoming arcs
and that all the incoming arcs to a given state have the same
label. This latest assumption implicitly associate the labels to
the states rather than to the arc.
To create an acceptor use single labels instead of mappings, for
instance
```
WFST(
...
statelabels = ["a", "b", "c"],
...
)
```
Accepting the empty sequence ϵ requires to allow the automaton to
terminate in the initial state 0, that is to attribute a non-zero final
weight to the intial state. This is achieved by using the argument
`ϵweight = one(K)` in `WFST`.
## Representing ϵ arcs
So far we have only considered ϵ-free WFST, that is WFST with no ϵ
transition. FiniteStateAutomata.jl has a special way to represent such
arcs. Internally, it represents the WFST (excluding the initial state)
as a matrix with the following decomposition:
```math
\mathbf{T} = \mathbf{S} + \mathbf{U}\mathbf{E}^*\mathbf{V}.
```
``\mathbf{S}`` is ``Q \times Q`` square matrix where ``Q`` is the
number of states (not including the initial state). Each non-zero
element in ``\mathbf{S}`` corresponds to the weight of an arc with
non-ϵ label. The right-and-side term corresponds to additional arcs
that can be compressed by being represented by a low-rank factorize
matrix. ``\mathbf{U}`` is a ``Q \times P`` matrix, ``\mathbf{E}`` is
a ``P \times P`` matrix and ``\mathbf{V}`` is a ``P \times Q`` matrix
where ``P`` is the numbers low-rank *factors*. Finally, the ``^*``
operator denotes the matrix power series
```math
\mathbf{E}^* = \mathbf{E}^0 + \mathbf{E}^1 + \mathbf{E}^2 + \dots
```
We interpret these "factors" as ϵ-state, i.e. states for which each
incoming arc has an ϵ label. Following this rationale, ``\mathbf{U}``
represents the arcs leaving regular states to ϵ-states, ``\mathbf{E}``
represents transition between ϵ-states and ``\mathbf{V}`` represents
the arcs leaving ϵ-states to regular states. A WFST with factors
can be created by providing the arguments `infactors` (``\mathcal{U}``),
`factors` (``\mathbf{E}``) and `outfactors` (``\mathbf{V}``)
```julia
WFST(
semiring = K,
initweights = [
(1, K(5))
],
arcs = [
(1, 3, K(2)),
(1, 2, K(3)),
(2, 3, K(4))
],
finalweights = [
(2, K(5)),
(3, K(5))
],
statelabels = [
"a" => "x",
"b" => "y",
"c" => "z"
],
infactors = [
(1, 1, K(2))
],
outfactors = [
(1, 2, K(3)),
(2, 3, K(3))
],
factors = [
(1, 2, K(2))
]
)
```
![](./create_transducer_epsilon.svg)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.46.0 (20210118.1747)
-->
<!-- Pages: 1 -->
<svg width="547pt" height="163pt"
viewBox="0.00 0.00 546.80 162.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 158.8)">
<polygon fill="white" stroke="transparent" points="-4,4 -4,-158.8 542.8,-158.8 542.8,4 -4,4"/>
<!-- 0 -->
<g id="node1" class="node">
<title>0</title>
<ellipse fill="none" stroke="black" stroke-width="2" cx="18" cy="-105" rx="18" ry="18"/>
<text text-anchor="middle" x="18" y="-100.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- 1 -->
<g id="node2" class="node">
<title>1</title>
<ellipse fill="none" stroke="black" cx="128.5" cy="-105" rx="18" ry="18"/>
<text text-anchor="middle" x="128.5" y="-100.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- 0&#45;&gt;1 -->
<g id="edge1" class="edge">
<title>0&#45;&gt;1</title>
<path fill="none" stroke="black" d="M36.43,-105C53.7,-105 80.38,-105 100.41,-105"/>
<polygon fill="black" stroke="black" points="100.47,-108.5 110.47,-105 100.47,-101.5 100.47,-108.5"/>
<text text-anchor="middle" x="73.25" y="-109.2" font-family="Times,serif" font-size="14.00">a:x/5.0</text>
</g>
<!-- 2 -->
<g id="node3" class="node">
<title>2</title>
<ellipse fill="none" stroke="black" cx="361.23" cy="-89" rx="30.73" ry="30.73"/>
<ellipse fill="none" stroke="black" cx="361.23" cy="-89" rx="34.74" ry="34.74"/>
<text text-anchor="middle" x="361.23" y="-84.8" font-family="Times,serif" font-size="14.00">2/5.0</text>
</g>
<!-- 1&#45;&gt;2 -->
<g id="edge2" class="edge">
<title>1&#45;&gt;2</title>
<path fill="none" stroke="black" d="M146.46,-103.82C181.9,-101.37 264.77,-95.62 316.29,-92.05"/>
<polygon fill="black" stroke="black" points="316.73,-95.52 326.47,-91.34 316.25,-88.54 316.73,-95.52"/>
<text text-anchor="middle" x="231.69" y="-103.2" font-family="Times,serif" font-size="14.00">b:y/3.0</text>
</g>
<!-- 3 -->
<g id="node4" class="node">
<title>3</title>
<ellipse fill="none" stroke="black" cx="504.18" cy="-89" rx="30.73" ry="30.73"/>
<ellipse fill="none" stroke="black" cx="504.18" cy="-89" rx="34.74" ry="34.74"/>
<text text-anchor="middle" x="504.18" y="-84.8" font-family="Times,serif" font-size="14.00">3/5.0</text>
</g>
<!-- 1&#45;&gt;3 -->
<g id="edge3" class="edge">
<title>1&#45;&gt;3</title>
<path fill="none" stroke="black" d="M145.86,-110.08C187.79,-122.39 302.33,-151.43 395.85,-133 419.39,-128.36 444.26,-118.51 464.13,-109.31"/>
<polygon fill="black" stroke="black" points="465.65,-112.46 473.17,-105 462.64,-106.14 465.65,-112.46"/>
<text text-anchor="middle" x="288.97" y="-142.2" font-family="Times,serif" font-size="14.00">c:z/2.0</text>
</g>
<!-- 4 -->
<g id="node5" class="node">
<title>4</title>
<ellipse fill="#c1cdcd" stroke="black" cx="231.69" cy="-51" rx="18" ry="18"/>
<text text-anchor="middle" x="231.69" y="-46.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- 1&#45;&gt;4 -->
<g id="edge5" class="edge">
<title>1&#45;&gt;4</title>
<path fill="none" stroke="black" d="M141.54,-92.31C147.9,-86.18 156.11,-79.11 164.5,-74.2 176.73,-67.04 191.52,-61.6 204.02,-57.79"/>
<polygon fill="black" stroke="black" points="205.22,-61.08 213.87,-54.97 203.29,-54.35 205.22,-61.08"/>
<text text-anchor="middle" x="179.27" y="-79.2" font-family="Times,serif" font-size="14.00">ϵ/2.0</text>
</g>
<!-- 2&#45;&gt;3 -->
<g id="edge4" class="edge">
<title>2&#45;&gt;3</title>
<path fill="none" stroke="black" d="M395.99,-89C414.94,-89 438.81,-89 459.2,-89"/>
<polygon fill="black" stroke="black" points="459.21,-92.5 469.21,-89 459.21,-85.5 459.21,-92.5"/>
<text text-anchor="middle" x="432.7" y="-93.2" font-family="Times,serif" font-size="14.00">c:z/4.0</text>
</g>
<!-- 4&#45;&gt;2 -->
<g id="edge7" class="edge">
<title>4&#45;&gt;2</title>
<path fill="none" stroke="black" d="M249.1,-55.89C266.47,-61.06 294.57,-69.44 318.17,-76.47"/>
<polygon fill="black" stroke="black" points="317.38,-79.88 327.96,-79.39 319.38,-73.18 317.38,-79.88"/>
<text text-anchor="middle" x="288.97" y="-78.2" font-family="Times,serif" font-size="14.00">b:y/3.0</text>
</g>
<!-- 5 -->
<g id="node6" class="node">
<title>5</title>
<ellipse fill="#c1cdcd" stroke="black" cx="361.23" cy="-18" rx="18" ry="18"/>
<text text-anchor="middle" x="361.23" y="-13.8" font-family="Times,serif" font-size="14.00">2</text>
</g>
<!-- 4&#45;&gt;5 -->
<g id="edge6" class="edge">
<title>4&#45;&gt;5</title>
<path fill="none" stroke="black" d="M247.06,-41.14C253.58,-37.12 261.56,-32.81 269.33,-30.2 290.02,-23.23 314.61,-20.23 333,-18.94"/>
<polygon fill="black" stroke="black" points="333.25,-22.43 343.04,-18.37 332.85,-15.44 333.25,-22.43"/>
<text text-anchor="middle" x="288.97" y="-35.2" font-family="Times,serif" font-size="14.00">ϵ/2.0</text>
</g>
<!-- 5&#45;&gt;3 -->
<g id="edge8" class="edge">
<title>5&#45;&gt;3</title>
<path fill="none" stroke="black" d="M377.58,-25.73C398.12,-36.08 435.26,-54.79 463.85,-69.19"/>
<polygon fill="black" stroke="black" points="462.29,-72.32 472.8,-73.7 465.44,-66.07 462.29,-72.32"/>
<text text-anchor="middle" x="432.7" y="-66.2" font-family="Times,serif" font-size="14.00">c:z/3.0</text>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.46.0 (20210118.1747)
-->
<!-- Pages: 1 -->
<svg width="442pt" height="130pt"
viewBox="0.00 0.00 441.97 130.24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 126.24)">
<polygon fill="white" stroke="transparent" points="-4,4 -4,-126.24 437.97,-126.24 437.97,4 -4,4"/>
<!-- 0 -->
<g id="node1" class="node">
<title>0</title>
<ellipse fill="none" stroke="black" stroke-width="2" cx="18" cy="-34.62" rx="18" ry="18"/>
<text text-anchor="middle" x="18" y="-30.42" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- 1 -->
<g id="node2" class="node">
<title>1</title>
<ellipse fill="none" stroke="black" cx="128.5" cy="-34.62" rx="18" ry="18"/>
<text text-anchor="middle" x="128.5" y="-30.42" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- 0&#45;&gt;1 -->
<g id="edge1" class="edge">
<title>0&#45;&gt;1</title>
<path fill="none" stroke="black" d="M36.43,-34.62C53.7,-34.62 80.38,-34.62 100.41,-34.62"/>
<polygon fill="black" stroke="black" points="100.47,-38.12 110.47,-34.62 100.47,-31.12 100.47,-38.12"/>
<text text-anchor="middle" x="73.25" y="-38.82" font-family="Times,serif" font-size="14.00">a:x/5.0</text>
</g>
<!-- 2 -->
<g id="node3" class="node">
<title>2</title>
<ellipse fill="none" stroke="black" cx="256.4" cy="-87.62" rx="30.73" ry="30.73"/>
<ellipse fill="none" stroke="black" cx="256.4" cy="-87.62" rx="34.74" ry="34.74"/>
<text text-anchor="middle" x="256.4" y="-83.42" font-family="Times,serif" font-size="14.00">2/5.0</text>
</g>
<!-- 1&#45;&gt;2 -->
<g id="edge2" class="edge">
<title>1&#45;&gt;2</title>
<path fill="none" stroke="black" d="M145.44,-41.33C162.77,-48.63 191.14,-60.57 214.73,-70.5"/>
<polygon fill="black" stroke="black" points="213.59,-73.82 224.16,-74.47 216.3,-67.37 213.59,-73.82"/>
<text text-anchor="middle" x="184.14" y="-69.82" font-family="Times,serif" font-size="14.00">b:y/3.0</text>
</g>
<!-- 3 -->
<g id="node4" class="node">
<title>3</title>
<ellipse fill="none" stroke="black" cx="399.35" cy="-34.62" rx="30.73" ry="30.73"/>
<ellipse fill="none" stroke="black" cx="399.35" cy="-34.62" rx="34.74" ry="34.74"/>
<text text-anchor="middle" x="399.35" y="-30.42" font-family="Times,serif" font-size="14.00">3/5.0</text>
</g>
<!-- 1&#45;&gt;3 -->
<g id="edge3" class="edge">
<title>1&#45;&gt;3</title>
<path fill="none" stroke="black" d="M146.48,-32.75C164.97,-30.82 195.43,-27.93 221.78,-26.82 252.52,-25.52 260.26,-25.7 291.02,-26.82 311.91,-27.58 335.04,-29.16 354.46,-30.71"/>
<polygon fill="black" stroke="black" points="354.29,-34.21 364.54,-31.53 354.86,-27.23 354.29,-34.21"/>
<text text-anchor="middle" x="256.4" y="-30.82" font-family="Times,serif" font-size="14.00">c:z/2.0</text>
</g>
<!-- 2&#45;&gt;3 -->
<g id="edge4" class="edge">
<title>2&#45;&gt;3</title>
<path fill="none" stroke="black" d="M289.03,-75.73C309.02,-68.21 335.07,-58.41 356.73,-50.27"/>
<polygon fill="black" stroke="black" points="358.2,-53.45 366.33,-46.66 355.74,-46.9 358.2,-53.45"/>
<text text-anchor="middle" x="327.87" y="-70.82" font-family="Times,serif" font-size="14.00">c:z/4.0</text>
</g>
</g>
</svg>
# Weighted Finite State Transducer in Julia
FiniteStateAutomata.jl is a Julia package to create and use Weighted
Finite State Transducers (WFSTs). It is based on a sparse algebraic
representation of WFST and it is part of the
[FAST project](https://hebergement.universite-paris-saclay.fr/fast-asr/).
The source code of the project is available at
[gitlab repository](https://gitlab.lisn.upsaclay.fr/fast/finitestateautomata.jl).
If you have any questions, please use the [FAST chat room](https://join.citadel.team/#/room/!hAUhJkyFxnywTbOgQk:cnrs.citadel.team?deeplink=true)
on [Citadel Team](https://www.thalesgroup.com/en/citadel-team).
Related WFST toolkits:
* [OpenFST](https://www.openfst.org)
# Installation
FiniteStateAutomata.jl is available via the [FAST registry](registry).
In a Julia REPL session type `[` to enter the package mode and then
type
```julia
pkg> add FiniteStateAutomata
```
Then import the module
```julia
julia> using FiniteStateAutomata
```
# Library
# Operations on WFST
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment